1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Merge branch 'canary'

This commit is contained in:
Tim Neutkens 2018-02-05 19:25:02 +01:00
commit c5ddfea689
449 changed files with 9036 additions and 3127 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@ dist
# dependencies # dependencies
node_modules node_modules
package-lock.json package-lock.json
test/node_modules
# logs # logs
*.log *.log

View file

@ -10,7 +10,7 @@
language: "node_js", language: "node_js",
node_js: ["6"], node_js: ["6"],
cache: { cache: {
directories: ["node-modules"] directories: ["node_modules"]
}, },
before_install: [ before_install: [
"rm yarn.lock", "rm yarn.lock",
@ -22,6 +22,7 @@
deploy: { deploy: {
provider: "npm", provider: "npm",
email: "leo@zeit.co", email: "leo@zeit.co",
tag: "canary",
api_key: { api_key: {
secure: secure:
"br9gLncKeLSoL7iOq0PXFeD1Gp3jRI8QMCSNIrGdZg/MuLeuwYPv36kmMgf7aGIfpjFLtU2/eVrOHSB+T5g1nKgOsqmWsfZE1tQYWph0//ookd/sj+IyxIx8nVLbUV/C4ctYOhX/efotRgNn56w5Av5hWc1IQLmW9mSN8ijrQnM+GzRI8QitiofeY2EP3N1eO8vC8E2oGkOsAdcypiX6lFG908zyWt7X2SD+iOsK2eAHjxoAEUdrxE5a8gTDhcTH6qnmtBs9rCeEKbO3JZjEy5dvccxlX3Nd+2GC1rckayk6o5L/zveTilsUx6Auqqbwn1dT5ffQuYsV4RPofs8IMrhnizc8y+OfUcCCpBJ4ia4w7N8FEP56TnRNTFoFBGJL5Y6NfeT0HHAlClxUWMG9pRGWGN+sskODDQ9FEntGZoqwV396ogs+3YhkxbY0AIr84QOctflsFcPtOgr/CoBeOsjbB+o9+Rlsqwlf3u3B7qhtU9eV6KcMfK4x9qW+2cwTllK+gD8S9wILx5BChkfx99g/7u/Rg1PCym64tTsDOBtqTVC2YCqeYYvjmpw4Vl3ofLrFsoNQnbmb6Q5+JSpOcJ/bEj7P/FuZdlU0fNV28tFhElu5caKhSCJz/avUlXG7NeveW1Ee8gjhURC4V/l4ryacyjA2vcDY/4RRkWtHNr4=" "br9gLncKeLSoL7iOq0PXFeD1Gp3jRI8QMCSNIrGdZg/MuLeuwYPv36kmMgf7aGIfpjFLtU2/eVrOHSB+T5g1nKgOsqmWsfZE1tQYWph0//ookd/sj+IyxIx8nVLbUV/C4ctYOhX/efotRgNn56w5Av5hWc1IQLmW9mSN8ijrQnM+GzRI8QitiofeY2EP3N1eO8vC8E2oGkOsAdcypiX6lFG908zyWt7X2SD+iOsK2eAHjxoAEUdrxE5a8gTDhcTH6qnmtBs9rCeEKbO3JZjEy5dvccxlX3Nd+2GC1rckayk6o5L/zveTilsUx6Auqqbwn1dT5ffQuYsV4RPofs8IMrhnizc8y+OfUcCCpBJ4ia4w7N8FEP56TnRNTFoFBGJL5Y6NfeT0HHAlClxUWMG9pRGWGN+sskODDQ9FEntGZoqwV396ogs+3YhkxbY0AIr84QOctflsFcPtOgr/CoBeOsjbB+o9+Rlsqwlf3u3B7qhtU9eV6KcMfK4x9qW+2cwTllK+gD8S9wILx5BChkfx99g/7u/Rg1PCym64tTsDOBtqTVC2YCqeYYvjmpw4Vl3ofLrFsoNQnbmb6Q5+JSpOcJ/bEj7P/FuZdlU0fNV28tFhElu5caKhSCJz/avUlXG7NeveW1Ee8gjhURC4V/l4ryacyjA2vcDY/4RRkWtHNr4="

1
asset.js Normal file
View file

@ -0,0 +1 @@
module.exports = require('./dist/lib/asset')

View file

@ -1,10 +1,7 @@
#!/usr/bin/env node #!/usr/bin/env node
import { join } from 'path'
import { join, resolve } from 'path'
import { spawn } from 'cross-spawn' import { spawn } from 'cross-spawn'
import { watchFile } from 'fs'
import pkg from '../../package.json' import pkg from '../../package.json'
import getConfig from '../server/config'
if (pkg.peerDependencies) { if (pkg.peerDependencies) {
Object.keys(pkg.peerDependencies).forEach(dependency => { Object.keys(pkg.peerDependencies).forEach(dependency => {
@ -27,13 +24,18 @@ const commands = new Set([
]) ])
let cmd = process.argv[2] let cmd = process.argv[2]
let args let args = []
let nodeArgs = []
if (new Set(['--version', '-v']).has(cmd)) { if (new Set(['--version', '-v']).has(cmd)) {
console.log(`next.js v${pkg.version}`) console.log(`next.js v${pkg.version}`)
process.exit(0) process.exit(0)
} }
if (new Set(process.argv).has('--inspect')) {
nodeArgs.push('--inspect')
}
if (new Set(['--help', '-h']).has(cmd)) { if (new Set(['--help', '-h']).has(cmd)) {
console.log(` console.log(`
Usage Usage
@ -61,7 +63,7 @@ process.env.NODE_ENV = process.env.NODE_ENV || defaultEnv
const bin = join(__dirname, 'next-' + cmd) const bin = join(__dirname, 'next-' + cmd)
const startProcess = () => { const startProcess = () => {
const proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] }) const proc = spawn('node', [...nodeArgs, ...[bin], ...args], { stdio: 'inherit', customFds: [0, 1, 2] })
proc.on('close', (code, signal) => { proc.on('close', (code, signal) => {
if (code !== null) { if (code !== null) {
process.exit(code) process.exit(code)
@ -83,10 +85,10 @@ const startProcess = () => {
} }
let proc = startProcess() let proc = startProcess()
const { pagesDirectory = resolve(process.cwd(), 'pages') } = getConfig(process.cwd())
if (cmd === 'dev') { if (cmd === 'dev') {
watchFile(`${resolve(pagesDirectory, '..')}/next.config.js`, (cur, prev) => { const {watchFile} = require('fs')
watchFile(`${process.cwd()}/next.config.js`, (cur, prev) => {
if (cur.size > 0 || prev.size > 0) { if (cur.size > 0 || prev.size > 0) {
console.log('\n> Found a change in next.config.js, restarting the server...') console.log('\n> Found a change in next.config.js, restarting the server...')
// Don't listen to 'close' now since otherwise parent gets killed by listener // Don't listen to 'close' now since otherwise parent gets killed by listener

View file

@ -1,11 +1,9 @@
#!/usr/bin/env node #!/usr/bin/env node
import 'source-map-support/register'
import { resolve, join } from 'path' import { resolve, join } from 'path'
import parseArgs from 'minimist' import parseArgs from 'minimist'
import { existsSync, readFileSync } from 'fs' import { existsSync, readFileSync } from 'fs'
import Server from '../server' import Server from '../server'
import { printAndExit } from '../lib/utils' import { printAndExit } from '../lib/utils'
import pkgUp from 'pkg-up'
const argv = parseArgs(process.argv.slice(2), { const argv = parseArgs(process.argv.slice(2), {
alias: { alias: {
@ -64,7 +62,7 @@ srv.start(argv.port, argv.hostname)
.catch((err) => { .catch((err) => {
if (err.code === 'EADDRINUSE') { if (err.code === 'EADDRINUSE') {
let errorMessage = `Port ${argv.port} is already in use.` let errorMessage = `Port ${argv.port} is already in use.`
const pkgAppPath = pkgUp.sync('.') const pkgAppPath = require('pkg-up').sync('.')
const appPackage = JSON.parse(readFileSync(pkgAppPath, 'utf8')) const appPackage = JSON.parse(readFileSync(pkgAppPath, 'utf8'))
const nextScript = Object.entries(appPackage.scripts).find(scriptLine => scriptLine[1] === 'next') const nextScript = Object.entries(appPackage.scripts).find(scriptLine => scriptLine[1] === 'next')
if (nextScript) errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p <some other port>\`.` if (nextScript) errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p <some other port>\`.`

View file

@ -6,6 +6,7 @@ import EventEmitter from '../lib/EventEmitter'
import App from '../lib/app' import App from '../lib/app'
import { loadGetInitialProps, getURL } from '../lib/utils' import { loadGetInitialProps, getURL } from '../lib/utils'
import PageLoader from '../lib/page-loader' import PageLoader from '../lib/page-loader'
import * as asset from '../lib/asset'
// Polyfill Promise globally // Polyfill Promise globally
// This is needed because Webpack2's dynamic loading(common chunks) code // This is needed because Webpack2's dynamic loading(common chunks) code
@ -29,6 +30,12 @@ const {
location location
} = window } = window
// With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
// So, this is how we do it in the client side at runtime
__webpack_public_path__ = `${assetPrefix}/_next/webpack/` //eslint-disable-line
// Initialize next/asset with the assetPrefix
asset.setAssetPrefix(assetPrefix)
const asPath = getURL() const asPath = getURL()
const pageLoader = new PageLoader(buildId, assetPrefix) const pageLoader = new PageLoader(buildId, assetPrefix)
@ -93,10 +100,7 @@ export default async ({ ErrorDebugComponent: passedDebugComponent, stripAnsi: pa
} }
export async function render (props) { export async function render (props) {
// There are some errors we should ignore. if (props.err) {
// Next.js rendering logic knows how to handle them.
// These are specially 404 errors
if (props.err && !props.err.ignore) {
await renderError(props.err) await renderError(props.err)
return return
} }
@ -159,7 +163,8 @@ async function doRender ({ Component, props, hash, err, emitter: emitterProp = e
let isInitialRender = true let isInitialRender = true
function renderReactElement (reactEl, domEl) { function renderReactElement (reactEl, domEl) {
if (isInitialRender) { // The check for `.hydrate` is there to support React alternatives like preact
if (isInitialRender && typeof ReactDOM.hydrate === 'function') {
ReactDOM.hydrate(reactEl, domEl) ReactDOM.hydrate(reactEl, domEl)
isInitialRender = false isInitialRender = false
} else { } else {

View file

@ -1,10 +1,11 @@
import 'react-hot-loader/patch'
import stripAnsi from 'strip-ansi' import stripAnsi from 'strip-ansi'
import initNext, * as next from './' import initNext, * as next from './'
import ErrorDebugComponent from '../lib/error-debug' import ErrorDebugComponent from '../lib/error-debug'
import initOnDemandEntries from './on-demand-entries-client' import initOnDemandEntries from './on-demand-entries-client'
import initWebpackHMR from './webpack-hot-middleware-client' import initWebpackHMR from './webpack-hot-middleware-client'
require('@zeit/source-map-support/browser-source-map-support')
window.next = next window.next = next
initNext({ ErrorDebugComponent, stripAnsi }) initNext({ ErrorDebugComponent, stripAnsi })

View file

@ -3,6 +3,12 @@
import Router from '../lib/router' import Router from '../lib/router'
import fetch from 'unfetch' import fetch from 'unfetch'
const {
__NEXT_DATA__: {
assetPrefix
}
} = window
export default () => { export default () => {
Router.ready(() => { Router.ready(() => {
Router.router.events.on('routeChangeComplete', ping) Router.router.events.on('routeChangeComplete', ping)
@ -10,16 +16,16 @@ export default () => {
async function ping () { async function ping () {
try { try {
const url = `/_next/on-demand-entries-ping?page=${Router.pathname}` const url = `${assetPrefix}/_next/on-demand-entries-ping?page=${Router.pathname}`
const res = await fetch(url, { const res = await fetch(url, {
credentials: 'same-origin' credentials: 'omit'
}) })
const payload = await res.json() const payload = await res.json()
if (payload.invalid) { if (payload.invalid) {
// Payload can be invalid even if the page is not exists. // Payload can be invalid even if the page is not exists.
// So, we need to make sure it's exists before reloading. // So, we need to make sure it's exists before reloading.
const pageRes = await fetch(location.href, { const pageRes = await fetch(location.href, {
credentials: 'same-origin' credentials: 'omit'
}) })
if (pageRes.status === 200) { if (pageRes.status === 200) {
location.reload() location.reload()

View file

@ -1,7 +1,19 @@
import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?overlay=false&reload=true&path=/_next/webpack-hmr' import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?autoConnect=false'
import Router from '../lib/router' import Router from '../lib/router'
const {
__NEXT_DATA__: {
assetPrefix
}
} = window
export default () => { export default () => {
webpackHotMiddlewareClient.setOptionsAndConnect({
overlay: false,
reload: true,
path: `${assetPrefix}/_next/webpack-hmr`
})
const handlers = { const handlers = {
reload (route) { reload (route) {
if (route === '/_error') { if (route === '/_error') {

1
css.js
View file

@ -1 +0,0 @@
module.exports = require('./dist/lib/css')

View file

@ -0,0 +1,30 @@
# Build directory not writeable
#### Why This Error Occurred
The filesystem does not allow writing to the specified directory. A common cause for this error is starting a [custom server](https://github.com/zeit/next.js#custom-server-and-routing) in development mode on a production server, for example, [now.sh](https://zeit.co) which [doesn't allow you to write to the filesystem after your app is built](https://zeit.co/docs/deployment-types/node#file-system-specifications).
#### Possible Ways to Fix It
When using a custom server with a server file, for example called `server.js`, make sure you update the scripts key in `package.json` to:
```json
{
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
}
}
```
and the custom server starts Next in production mode when `NODE_ENV` is `production`
```js
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
```
### Useful Links
- [Custom Server documentation + examples](https://github.com/zeit/next.js#custom-server-and-routing)

View file

@ -0,0 +1,15 @@
# The poweredByHeader has been removed
#### Why This Error Occurred
Starting at Next.js version 5.0.0 the `poweredByHeader` option has been removed.
#### Possible Ways to Fix It
If you still want to remove `x-powered-by` you can use one of the custom-server examples.
And then manually remove the header using `res.removeHeader('x-powered-by')`
### Useful Links
- [Custom Server documentation + examples](https://github.com/zeit/next.js#custom-server-and-routing)

View file

@ -0,0 +1,40 @@
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/active-class-name)
# activeClassName 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 active-class-name active-class-name-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/active-class-name
cd active-class-name
```
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
ReactRouter has a convenience property on the `Link` element to allow an author to set the _active_ className on a link. This example replicates that functionality using Next's own `Link`.

View file

@ -0,0 +1,18 @@
import { withRouter } from 'next/router'
import Link from 'next/link'
import React, { Children } from 'react'
const ActiveLink = ({ router, children, ...props }) => {
const child = Children.only(children)
let className = child.props.className || ''
if (router.pathname === props.href && props.activeClassName) {
className = `${className} ${props.activeClassName}`.trim()
}
delete props.activeClassName
return <Link {...props}>{React.cloneElement(child, { className })}</Link>
}
export default withRouter(ActiveLink)

View file

@ -0,0 +1,30 @@
import Link from './Link'
export default () => (
<nav>
<style jsx>{`
.active:after {
content: ' (current page)';
}
.nav-link {
text-decoration: none;
padding: 10px;
display: block;
}
`}</style>
<ul>
<li>
<Link activeClassName='active' href='/'>
<a className='nav-link home-link'>Home</a>
</Link>
</li>
<li>
<Link activeClassName='active' href='/about'>
<a className='nav-link'>About</a>
</Link>
</li>
</ul>
</nav>
)

View file

@ -0,0 +1,16 @@
{
"name": "active-class-name",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"author": "Remy Sharp <remy@leftlogic.com>",
"dependencies": {
"next": "latest",
"react": "^16.0.0",
"react-dom": "^16.0.0"
},
"license": "ISC"
}

View file

@ -0,0 +1,8 @@
import Nav from '../components/Nav'
export default () => (
<div>
<Nav />
<p>Hello, I'm About.js</p>
</div>
)

View file

@ -0,0 +1,8 @@
import Nav from '../components/Nav'
export default () => (
<div>
<Nav />
<p>Hello, I'm the home page</p>
</div>
)

View file

@ -4,10 +4,21 @@
## How to use ## 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 basic-css basic-css-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/basic-css curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/basic-css
cd basic-css cd basic-css
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 custom-server-express custom-server-express-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/custom-server-express curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-server-express
cd custom-server-express cd custom-server-express
``` ```

View file

@ -5,5 +5,13 @@ export default () => (
<ul> <ul>
<li><Link href='/b' as='/a'><a>a</a></Link></li> <li><Link href='/b' as='/a'><a>a</a></Link></li>
<li><Link href='/a' as='/b'><a>b</a></Link></li> <li><Link href='/a' as='/b'><a>b</a></Link></li>
<li>
<Link
href={{pathname: '/posts', query: { id: '2' }}}
as='/posts/2'
>
<a>post #2</a>
</Link>
</li>
</ul> </ul>
) )

View file

@ -0,0 +1,17 @@
import React, { Component } from 'react'
export default class extends Component {
static getInitialProps ({ query: { id } }) {
return { postId: id }
}
render () {
return <div>
<h1>My blog post #{this.props.postId}</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua.
</p>
</div>
}
}

View file

@ -18,6 +18,10 @@ app.prepare()
return app.render(req, res, '/a', req.query) return app.render(req, res, '/a', req.query)
}) })
server.get('/posts/:id', (req, res) => {
return app.render(req, res, '/posts', { id: req.params.id })
})
server.get('*', (req, res) => { server.get('*', (req, res) => {
return handle(req, res) return handle(req, res)
}) })

View file

@ -4,10 +4,21 @@
## How to use ## 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 custom-server-fastify custom-server-fastify-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/custom-server-fastify curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-server-fastify
cd custom-server-fastify cd custom-server-fastify
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 custom-server-hapi custom-server-hapi-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/custom-server-hapi curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-server-hapi
cd custom-server-hapi cd custom-server-hapi
``` ```

View file

@ -1,13 +1,19 @@
const pathWrapper = (app, pathName, opts) => ({ raw, query }, hapiReply) => const { parse } = require('url')
app.renderToHTML(raw.req, raw.res, pathName, query, opts)
.then(hapiReply)
const defaultHandlerWrapper = app => { const nextHandlerWrapper = app => {
const handler = app.getRequestHandler() const handler = app.getRequestHandler()
return ({ raw, url }, hapiReply) => return async ({ raw, url }, h) => {
handler(raw.req, raw.res, url) await handler(raw.req, raw.res, url)
.then(() => { return h.close
hapiReply.close(false) }
})
} }
module.exports = { pathWrapper, defaultHandlerWrapper } const defaultHandlerWrapper = app => async ({ raw: { req, res }, url }) => {
const { pathname, query } = parse(url, true)
return app.renderToHTML(req, res, pathname, query)
}
const pathWrapper = (app, pathName, opts) => async ({ raw, query, params }) => {
return app.renderToHTML(raw.req, raw.res, pathName, { ...query, ...params }, opts)
}
module.exports = { pathWrapper, defaultHandlerWrapper, nextHandlerWrapper }

View file

@ -7,11 +7,9 @@
"start": "NODE_ENV=production node server.js" "start": "NODE_ENV=production node server.js"
}, },
"dependencies": { "dependencies": {
"hapi": "^16.1.0", "hapi": "^17.1.1",
"next": "latest", "next": "latest",
"react": "^16.0.0", "react": "^16.0.0",
"react-dom": "^16.0.0", "react-dom": "^16.0.0"
"good": "^7.1.0",
"good-console": "^6.2.0"
} }
} }

View file

@ -1,32 +1,17 @@
const next = require('next') const next = require('next')
const Hapi = require('hapi') const Hapi = require('hapi')
const Good = require('good') const { pathWrapper, defaultHandlerWrapper, nextHandlerWrapper } = require('./next-wrapper')
const { pathWrapper, defaultHandlerWrapper } = require('./next-wrapper')
const port = parseInt(process.env.PORT, 10) || 3000 const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production' const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev }) const app = next({ dev })
const server = new Hapi.Server() const server = new Hapi.Server({
port
})
// add request logging (optional) app
const pluginOptions = [ .prepare()
{ .then(async () => {
register: Good,
options: {
reporters: {
console: [{
module: 'good-console'
}, 'stdout']
}
}
}
]
app.prepare()
.then(() => {
server.connection({ port })
server.register(pluginOptions)
.then(() => {
server.route({ server.route({
method: 'GET', method: 'GET',
path: '/a', path: '/a',
@ -39,17 +24,23 @@ app.prepare()
handler: pathWrapper(app, '/b') handler: pathWrapper(app, '/b')
}) })
server.route({
method: 'GET',
path: '/_next/{p*}', /* next specific routes */
handler: nextHandlerWrapper(app)
})
server.route({ server.route({
method: 'GET', method: 'GET',
path: '/{p*}', /* catch all route */ path: '/{p*}', /* catch all route */
handler: defaultHandlerWrapper(app) handler: defaultHandlerWrapper(app)
}) })
server.start().catch(error => { try {
await server.start()
console.log(`> Ready on http://localhost:${port}`)
} catch (error) {
console.log('Error starting server') console.log('Error starting server')
console.log(error) console.log(error)
}).then(() => { }
console.log(`> Ready on http://localhost:${port}`)
})
})
}) })

View file

@ -4,10 +4,21 @@
## How to use ## 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 custom-server-koa custom-server-koa-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/custom-server-koa curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-server-koa
cd custom-server-koa cd custom-server-koa
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 custom-server-micro custom-server-micro-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/custom-server-micro curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-server-micro
cd custom-server-micro cd custom-server-micro
``` ```

View file

@ -1,17 +1,18 @@
{ {
"main": "server.js",
"scripts": { "scripts": {
"dev": "node server.js", "dev": "micro-dev --watch server.js",
"build": "next build", "build": "next build",
"start": "NODE_ENV=production node server.js" "start": "NODE_ENV=production micro"
}, },
"dependencies": { "dependencies": {
"micro": "^8.0.1", "micro": "^9.1.0",
"micro-route": "^2.4.0", "micro-route": "^2.4.0",
"next": "^3.0.3", "next": "latest",
"react": "^15.6.1", "react": "^16.1.1",
"react-dom": "^15.6.1" "react-dom": "^16.1.1"
}, },
"devDependencies": { "devDependencies": {
"micro-dev": "^1.1.2" "micro-dev": "^2.2.0"
} }
} }

View file

@ -1,29 +1,31 @@
const micro = require('micro')
const match = require('micro-route/match')
const { parse } = require('url') const { parse } = require('url')
const match = require('micro-route/match')
const next = require('next') const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production' const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev }) const app = next({ dev })
const handle = app.getRequestHandler() const handle = app.getRequestHandler()
const server = micro(async (req, res) => { const isA = req => match(req, '/a')
const isB = req => match(req, '/b')
async function main (req, res) {
const parsedUrl = parse(req.url, true) const parsedUrl = parse(req.url, true)
const { query } = parsedUrl const { query } = parsedUrl
if (match(req, '/a')) { if (isA(req)) {
return app.render(req, res, '/b', query) return app.render(req, res, '/b', query)
} else if (match(req, '/b')) { } else if (isB(req)) {
return app.render(req, res, '/a', query) return app.render(req, res, '/a', query)
} }
return handle(req, res, parsedUrl) return handle(req, res, parsedUrl)
}) }
app.prepare().then(() => { async function setup (handler) {
server.listen(port, err => { await app.prepare()
if (err) throw err return handler
console.log(`> Ready on http://localhost:${port}`) }
})
}) module.exports = setup(main)

View file

@ -0,0 +1,40 @@
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/custom-server-nodemon)
# Custom server with Nodemon 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 custom-server-nodemon custom-server-nodemon-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/custom-server-nodemon
cd custom-server-nodemon
```
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
The example shows how you can apply [Nodemon](https://nodemon.io/) to a custom server to have live reload of the server code without being affected by the Next.js universal code.

View file

@ -0,0 +1,3 @@
{
"watch": ["server/**/*.js"]
}

View file

@ -0,0 +1,15 @@
{
"scripts": {
"dev": "nodemon server/index.js",
"build": "next build",
"start": "NODE_ENV=production node server/index.js"
},
"dependencies": {
"next": "latest",
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"devDependencies": {
"nodemon": "^1.12.1"
}
}

View file

@ -0,0 +1,3 @@
import React from 'react'
export default () => <div>a</div>

View file

@ -0,0 +1,3 @@
import React from 'react'
export default () => <div>b</div>

View file

@ -0,0 +1,9 @@
import React from 'react'
import Link from 'next/link'
export default () => (
<ul>
<li><Link href='/b' as='/a'><a>a</a></Link></li>
<li><Link href='/a' as='/b'><a>b</a></Link></li>
</ul>
)

View file

@ -0,0 +1,28 @@
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
if (pathname === '/a') {
app.render(req, res, '/b', query)
} else if (pathname === '/b') {
app.render(req, res, '/a', query)
} else {
handle(req, res, parsedUrl)
}
})
.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})

View file

@ -0,0 +1,15 @@
{
"name": "custom-server-polka",
"version": "1.0.0",
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
"dependencies": {
"next": "latest",
"polka": "0.2.3",
"react": "16.2.0",
"react-dom": "16.2.0"
}
}

View file

@ -0,0 +1,3 @@
import React from 'react'
export default () => <div>a</div>

View file

@ -0,0 +1,3 @@
import React from 'react'
export default () => <div>b</div>

View file

@ -0,0 +1,17 @@
import React from 'react'
import Link from 'next/link'
export default () => (
<ul>
<li>
<Link href='/b' as='/a'>
<a>a</a>
</Link>
</li>
<li>
<Link href='/a' as='/b'>
<a>b</a>
</Link>
</li>
</ul>
)

View file

@ -0,0 +1,21 @@
const polka = require('polka')
const next = require('next')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = polka()
server.get('/a', (req, res) => app.render(req, res, '/b', req.query))
server.get('/b', (req, res) => app.render(req, res, '/a', req.query))
server.get('*', (req, res) => handle(req, res))
server
.listen(port)
.then(() => console.log(`> Ready on http://localhost:${port}`))
})

View file

@ -4,10 +4,21 @@
## How to use ## 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 custom-server custom-server-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/custom-server curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-server
cd custom-server cd custom-server
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 data-fetch data-fetch-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/data-fetch curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/data-fetch
cd data-fetch cd data-fetch
``` ```

View file

@ -7,7 +7,7 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"isomorphic-fetch": "^2.2.1", "isomorphic-unfetch": "^2.0.0",
"next": "latest", "next": "latest",
"react": "^16.0.0", "react": "^16.0.0",
"react-dom": "^16.0.0" "react-dom": "^16.0.0"

View file

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import Link from 'next/link' import Link from 'next/link'
import 'isomorphic-fetch' import 'isomorphic-unfetch'
export default class MyPage extends React.Component { export default class MyPage extends React.Component {
static async getInitialProps () { static async getInitialProps () {

View file

@ -1,7 +1,7 @@
import React from 'react' import React from 'react'
import Link from 'next/link' import Link from 'next/link'
import 'isomorphic-fetch' import 'isomorphic-unfetch'
export default class MyPage extends React.Component { export default class MyPage extends React.Component {
static async getInitialProps () { static async getInitialProps () {

View file

@ -4,10 +4,21 @@
## How to use ## 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 form-handler form-handler-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/form-handler curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/form-handler
cd form-handler cd form-handler
``` ```

View file

@ -14,11 +14,11 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"express": "^4.15.4", "express": "^4.15.4",
"next": "^3.2.2", "next": "latest",
"react": "^16.1.1",
"react-dom": "^16.1.1",
"next-redux-wrapper": "^1.3.2", "next-redux-wrapper": "^1.3.2",
"react": "^15.6.1",
"react-bootstrap": "^0.31.3", "react-bootstrap": "^0.31.3",
"react-dom": "^15.6.1",
"react-redux": "^5.0.6", "react-redux": "^5.0.6",
"redux": "^3.7.2", "redux": "^3.7.2",
"redux-thunk": "^2.2.0" "redux-thunk": "^2.2.0"

View file

@ -0,0 +1,8 @@
{
"presets": [
"next/babel"
],
"plugins": [
["transform-define", "./env-config.js"]
]
}

2
examples/gh-pages/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
node_modules
.next

View file

@ -0,0 +1,57 @@
# gh-pages Hello World example
## How to use
### 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/master | tar -xz --strip=2 next.js-master/examples/gh-pages
cd gh-pages
```
Install it and run:
```bash
npm install
npm run dev
```
### Deploy it to github
Edit ```env-config.js``` and replace ```'Next-gh-page-example'``` by your project name.
Edit ```next.config.js``` and replace ```'Next-gh-page-example'``` by your project name.
1. Create repository.
2. Link it to your github account.
3. Publish your master branch.
```bash
npm run deploy
```
Test it:
Replace 'github-user-name' and 'github-project-name'
```bash
https://github-user-name.github.io/github-project-name/
```
Example:
```bash
https://github.com/thierryc/Next-gh-page-example/
https://thierryc.github.io/Next-gh-page-example/
```
## The idea behind the example
This example shows the most basic idea behind Next. We have 2 pages: `pages/index.js` and `pages/about.js`. The former responds to `/` requests and the latter to `/about`. Using `next/link` you can add hyperlinks between them with universal routing capabilities.

View file

@ -0,0 +1,5 @@
const prod = process.env.NODE_ENV === 'production'
module.exports = {
'process.env.BACKEND_URL': prod ? '/Next-gh-page-example' : ''
}

View file

@ -0,0 +1,15 @@
// This file is not going through babel transformation.
// So, we write it in vanilla JS
// (But you could use ES2015 features supported by your Node.js version)
const debug = process.env.NODE_ENV !== 'production'
module.exports = {
exportPathMap: function () {
return {
'/': { page: '/' },
'/about': { page: '/about' }
}
},
assetPrefix: !debug ? '/Next-gh-page-example/' : ''
}

View file

@ -0,0 +1,20 @@
{
"name": "gh-pages",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"export": "next export",
"deploy": "rm -rf node_modules/.cache && next build && next export && touch out/.nojekyll && git add out/ && git commit -m \"Deploy Next.js to gh-pages\" && git subtree push --prefix out origin gh-pages"
},
"dependencies": {
"next": "latest",
"react": "^16.0.0",
"react-dom": "^16.0.0"
},
"license": "ISC",
"devDependencies": {
"babel-plugin-transform-define": "^1.3.0"
}
}

View file

@ -0,0 +1,7 @@
import Link from 'next/link'
export default () => (
<div>
<div>About us</div>
<div>Back to <Link href='/' as={process.env.BACKEND_URL + '/'}><a>Home</a></Link></div>
</div>
)

View file

@ -0,0 +1,4 @@
import Link from 'next/link'
export default () => (
<div>Hello World. <Link href='/about' as={process.env.BACKEND_URL + '/about'}><a>About</a></Link></div>
)

View file

@ -4,10 +4,21 @@
## How to use ## 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 head-elements head-elements-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/head-elements curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/head-elements
cd head-elements cd head-elements
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 hello-world hello-world-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/hello-world curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/hello-world
cd hello-world cd hello-world
``` ```

View file

@ -0,0 +1,3 @@
export default () => (
<div>About 2</div>
)

View file

@ -0,0 +1,3 @@
export default () => (
<div>Hello Day</div>
)

View file

@ -4,10 +4,21 @@
## How to use ## 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 layout-component layout-component-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/layout-component curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/layout-component
cd layout-component cd layout-component
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 nested-components nested-components-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/nested-components curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/nested-components
cd nested-components cd nested-components
``` ```

View file

@ -0,0 +1,27 @@
# Hello World example
## Only client render for external dependencies
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/only-client-render-external-dependencies
cd only-client-render-external-dependencies
```
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 shows how to use an external dependency that only allows client-render.

View file

@ -0,0 +1,16 @@
{
"name": "only-client-render-external-dependencies",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "latest",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"recharts": "^1.0.0-beta.0"
},
"license": "ISC"
}

View file

@ -0,0 +1,44 @@
import React from 'react'
let LineChart
let Line
class Chart extends React.Component {
constructor () {
super()
this.state = {
chart: false,
data: [
{name: 'Page A', uv: 4000, pv: 2400, amt: 2400},
{name: 'Page B', uv: 3000, pv: 1398, amt: 2210},
{name: 'Page C', uv: 2000, pv: 9800, amt: 2290},
{name: 'Page D', uv: 2780, pv: 3908, amt: 2000},
{name: 'Page E', uv: 1890, pv: 4800, amt: 2181},
{name: 'Page F', uv: 2390, pv: 3800, amt: 2500},
{name: 'Page G', uv: 3490, pv: 4300, amt: 2100}
]
}
}
componentDidMount () {
LineChart = require('recharts').LineChart
Line = require('recharts').Line
this.setState({
chart: true
})
}
render () {
return (
<div>
<h1>Another chart</h1>
{this.state.chart &&
<LineChart width={400} height={400} data={this.state.data}>
<Line type='monotone' dataKey='uv' stroke='#8884d8' />
</LineChart>
}
</div>
)
}
}
export default Chart

View file

@ -0,0 +1,47 @@
import React from 'react'
import Link from 'next/link'
let LineChart
let Line
class Index extends React.Component {
constructor () {
super()
this.state = {
chart: false,
data: [
{name: 'Page A', uv: 1000, pv: 2400, amt: 2400},
{name: 'Page B', uv: 3000, pv: 1398, amt: 2210},
{name: 'Page C', uv: 2000, pv: 9800, amt: 2290},
{name: 'Page D', uv: 2780, pv: 3908, amt: 2000},
{name: 'Page E', uv: 1890, pv: 4800, amt: 2181},
{name: 'Page F', uv: 2390, pv: 3800, amt: 2500},
{name: 'Page G', uv: 3490, pv: 4300, amt: 2100}
]
}
}
componentDidMount () {
LineChart = require('recharts').LineChart
Line = require('recharts').Line
this.setState({
chart: true
})
}
render () {
return (
<div>
<h1>Chart</h1>
<Link href='/chart'><a>Go to another chart</a></Link>
{this.state.chart &&
<LineChart width={400} height={400} data={this.state.data}>
<Line type='monotone' dataKey='uv' stroke='#8884d8' />
</LineChart>
}
</div>
)
}
}
export default Index

View file

@ -4,10 +4,21 @@
## How to use ## 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 page-transitions page-transitions-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/page-transitions curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/page-transitions
cd page-transitions cd page-transitions
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 parameterized-routing parameterized-routing-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/parameterized-routing curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/parameterized-routing
cd parameterized-routing cd parameterized-routing
``` ```

View file

@ -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

View file

@ -0,0 +1,5 @@
{
"title": "Now",
"subtitle": "Realtime global deployments",
"seller": "Zeit"
}

View file

@ -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 }

View file

@ -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"
}
}

View file

@ -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>
)

View file

@ -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>
)
}
}

View file

@ -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')
})
})

View file

@ -3,10 +3,21 @@
## How to use ## 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 progressive-render progressive-render-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/progressive-render curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/progressive-render
cd progressive-render cd progressive-render
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 root-static-files root-static-files-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/custom-server curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-server
cd custom-server cd custom-server
``` ```

View file

@ -3,10 +3,21 @@
## How to use ## 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 shared-modules shared-modules-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/shared-modules curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/shared-modules
cd shared-modules cd shared-modules
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 ssr-caching ssr-caching-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/ssr-caching curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/ssr-caching
cd ssr-caching cd ssr-caching
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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 svg-components svg-components-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/svg-components curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/svg-components
cd svg-components cd svg-components
``` ```

View file

@ -7,7 +7,9 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"next": "latest" "next": "latest",
"react": "latest,
"react-dom": "latest"
}, },
"devDependencies": { "devDependencies": {
"babel-plugin-inline-react-svg": "^0.2.0" "babel-plugin-inline-react-svg": "^0.2.0"

View file

@ -4,10 +4,21 @@
## How to use ## 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-inferno using-inferno-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/using-inferno curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/using-inferno
cd using-inferno cd using-inferno
``` ```

View file

@ -4,10 +4,21 @@
## How to use ## 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-preact using-preact-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/using-preact curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/using-preact
cd using-preact cd using-preact
``` ```

View file

@ -1,16 +1,3 @@
module.exports = { const withPreact = require('@zeit/next-preact')
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 = { module.exports = withPreact()
'react': 'preact-compat/dist/preact-compat',
'react-dom': 'preact-compat/dist/preact-compat'
}
return config
}
}

View file

@ -7,16 +7,10 @@
"start": "NODE_ENV=production node server.js" "start": "NODE_ENV=production node server.js"
}, },
"dependencies": { "dependencies": {
"module-alias": "^2.0.0", "@zeit/next-preact": "0.0.4",
"next": "latest", "next": "latest",
"preact": "^7.2.0", "preact": "8.2.7",
"preact-compat": "^3.14.0", "preact-compat": "3.18.0"
"react": "^16.0.0",
"react-dom": "^16.0.0"
}, },
"license": "ISC", "license": "ISC"
"devDependencies": {
"react": "~15.6.1",
"react-dom": "~15.6.1"
}
} }

View file

@ -1,13 +1,7 @@
const port = parseInt(process.env.PORT, 10) || 3000 const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production' const dev = process.env.NODE_ENV !== 'production'
const moduleAlias = require('module-alias')
// For the development version, we'll use React. require('@zeit/next-preact/alias')()
// Because, it support react hot loading and so on.
if (!dev) {
moduleAlias.addAlias('react', 'preact-compat')
moduleAlias.addAlias('react-dom', 'preact-compat')
}
const { createServer } = require('http') const { createServer } = require('http')
const { parse } = require('url') const { parse } = require('url')

View file

@ -3,10 +3,21 @@
## How to use ## 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-router using-router-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/using-router curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/using-router
cd using-router cd using-router
``` ```

View file

@ -3,10 +3,21 @@
## How to use ## 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-with-router using-with-router-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/using-with-router curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/using-with-router
cd using-with-router cd using-with-router
``` ```

View file

@ -2,10 +2,21 @@
## How to use ## 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 with-absolute-imports with-absolute-imports-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-absolute-import curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-absolute-import
cd with-absolute-import cd with-absolute-import
``` ```

View file

@ -6,8 +6,8 @@
}, },
"dependencies": { "dependencies": {
"babel-plugin-module-resolver": "^2.7.1", "babel-plugin-module-resolver": "^2.7.1",
"next": "^3.0.6", "next": "latest",
"react": "^15.6.1", "react": "^16.1.1",
"react-dom": "^15.6.1" "react-dom": "^16.1.1"
} }
} }

View file

@ -4,10 +4,21 @@
## How to use ## 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 with-algolia-react-instantsearch with-algolia-react-instantsearch-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js): Download the example [or clone the repo](https://github.com/zeit/next.js):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-algolia-react-instantsearch curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-algolia-react-instantsearch
cd with-algolia-react-instantsearch cd with-algolia-react-instantsearch
``` ```

View file

@ -7,11 +7,11 @@
}, },
"dependencies": { "dependencies": {
"css-loader": "^0.28.1", "css-loader": "^0.28.1",
"next": "^2.4.7",
"prop-types": "^15.5.10", "prop-types": "^15.5.10",
"qs": "^6.4.0", "qs": "^6.4.0",
"react": "^15.5.4", "next": "latest",
"react-dom": "^15.5.4", "react": "^16.1.1",
"react-dom": "^16.1.1",
"react-instantsearch": "beta", "react-instantsearch": "beta",
"react-instantsearch-theme-algolia": "beta", "react-instantsearch-theme-algolia": "beta",
"style-loader": "^0.17.0" "style-loader": "^0.17.0"

View file

@ -4,10 +4,21 @@
## How to use ## 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 with-amp with-amp-app
```
### Download manually
Download the example [or clone the repo](https://github.com/zeit/next.js.git): Download the example [or clone the repo](https://github.com/zeit/next.js.git):
```bash ```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-amp curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-amp
cd with-amp cd with-amp
``` ```

View file

@ -0,0 +1,40 @@
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-analytics)
# Example app with analytics
## 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 with-analytics with-analytics-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/with-analytics
cd with-analytics
```
Install it and run:
```bash
yarn
yarn 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 shows how to use Next.js along with [Segment Analytics](https://segment.com). A custom document is used in inject the [Segment snippet](https://github.com/segmentio/snippet) into the `<head>` and components fire ["track"](https://segment.com/docs/spec/track/) events based on user actions.

View file

@ -0,0 +1,14 @@
import React from 'react'
import Link from 'next/link'
export default () => (
<header>
<nav>
<ul>
<li><Link href='/'><a>Home</a></Link></li>
<li><Link href='/about'><a>About</a></Link></li>
<li><Link href='/contact'><a>Contact</a></Link></li>
</ul>
</nav>
</header>
)

View file

@ -0,0 +1,14 @@
{
"name": "with-analytics",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@segment/snippet": "^4.0.1",
"next": "latest",
"react": "^16.2.0",
"react-dom": "^16.2.0"
}
}

View file

@ -0,0 +1,44 @@
import React from 'react'
import Document, { Head, Main, NextScript } from 'next/document'
import * as snippet from '@segment/snippet'
const {
// This write key is associated with https://segment.com/nextjs-example/sources/nextjs.
ANALYTICS_WRITE_KEY = 'NPsk1GimHq09s7egCUlv7D0tqtUAU5wa',
NODE_ENV = 'development'
} = process.env
export default class extends Document {
static getInitialProps ({ renderPage }) {
const { html, head, errorHtml, chunks } = renderPage()
return { html, head, errorHtml, chunks }
}
renderSnippet () {
const opts = {
apiKey: ANALYTICS_WRITE_KEY,
page: true // Set this to `false` if you want to manually fire `analytics.page()` from within your pages.
}
if (NODE_ENV === 'development') {
return snippet.max(opts)
}
return snippet.min(opts)
}
render () {
return (
<html>
<Head>
{/* Inject the Segment snippet into the <head> of the document */}
<script dangerouslySetInnerHTML={{ __html: this.renderSnippet() }} />
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}

Some files were not shown because too many files have changed in this diff Show more