-
Notifications
You must be signed in to change notification settings - Fork 27.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Example: Passing data from server through API (#2594)
* Add example on how to pass data through js api during SSR Requested in #1117 * Use content negotiation instead of a separate route * Codereview feedback * Move security related test cases into a its own file. * Removes the unused renderScript function * Add a nerv example. (#3573) * Add a nerv example. * Fix for indentation/style * Fix for name
- Loading branch information
1 parent
d103345
commit 7afc008
Showing
15 changed files
with
333 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/pass-server-data) | ||
|
||
# Pass Server Data Directly to a Next.js Page during SSR | ||
|
||
## How to use | ||
|
||
Download the example [or clone the repo](https://github.com/zeit/next.js): | ||
|
||
```bash | ||
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/pass-server-data | ||
cd pass-server-data | ||
``` | ||
|
||
Install it and run: | ||
|
||
```bash | ||
npm install | ||
npm run dev | ||
``` | ||
|
||
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) | ||
|
||
```bash | ||
now | ||
``` | ||
|
||
## The idea behind the example | ||
|
||
If you already have a custom server which has local data (for instance cached data from an API call, or data read | ||
from a file at startup) that you wish to make available in the Next.js page, you can pass that data in the query | ||
parameter of `nextApp.render()`. | ||
|
||
This is not the only way to pass data. You could also expose an endpoint and make a `fetch()` call to localhost, or you could | ||
import server-side code with `eval` (necessary to prevent webpack from trying to package your server code). However both | ||
solutions leave something to be desired in either performance or elegance. | ||
|
||
This example shows the express server at `server.js` reading in a file at load time with static data (this could also have been | ||
data cached from an API call) in `operations/get-item.js`. It has two routes: a home page, and an item page. The item page uses | ||
data from the get-item operation, passed as a query parameter in `routes/item.js`. | ||
|
||
We use this data in `pages/item.js` if rendered server-side, or make a fetch request if rendered client-side. | ||
The server knows whether or not to use next.js to render the route based on the Accept header, which will be | ||
`application/json` when we fetch client-side. | ||
|
||
Take a look at the following files: | ||
|
||
* server.js | ||
* routes/item.js | ||
* pages/item.js | ||
* operations/get-item.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"title": "Now", | ||
"subtitle": "Realtime global deployments", | ||
"seller": "Zeit" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const fs = require('fs') | ||
|
||
// In this case, data read from the fs, but it could also be a cached API result. | ||
const data = fs.readFileSync('./data/item.json', 'utf8') | ||
const parsedData = JSON.parse(data) | ||
|
||
function getItem () { | ||
console.log('Requested Item Data:', data) | ||
return parsedData | ||
} | ||
|
||
module.exports = { getItem } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"name": "pass-server-data", | ||
"version": "1.0.0", | ||
"scripts": { | ||
"dev": "node server.js", | ||
"build": "next build", | ||
"start": "NODE_ENV=production node server.js" | ||
}, | ||
"dependencies": { | ||
"express": "^4.14.0", | ||
"isomorphic-fetch": "^2.2.1", | ||
"next": "latest", | ||
"react": "^15.4.2", | ||
"react-dom": "^15.4.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import React from 'react' | ||
import Link from 'next/link' | ||
|
||
export default () => ( | ||
<ul> | ||
<li><Link href='/item'><a>View Item</a></Link></li> | ||
</ul> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import {Component} from 'react' | ||
import Link from 'next/link' | ||
import fetch from 'isomorphic-fetch' | ||
|
||
export default class extends Component { | ||
static async getInitialProps ({ req, query }) { | ||
const isServer = !!req | ||
|
||
console.log('getInitialProps called:', isServer ? 'server' : 'client') | ||
|
||
if (isServer) { | ||
// When being rendered server-side, we have access to our data in query that we put there in routes/item.js, | ||
// saving us an http call. Note that if we were to try to require('../operations/get-item') here, | ||
// it would result in a webpack error. | ||
return { item: query.itemData } | ||
} else { | ||
// On the client, we should fetch the data remotely | ||
const res = await fetch('/_data/item', {headers: {'Accept': 'application/json'}}) | ||
const json = await res.json() | ||
return { item: json } | ||
} | ||
} | ||
|
||
render () { | ||
return ( | ||
<div className='item'> | ||
<div><Link href='/'><a>Back Home</a></Link></div> | ||
<h1>{this.props.item.title}</h1> | ||
<h2>{this.props.item.subtitle} - {this.props.item.seller}</h2> | ||
</div> | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const express = require('express') | ||
const next = require('next') | ||
const api = require('./operations/get-item') | ||
|
||
const dev = process.env.NODE_ENV !== 'production' | ||
const app = next({ dev }) | ||
const handle = app.getRequestHandler() | ||
|
||
app.prepare().then(() => { | ||
const server = express() | ||
|
||
// Set up home page as a simple render of the page. | ||
server.get('/', (req, res) => { | ||
console.log('Render home page') | ||
return app.render(req, res, '/', req.query) | ||
}) | ||
|
||
// Serve the item webpage with next.js as the renderer | ||
server.get('/item', (req, res) => { | ||
const itemData = api.getItem() | ||
app.render(req, res, '/item', { itemData }) | ||
}) | ||
|
||
// When rendering client-side, we will request the same data from this route | ||
server.get('/_data/item', (req, res) => { | ||
const itemData = api.getItem() | ||
res.json(itemData) | ||
}) | ||
|
||
// Fall-back on other next.js assets. | ||
server.get('*', (req, res) => { | ||
return handle(req, res) | ||
}) | ||
|
||
server.listen(3000, (err) => { | ||
if (err) throw err | ||
console.log('> Ready on http://localhost:3000') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/using-nerv) | ||
|
||
# Hello World example | ||
|
||
## How to use | ||
|
||
### Using `create-next-app` | ||
|
||
Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example: | ||
|
||
``` | ||
npm i -g create-next-app | ||
create-next-app --example using-nerv using-nerv-app | ||
``` | ||
|
||
### Download manually | ||
|
||
Download the example [or clone the repo](https://github.com/zeit/next.js): | ||
|
||
```bash | ||
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/using-nerv | ||
cd using-nerv | ||
``` | ||
|
||
Install it and run: | ||
|
||
```bash | ||
npm install | ||
npm run dev | ||
``` | ||
|
||
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download)) | ||
|
||
```bash | ||
now | ||
``` | ||
|
||
## The idea behind the example | ||
|
||
This example uses [Nerv](https://nerv.aotu.io/) instead of React. It's a "blazing fast React alternative, compatible with IE8 and React 16". Here we've customized Next.js to use Nerv instead of React. | ||
|
||
Here's how we did it: | ||
|
||
* Use `next.config.js` to customize our webpack config to support [Nerv](https://nerv.aotu.io/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module.exports = { | ||
webpack: function (config, { dev }) { | ||
// For the development version, we'll use React. | ||
// Because, it supports react hot loading and so on. | ||
if (dev) { | ||
return config | ||
} | ||
|
||
config.resolve.alias = { | ||
react: 'nervjs', | ||
'react-dom': 'nervjs' | ||
} | ||
|
||
return config | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"name": "using-nerv", | ||
"version": "1.0.0", | ||
"scripts": { | ||
"dev": "node server.js", | ||
"build": "next build", | ||
"start": "NODE_ENV=production node server.js" | ||
}, | ||
"dependencies": { | ||
"module-alias": "^2.0.0", | ||
"next": "latest", | ||
"nervjs": "^1.2.4", | ||
"react": "^16.0.0", | ||
"react-dom": "^16.0.0" | ||
}, | ||
"license": "ISC", | ||
"devDependencies": { | ||
"react": "~15.6.1", | ||
"react-dom": "~15.6.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import React from 'react' | ||
|
||
export default () => ( | ||
<div>About us</div> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import React from 'react' | ||
import Link from 'next/link' | ||
|
||
export default () => ( | ||
<div>Hello World. <Link href='/about'><a>About</a></Link></div> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
const port = parseInt(process.env.PORT, 10) || 3000 | ||
const dev = process.env.NODE_ENV !== 'production' | ||
const moduleAlias = require('module-alias') | ||
|
||
// For the development version, we'll use React. | ||
// Because, it support react hot loading and so on. | ||
if (!dev) { | ||
moduleAlias.addAlias('react', 'nervjs') | ||
moduleAlias.addAlias('react-dom', 'nervjs') | ||
} | ||
|
||
const { createServer } = require('http') | ||
const { parse } = require('url') | ||
const next = require('next') | ||
|
||
const app = next({ dev }) | ||
const handle = app.getRequestHandler() | ||
|
||
app.prepare() | ||
.then(() => { | ||
createServer((req, res) => { | ||
const parsedUrl = parse(req.url, true) | ||
handle(req, res, parsedUrl) | ||
}) | ||
.listen(port, (err) => { | ||
if (err) throw err | ||
console.log(`> Ready on http://localhost:${port}`) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.