2016-10-25 12:37:55 +00:00
< img width = "112" alt = "screen shot 2016-10-25 at 2 37 27 pm" src = "https://cloud.githubusercontent.com/assets/13041/19686250/971bf7f8-9ac0-11e6-975c-188defd82df1.png" >
2016-10-05 23:35:00 +00:00
2016-11-05 18:21:32 +00:00
[![Build Status ](https://travis-ci.org/zeit/next.js.svg?branch=master )](https://travis-ci.org/zeit/next.js)
2016-11-15 08:24:20 +00:00
[![Coverage Status ](https://coveralls.io/repos/zeit/next.js/badge.svg?branch=master )](https://coveralls.io/r/zeit/next.js?branch=master)
2016-11-02 19:02:56 +00:00
[![Slack Channel ](https://zeit-slackin.now.sh/badge.svg )](https://zeit.chat)
2016-10-25 06:09:45 +00:00
Next.js is a minimalistic framework for server-rendered React applications.
2016-10-05 23:35:00 +00:00
2017-05-09 23:34:43 +00:00
**Visit https://learnnextjs.com to get started with Next.js.**
---
2017-02-09 11:47:20 +00:00
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE - RUN doctoc TO UPDATE -->
<!-- https://github.com/thlorenz/doctoc -->
- [How to use ](#how-to-use )
- [Setup ](#setup )
- [Automatic code splitting ](#automatic-code-splitting )
- [CSS ](#css )
- [Built-in CSS support ](#built-in-css-support )
- [CSS-in-JS ](#css-in-js )
- [Static file serving (e.g.: images) ](#static-file-serving-eg-images )
- [Populating `<head>` ](#populating-head )
- [Fetching data and component lifecycle ](#fetching-data-and-component-lifecycle )
- [Routing ](#routing )
- [With `<Link>` ](#with-link )
- [Imperatively ](#imperatively )
- [Router Events ](#router-events )
2017-03-06 16:48:35 +00:00
- [Shallow Routing ](#shallow-routing )
2017-02-09 11:47:20 +00:00
- [Prefetching Pages ](#prefetching-pages )
- [With `<Link>` ](#with-link-1 )
- [Imperatively ](#imperatively-1 )
- [Custom server and routing ](#custom-server-and-routing )
- [Custom `<Document>` ](#custom-document )
- [Custom error handling ](#custom-error-handling )
- [Custom configuration ](#custom-configuration )
- [Customizing webpack config ](#customizing-webpack-config )
- [Customizing babel config ](#customizing-babel-config )
2017-04-18 04:18:43 +00:00
- [CDN support with Asset Prefix ](#cdn-support-with-asset-prefix )
2017-02-09 11:47:20 +00:00
- [Production deployment ](#production-deployment )
2017-05-09 18:22:14 +00:00
- [Recipes ](#recipes )
2017-02-09 11:47:20 +00:00
- [FAQ ](#faq )
2017-02-09 11:52:14 +00:00
- [Contributing ](#contributing )
2017-02-09 11:47:20 +00:00
- [Authors ](#authors )
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
2016-12-16 20:22:55 +00:00
2016-10-05 23:35:00 +00:00
## How to use
2017-02-09 11:47:20 +00:00
### Setup
2016-10-25 06:09:45 +00:00
Install it:
2016-12-20 19:19:03 +00:00
```bash
2017-02-14 01:52:31 +00:00
npm install next react react-dom --save
2016-10-25 06:09:45 +00:00
```
2016-10-26 01:46:58 +00:00
and add a script to your package.json like this:
```json
{
"scripts": {
2017-01-26 17:00:55 +00:00
"dev": "next",
"build": "next build",
"start": "next start"
2016-12-19 14:40:26 +00:00
}
2016-10-26 01:46:58 +00:00
}
```
2016-10-25 06:09:45 +00:00
After that, the file-system is the main API. Every `.js` file becomes a route that gets automatically processed and rendered.
2016-10-05 23:35:00 +00:00
2016-10-05 23:36:18 +00:00
Populate `./pages/index.js` inside your project:
2016-10-05 23:35:00 +00:00
2016-10-05 23:58:36 +00:00
```jsx
2016-10-05 23:35:00 +00:00
export default () => (
< div > Welcome to next.js!< / div >
)
```
2017-03-28 20:27:21 +00:00
and then just run `npm run dev` and go to `http://localhost:3000` . To use another port, you can run `npm run dev -- -p <your port here>` .
2016-10-05 23:35:00 +00:00
So far, we get:
- Automatic transpilation and bundling (with webpack and babel)
- Hot code reloading
2016-10-05 23:36:18 +00:00
- Server rendering and indexing of `./pages`
- Static file serving. `./static/` is mapped to `/static/`
2016-10-05 23:35:00 +00:00
2016-10-25 16:26:27 +00:00
To see how simple this is, check out the [sample app - nextgram ](https://github.com/zeit/nextgram )
2016-10-25 16:18:57 +00:00
2016-12-19 21:34:19 +00:00
### Automatic code splitting
2016-10-05 23:35:00 +00:00
2016-12-19 21:34:19 +00:00
Every `import` you declare gets bundled and served with each page. That means pages never load unnecessary code!
2016-10-05 23:35:00 +00:00
2016-10-05 23:58:36 +00:00
```jsx
2016-10-14 21:13:46 +00:00
import cowsay from 'cowsay-browser'
2016-10-05 23:35:00 +00:00
export default () => (
2016-10-25 17:03:20 +00:00
< pre > { cowsay.say({ text: 'hi there!' }) }< / pre >
2016-10-05 23:35:00 +00:00
)
```
### CSS
2016-12-19 19:20:18 +00:00
#### Built-in CSS support
2016-10-31 07:32:51 +00:00
2016-12-24 01:36:34 +00:00
< p > < details >
2016-12-22 21:04:32 +00:00
< summary > < b > Examples< / b > < / summary >
2016-12-24 01:36:34 +00:00
< ul > < li > < a href = "./examples/basic-css" > Basic css< / a > < / li > < / ul >
< / details > < / p >
2016-12-22 21:04:32 +00:00
2016-12-19 19:20:18 +00:00
We bundle [styled-jsx ](https://github.com/zeit/styled-jsx ) to provide support for isolated scoped CSS. The aim is to support "shadow CSS" resembling of Web Components, which unfortunately [do not support server-rendering and are JS-only ](https://github.com/w3c/webcomponents/issues/71 ).
2016-10-05 23:35:00 +00:00
2016-10-05 23:58:36 +00:00
```jsx
2016-10-14 21:13:46 +00:00
export default () => (
2016-12-19 19:20:18 +00:00
< div >
2016-10-05 23:35:00 +00:00
Hello world
2016-12-19 19:20:18 +00:00
< p > scoped!< / p >
< style jsx > { `
p {
color: blue;
}
div {
background: red;
}
@media (max-width: 600px) {
div {
background: blue;
}
}
`}< / style >
2017-05-10 08:25:56 +00:00
< style global jsx > { `
body {
background: black;
}
`}< / style >
2016-10-05 23:35:00 +00:00
< / div >
2016-10-14 21:13:46 +00:00
)
2016-12-19 19:20:18 +00:00
```
2017-05-10 08:25:56 +00:00
Please see the [styled-jsx documentation ](https://github.com/zeit/styled-jsx ) for more examples.
2016-12-19 19:20:18 +00:00
#### CSS-in-JS
2016-12-23 13:01:24 +00:00
< p > < details >
2017-01-25 12:13:34 +00:00
< summary >
< b > Examples< / b >
< / summary >
2017-05-06 18:31:42 +00:00
< ul > < li > < a href = "./examples/with-styled-components" > Styled components< / a > < / li > < li > < a href = "./examples/with-styletron" > Styletron< / a > < / li > < li > < a href = "./examples/with-glamor" > Glamor< / a > < / li > < li > < a href = "./examples/with-glamorous" > Glamorous< / a > < / li > < li > < a href = "./examples/with-cxs" > Cxs< / a > < / li > < li > < a href = "./examples/with-aphrodite" > Aphrodite< / a > < / li > < li > < a href = "./examples/with-fela" > Fela< / a > < / li > < / ul >
2016-12-23 13:01:24 +00:00
< / details > < / p >
2016-12-19 19:20:18 +00:00
It's possible to use any existing CSS-in-JS solution. The simplest one is inline styles:
2016-10-05 23:35:00 +00:00
2016-12-19 21:34:19 +00:00
```jsx
2016-12-19 19:20:18 +00:00
export default () => (
2016-12-20 22:57:11 +00:00
< p style = {{ color: ' red ' } } > hi there< / p >
2016-12-19 19:20:18 +00:00
)
```
2016-12-19 21:34:19 +00:00
To use more sophisticated CSS-in-JS solutions, you typically have to implement style flushing for server-side rendering. We enable this by allowing you to define your own [custom `<Document>` ](#user-content-custom-document ) component that wraps each page
2016-12-19 19:20:18 +00:00
2016-12-19 21:34:19 +00:00
### Static file serving (e.g.: images)
2016-11-17 16:03:04 +00:00
2016-12-19 21:34:19 +00:00
Create a folder called `static` in your project root directory. From your code you can then reference those files with `/static/` URLs:
```jsx
export default () => (
< img src = "/static/my-image.png" / >
)
```
2016-11-17 16:03:04 +00:00
2016-12-17 19:16:22 +00:00
### Populating `<head>`
2016-10-05 23:35:00 +00:00
2016-12-24 01:36:34 +00:00
< p > < details >
2016-12-22 21:04:32 +00:00
< summary > < b > Examples< / b > < / summary >
2017-01-05 21:03:36 +00:00
< ul >
< li > < a href = "./examples/head-elements" > Head elements< / a > < / li >
< li > < a href = "./examples/layout-component" > Layout component< / a > < / li >
< / ul >
2016-12-24 01:36:34 +00:00
< / details > < / p >
2016-12-22 21:04:32 +00:00
2016-10-05 23:35:00 +00:00
We expose a built-in component for appending elements to the `<head>` of the page.
2016-10-05 23:58:36 +00:00
```jsx
2016-10-05 23:35:00 +00:00
import Head from 'next/head'
export default () => (
2016-10-14 21:13:46 +00:00
< div >
< Head >
< title > My page title< / title >
< meta name = "viewport" content = "initial-scale=1.0, width=device-width" / >
< / Head >
< p > Hello world!< / p >
< / div >
2016-10-05 23:35:00 +00:00
)
```
2016-12-17 19:16:22 +00:00
_Note: The contents of `<head>` get cleared upon unmounting the component, so make sure each page completely defines what it needs in `<head>` , without making assumptions about what other pages added_
### Fetching data and component lifecycle
2016-10-05 23:35:00 +00:00
2016-12-22 23:05:49 +00:00
< p > < details >
< summary > < b > Examples< / b > < / summary >
< ul > < li > < a href = "./examples/data-fetch" > Data fetch< / a > < / li > < / ul >
< / details > < / p >
2016-12-19 21:34:19 +00:00
When you need state, lifecycle hooks or **initial data population** you can export a `React.Component` (instead of a stateless function, like shown above):
2016-10-05 23:35:00 +00:00
2016-10-05 23:58:36 +00:00
```jsx
2016-10-05 23:35:00 +00:00
import React from 'react'
export default class extends React.Component {
2016-10-09 00:50:09 +00:00
static async getInitialProps ({ req }) {
return req
2016-10-26 10:19:28 +00:00
? { userAgent: req.headers['user-agent'] }
2016-10-05 23:35:00 +00:00
: { userAgent: navigator.userAgent }
}
render () {
return < div >
Hello World {this.props.userAgent}
< / div >
}
}
```
2016-11-01 01:13:42 +00:00
Notice that to load data when the page loads, we use `getInitialProps` which is an [`async` ](https://zeit.co/blog/async-and-await ) static method. It can asynchronously fetch anything that resolves to a JavaScript plain `Object` , which populates `props` .
2016-12-19 15:16:44 +00:00
For the initial page load, `getInitialProps` will execute on the server only. `getInitialProps` will only be executed on the client when navigating to a different route via the `Link` component or using the routing APIs.
2016-11-04 11:37:36 +00:00
2017-02-15 02:58:13 +00:00
_Note: `getInitialProps` can **not** be used in children components. Only in `pages` ._
2017-03-29 22:11:18 +00:00
You can also define the `getInitialProps` lifecycle method for stateless components:
```jsx
const Page = ({ stars }) => < div > Next stars: {stars}< / div >
Page.getInitialProps = async ({ req }) => {
const res = await fetch('https://api.github.com/repos/zeit/next.js')
const json = await res.json()
return { stars: json.stargazers_count }
}
export default Page
```
2016-12-19 22:36:33 +00:00
`getInitialProps` receives a context object with the following properties:
2016-11-04 08:05:03 +00:00
- `pathname` - path section of URL
- `query` - query string section of URL parsed as an object
2017-05-03 16:40:09 +00:00
- `asPath` - the actual url path
2016-11-04 08:05:03 +00:00
- `req` - HTTP request object (server only)
- `res` - HTTP response object (server only)
2017-03-15 02:37:29 +00:00
- `jsonPageRes` - [Fetch Response ](https://developer.mozilla.org/en-US/docs/Web/API/Response ) object (client only)
2016-11-04 08:05:03 +00:00
- `err` - Error object if any error is encountered during the rendering
2016-12-19 15:16:44 +00:00
### Routing
2016-12-31 01:15:22 +00:00
#### With `<Link>`
2016-12-22 21:08:58 +00:00
< p > < details >
< summary > < b > Examples< / b > < / summary >
2016-12-31 01:15:22 +00:00
< ul >
< li > < a href = "./examples/hello-world" > Hello World< / a > < / li >
< / ul >
2016-12-22 21:08:58 +00:00
< / details > < / p >
2016-12-19 15:04:53 +00:00
Client-side transitions between routes can be enabled via a `<Link>` component. Consider these two pages:
2016-10-05 23:35:00 +00:00
2016-10-05 23:58:36 +00:00
```jsx
2016-12-19 15:04:53 +00:00
// pages/index.js
2016-10-05 23:35:00 +00:00
import Link from 'next/link'
export default () => (
< div > Click < Link href = "/about" > < a > here< / a > < / Link > to read more< / div >
)
```
2016-10-05 23:58:36 +00:00
```jsx
2016-12-19 15:04:53 +00:00
// pages/about.js
2016-10-05 23:35:00 +00:00
export default () => (
< p > Welcome to About!< / p >
)
```
2017-02-19 14:56:33 +00:00
__Note: use [`<Link prefetch>` ](#prefetching-pages ) for maximum performance, to link and prefetch in the background at the same time__
2016-12-26 23:14:27 +00:00
2016-12-19 15:04:53 +00:00
Client-side routing behaves exactly like the browser:
2016-10-05 23:35:00 +00:00
1. The component is fetched
2. If it defines `getInitialProps` , data is fetched. If an error occurs, `_error.js` is rendered
3. After 1 and 2 complete, `pushState` is performed and the new component rendered
Each top-level component receives a `url` property with the following API:
2016-10-26 09:49:05 +00:00
- `pathname` - `String` of the current path excluding the query string
2016-10-05 23:35:00 +00:00
- `query` - `Object` with the parsed query string. Defaults to `{}`
2017-05-03 16:40:09 +00:00
- `asPath` - `String` of the actual path (including the query) shows in the browser
2016-12-19 18:49:15 +00:00
- `push(url, as=url)` - performs a `pushState` call with the given url
- `replace(url, as=url)` - performs a `replaceState` call with the given url
2016-10-05 23:35:00 +00:00
2016-12-19 18:49:15 +00:00
The second `as` parameter for `push` and `replace` is an optional _decoration_ of the URL. Useful if you configured custom routes on the server.
2017-03-12 03:57:51 +00:00
##### With URL object
< p > < details >
< summary > < b > Examples< / b > < / summary >
< ul >
< li > < a href = "./examples/with-url-object-routing" > With URL Object Routing< / a > < / li >
< / ul >
< / details > < / p >
The component `<Link>` can also receive an URL object and it will automatically format it to create the URL string.
```jsx
// pages/index.js
import Link from 'next/link'
export default () => (
2017-04-17 03:30:12 +00:00
< div > Click < Link href = {{ pathname: ' about ' , query: { name: ' Zeit ' } } } > < a > here< / a > < / Link > to read more< / div >
2017-03-12 03:57:51 +00:00
)
```
That will generate the URL string `/about?name=Zeit` , you can use every property as defined in the [Node.js URL module documentation ](https://nodejs.org/api/url.html#url_url_strings_and_url_objects ).
2017-03-14 23:06:34 +00:00
The default behaviour for the `<Link>` component is to `push` a new url into the stack. You can use the `replace` prop to prevent adding a new entry.
```jsx
// pages/index.js
import Link from 'next/link'
export default () => (
< div > Click < Link href = '/about' replace > < a > here< / a > < / Link > to read more< / div >
)
```
2016-12-19 18:49:15 +00:00
#### Imperatively
2016-12-19 14:40:26 +00:00
2016-12-31 01:15:22 +00:00
< p > < details >
< summary > < b > Examples< / b > < / summary >
< ul >
< li > < a href = "./examples/using-router" > Basic routing< / a > < / li >
< li > < a href = "./examples/with-loading" > With a page loading indicator< / a > < / li >
< / ul >
< / details > < / p >
2016-12-19 15:16:44 +00:00
You can also do client-side page transitions using the `next/router`
2016-12-19 14:40:26 +00:00
```jsx
import Router from 'next/router'
export default () => (
2016-12-19 15:17:33 +00:00
< div > Click < span onClick = {() = > Router.push('/about')}>here< / span > to read more< / div >
2016-12-19 14:40:26 +00:00
)
```
Above `Router` object comes with the following API:
- `route` - `String` of the current route
- `pathname` - `String` of the current path excluding the query string
- `query` - `Object` with the parsed query string. Defaults to `{}`
2016-12-19 18:49:15 +00:00
- `push(url, as=url)` - performs a `pushState` call with the given url
- `replace(url, as=url)` - performs a `replaceState` call with the given url
2016-12-19 14:40:26 +00:00
2016-12-19 15:04:53 +00:00
The second `as` parameter for `push` and `replace` is an optional _decoration_ of the URL. Useful if you configured custom routes on the server.
2016-12-19 14:40:26 +00:00
2016-12-22 03:52:43 +00:00
_Note: in order to programmatically change the route without triggering navigation and component-fetching, use `props.url.push` and `props.url.replace` within a component_
2016-12-19 15:16:44 +00:00
2017-03-12 03:57:51 +00:00
##### With URL object
You can use an URL object the same way you use it in a `<Link>` component to `push` and `replace` an url.
```jsx
import Router from 'next/router'
const handler = () => Router.push({
pathname: 'about',
query: { name: 'Zeit' }
})
export default () => (
< div > Click < span onClick = {handler} > here< / span > to read more< / div >
)
```
This uses of the same exact parameters as in the `<Link>` component.
2016-12-31 01:15:22 +00:00
##### Router Events
You can also listen to different events happening inside the Router.
Here's a list of supported events:
- `routeChangeStart(url)` - Fires when a route starts to change
- `routeChangeComplete(url)` - Fires when a route changed completely
- `routeChangeError(err, url)` - Fires when there's an error when changing routes
2017-03-08 16:30:47 +00:00
- `beforeHistoryChange(url)` - Fires just before changing the browser's history
2017-02-20 23:48:17 +00:00
- `appUpdated(nextRoute)` - Fires when switching pages and there's a new version of the app
2016-12-31 01:15:22 +00:00
> Here `url` is the URL shown in the browser. If you call `Router.push(url, as)` (or similar), then the value of `url` will be `as`.
2017-01-16 10:41:46 +00:00
Here's how to properly listen to the router event `routeChangeStart` :
2016-12-31 01:15:22 +00:00
```js
Router.onRouteChangeStart = (url) => {
console.log('App is changing to: ', url)
}
```
If you are no longer want to listen to that event, you can simply unset the event listener like this:
```js
Router.onRouteChangeStart = null
```
2016-12-31 01:37:06 +00:00
If a route load is cancelled (for example by clicking two links rapidly in succession), `routeChangeError` will fire. The passed `err` will contained a `cancelled` property set to `true` .
2016-12-31 01:15:22 +00:00
```js
Router.onRouteChangeError = (err, url) => {
if (err.cancelled) {
2016-12-31 01:37:06 +00:00
console.log(`Route to ${url} was cancelled!`)
2016-12-31 01:15:22 +00:00
}
}
```
2017-02-20 23:48:17 +00:00
If you change a route while in between a new deployment, we can't navigate the app via client side. We need to do a full browser navigation. We do it automatically for you.
But you can customize that via `Route.onAppUpdated` event like this:
```js
Router.onAppUpdated = (nextUrl) => {
// persist the local state
location.href = nextUrl
}
```
2017-03-06 16:48:35 +00:00
##### Shallow Routing
< p > < details >
< summary > < b > Examples< / b > < / summary >
< ul >
< li > < a href = "./examples/with-shallow-routing" > Shallow Routing< / a > < / li >
< / ul >
< / details > < / p >
2017-03-15 12:24:34 +00:00
Shallow routing allows you to change the URL without running `getInitialProps` . You'll receive the updated `pathname` and the `query` via the `url` prop of the same page that's loaded, without losing state.
2017-03-06 16:48:35 +00:00
2017-04-02 07:28:39 +00:00
You can do this by invoking either `Router.push` or `Router.replace` with the `shallow: true` option. Here's an example:
2017-03-06 16:48:35 +00:00
2017-03-06 16:51:19 +00:00
```jsx
2017-03-06 16:48:35 +00:00
// Current URL is "/"
const href = '/?counter=10'
const as = href
Router.push(href, as, { shallow: true })
```
2017-03-06 16:51:19 +00:00
Now, the URL is updated to `/?counter=10` . You can see the updated URL with `this.props.url` inside the `Component` .
2017-03-06 16:48:35 +00:00
2017-03-06 16:51:19 +00:00
You can watch for URL changes via [`componentWillReceiveProps` ](https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops ) hook as shown below:
2017-03-06 16:48:35 +00:00
2017-03-06 16:51:19 +00:00
```jsx
2017-03-06 16:48:35 +00:00
componentWillReceiveProps(nextProps) {
const { pathname, query } = nextProps.url
// fetch data based on the new query
}
```
> NOTES:
2017-03-15 02:38:00 +00:00
>
2017-03-06 16:51:19 +00:00
> Shallow routing works **only** for same page URL changes. For an example, let's assume we've another page called `about`, and you run this:
2017-03-06 16:48:35 +00:00
> ```js
> Router.push('/about?counter=10', '/about?counter=10', { shallow: true })
> ```
2017-04-26 11:24:46 +00:00
> Since that's a new page, it'll unload the current page, load the new one and call `getInitialProps` even though we asked to do shallow routing.
2017-03-06 16:48:35 +00:00
2016-12-15 19:13:40 +00:00
### Prefetching Pages
2017-03-01 16:54:41 +00:00
(This is a production only feature)
2016-12-22 23:05:49 +00:00
< p > < details >
2016-12-22 21:04:32 +00:00
< summary > < b > Examples< / b > < / summary >
2016-12-22 23:05:49 +00:00
< ul > < li > < a href = "./examples/with-prefetching" > Prefetching< / a > < / li > < / ul >
< / details > < / p >
2016-12-22 21:04:32 +00:00
2017-02-15 08:52:22 +00:00
Next.js has an API which allows you to prefetch pages.
2016-12-15 19:13:40 +00:00
2016-12-19 14:40:26 +00:00
Since Next.js server-renders your pages, this allows all the future interaction paths of your app to be instant. Effectively Next.js gives you the great initial download performance of a _website_ , with the ahead-of-time download capabilities of an _app_ . [Read more ](https://zeit.co/blog/next#anticipation-is-the-key-to-performance ).
2016-12-15 19:13:40 +00:00
2017-02-15 08:52:22 +00:00
> With prefetching Next.js only download JS code. When the page is getting rendered, you may need to wait for the data.
2016-12-19 15:16:44 +00:00
#### With `<Link>`
2016-12-15 19:13:40 +00:00
2017-02-15 08:52:22 +00:00
You can add `prefetch` prop to any `<Link>` and Next.js will prefetch those pages in the background.
2016-12-15 19:13:40 +00:00
```jsx
2017-02-15 08:52:22 +00:00
import Link from 'next/link'
2016-12-17 19:16:22 +00:00
// example header component
2016-12-15 19:13:40 +00:00
export default () => (
2016-12-17 19:16:22 +00:00
< nav >
< ul >
2017-02-16 00:35:25 +00:00
< li > < Link prefetch href = '/' > < a > Home< / a > < / Link > < / li >
2017-02-15 08:52:22 +00:00
< li > < Link prefetch href = '/about' > < a > About< / a > < / Link > < / li >
< li > < Link prefetch href = '/contact' > < a > Contact< / a > < / Link > < / li >
2016-12-17 19:16:22 +00:00
< / ul >
< / nav >
2016-12-15 19:13:40 +00:00
)
```
2016-12-19 15:16:44 +00:00
#### Imperatively
2016-12-15 19:13:40 +00:00
2017-02-15 08:52:22 +00:00
Most prefetching needs are addressed by `<Link />` , but we also expose an imperative API for advanced usage:
2016-12-15 19:13:40 +00:00
```jsx
2017-02-15 08:52:22 +00:00
import Router from 'next/router'
2016-12-17 19:48:52 +00:00
export default ({ url }) => (
2016-12-20 22:57:11 +00:00
< div >
< a onClick = { ( ) = > setTimeout(() => url.pushTo('/dynamic'), 100) }>
A route transition will happen after 100ms
< / a >
{
// but we can prefetch it!
2017-02-15 08:52:22 +00:00
Router.prefetch('/dynamic')
2016-12-20 22:57:11 +00:00
}
< / div >
2016-12-17 19:16:22 +00:00
)
```
2016-12-15 19:13:40 +00:00
2016-12-20 19:19:03 +00:00
### Custom server and routing
2016-12-22 23:05:49 +00:00
< p > < details >
2016-12-22 21:04:32 +00:00
< summary > < b > Examples< / b > < / summary >
2016-12-22 23:05:49 +00:00
< ul >
< li > < a href = "./examples/custom-server" > Basic custom server< / a > < / li >
< li > < a href = "./examples/custom-server-express" > Express integration< / a > < / li >
2017-01-19 13:22:21 +00:00
< li > < a href = "./examples/custom-server-hapi" > Hapi integration< / a > < / li >
2017-01-17 07:23:06 +00:00
< li > < a href = "./examples/custom-server-koa" > Koa integration< / a > < / li >
2016-12-22 23:05:49 +00:00
< li > < a href = "./examples/parameterized-routing" > Parameterized routing< / a > < / li >
2016-12-24 01:30:06 +00:00
< li > < a href = "./examples/ssr-caching" > SSR caching< / a > < / li >
2016-12-22 23:05:49 +00:00
< / ul >
< / details > < / p >
2016-12-22 21:04:32 +00:00
2016-12-20 19:19:03 +00:00
Typically you start your next server with `next start` . It's possible, however, to start a server 100% programmatically in order to customize routes, use route patterns, etc
This example makes `/a` resolve to `./pages/b` , and `/b` resolve to `./pages/a` :
2016-12-20 19:27:29 +00:00
```js
2016-12-20 19:19:03 +00:00
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
2017-01-31 14:18:10 +00:00
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
2016-12-20 19:19:03 +00:00
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
2017-02-25 18:35:10 +00:00
// Be sure to pass `true` as the second argument to `url.parse` .
// This tells it to parse the query portion of the URL.
2017-02-02 06:51:08 +00:00
const parsedUrl = parse(req.url, true)
const { pathname, query } = parsedUrl
2016-12-20 19:19:03 +00:00
if (pathname === '/a') {
app.render(req, res, '/b', query)
} else if (pathname === '/b') {
app.render(req, res, '/a', query)
} else {
2017-02-02 06:51:08 +00:00
handle(req, res, parsedUrl)
2016-12-20 19:19:03 +00:00
}
})
.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
```
2016-12-20 19:26:59 +00:00
The `next` API is as follows:
2017-03-28 16:22:25 +00:00
- `next(path: string, opts: object)` - `path` is where the Next project is located
2016-12-20 19:26:59 +00:00
- `next(opts: object)`
Supported options:
2016-12-20 22:57:11 +00:00
- `dev` (`bool`) whether to launch Next.js in dev mode - default `false`
- `dir` (`string`) where the Next project is located - default `'.'`
2017-02-12 16:26:51 +00:00
- `quiet` (`bool`) Hide error messages containing server information - default `false`
2016-12-20 19:26:59 +00:00
2017-02-13 15:09:11 +00:00
Then, change your `start` script to `NODE_ENV=production node server.js` .
2016-12-19 21:34:19 +00:00
### Custom `<Document>`
2016-12-22 23:05:49 +00:00
< p > < details >
2016-12-22 21:04:32 +00:00
< summary > < b > Examples< / b > < / summary >
2016-12-22 23:05:49 +00:00
< ul > < li > < a href = "./examples/with-styled-components" > Styled components custom document< / a > < / li > < / ul >
2017-01-24 13:20:56 +00:00
< ul > < li > < a href = "./examples/with-amp" > Google AMP< / a > < / li > < / ul >
2016-12-22 23:05:49 +00:00
< / details > < / p >
2016-12-22 21:04:32 +00:00
2017-01-21 21:24:17 +00:00
Pages in `Next.js` skip the definition of the surrounding document's markup. For example, you never include `<html>` , `<body>` , etc. To override that default behavior, you must create a file at `./pages/_document.js` , where you can extend the `Document` class:
2016-12-19 21:34:19 +00:00
```jsx
2017-01-21 21:24:17 +00:00
// ./pages/_document.js
2017-01-17 04:26:23 +00:00
import Document, { Head, Main, NextScript } from 'next/document'
2017-02-27 23:45:49 +00:00
import flush from 'styled-jsx/server'
2016-12-19 21:34:19 +00:00
export default class MyDocument extends Document {
2017-02-27 23:45:49 +00:00
static getInitialProps ({ renderPage }) {
const {html, head} = renderPage()
const styles = flush()
return { html, head, styles }
2016-12-19 21:34:19 +00:00
}
render () {
return (
< html >
< Head >
2016-12-19 22:25:03 +00:00
< style > { ` b o d y { margin : 0 } /* custom! */ ` } < / style >
2016-12-19 21:34:19 +00:00
< / Head >
2016-12-19 22:25:03 +00:00
< body className = "custom_class" >
{this.props.customValue}
2016-12-19 21:34:19 +00:00
< Main / >
< NextScript / >
< / body >
< / html >
)
}
}
```
2016-12-19 22:41:21 +00:00
The `ctx` object is equivalent to the one received in all [`getInitialProps` ](#fetching-data-and-component-lifecycle ) hooks, with one addition:
2016-12-19 22:35:26 +00:00
- `renderPage` (`Function`) a callback that executes the actual React rendering logic (synchronously). It's useful to decorate this function in order to support server-rendering wrappers like Aphrodite's [`renderStatic` ](https://github.com/Khan/aphrodite#server-side-rendering )
2017-05-04 23:44:28 +00:00
__Note: React-components outside of `<Main />` will not be initialised by the browser. If you need shared components in all your pages (like a menu or a toolbar), do _not_ add application logic here, but take a look at [this example ](https://github.com/zeit/next.js/tree/master/examples/layout-component ).__
2016-12-17 19:33:07 +00:00
### Custom error handling
2016-10-15 22:36:54 +00:00
404 or 500 errors are handled both client and server side by a default component `error.js` . If you wish to override it, define a `_error.js` :
```jsx
import React from 'react'
2016-10-16 22:44:26 +00:00
export default class Error extends React.Component {
2017-03-15 02:37:29 +00:00
static getInitialProps ({ res, jsonPageRes }) {
const statusCode = res ? res.statusCode : (jsonPageRes ? jsonPageRes.status : null)
2016-10-16 22:44:26 +00:00
return { statusCode }
}
render () {
return (
2016-11-24 14:03:16 +00:00
< p > {
this.props.statusCode
? `An error ${this.props.statusCode} occurred on server`
: 'An error occurred on client'
2016-12-13 05:36:20 +00:00
}< / p >
2016-10-16 22:44:26 +00:00
)
}
}
2016-10-15 22:36:54 +00:00
```
2016-12-17 19:33:07 +00:00
### Custom configuration
2016-12-17 19:04:44 +00:00
2016-12-19 14:40:26 +00:00
For custom advanced behavior of Next.js, you can create a `next.config.js` in the root of your project directory (next to `pages/` and `package.json` ).
2016-12-17 19:04:44 +00:00
Note: `next.config.js` is a regular Node.js module, not a JSON file. It gets used by the Next server and build phases, and not included in the browser build.
```javascript
// next.config.js
module.exports = {
/* config options here */
}
```
2017-04-06 10:09:26 +00:00
#### Setting a custom build directory
You can specify a name to use for a custom build directory. For example, the following config will create a `build` folder instead of a `.next` folder. If no configuration is specified then next will create a `.next` folder.
```javascript
// next.config.js
module.exports = {
distDir: 'build'
}
```
2016-12-17 19:04:44 +00:00
### Customizing webpack config
2016-12-19 22:37:15 +00:00
In order to extend our usage of `webpack` , you can define a function that extends its config via `next.config.js` .
2016-12-17 19:04:44 +00:00
```js
2016-12-22 01:36:00 +00:00
// 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)
module.exports = {
webpack: (config, { dev }) => {
2017-01-03 18:06:55 +00:00
// Perform customizations to config
// Important: return the modified config
2016-12-22 01:36:00 +00:00
return config
}
}
```
2017-01-03 18:06:55 +00:00
*Warning: Adding loaders to support new file types (css, less, svg, etc.) is __not__ recommended because only the client code gets bundled via webpack and thus it won't work on the initial server rendering. Babel plugins are a good alternative because they're applied consistently between server/client rendering (e.g. [babel-plugin-inline-react-svg ](https://github.com/kesne/babel-plugin-inline-react-svg )).*
2016-12-22 01:36:00 +00:00
### Customizing babel config
2017-02-09 17:57:17 +00:00
< p > < details >
< summary > < b > Examples< / b > < / summary >
< ul > < li > < a href = "./examples/with-custom-babel-config" > Custom babel configuration< / a > < / li > < / ul >
< / details > < / p >
2016-12-29 13:58:28 +00:00
In order to extend our usage of `babel` , you can simply define a `.babelrc` file at the root of your app. This file is optional.
If found, we're going to consider it the *source of truth* , therefore it needs to define what next needs as well, which is the `next/babel` preset.
This is designed so that you are not surprised by modifications we could make to the babel configurations.
Here's an example `.babelrc` file:
2016-12-22 01:36:00 +00:00
```js
2016-12-26 18:13:45 +00:00
{
"presets": [
"next/babel",
"stage-0"
],
2016-12-17 19:04:44 +00:00
}
```
2017-04-18 04:18:43 +00:00
### CDN support with Asset Prefix
To set up a CDN, you can set up the `assetPrefix` setting and configure your CDN's origin to resolve to the domain that Next.js is hosted on.
```js
2017-04-27 13:21:50 +00:00
const isProd = process.env.NODE_ENV === 'production'
2017-04-18 04:18:43 +00:00
module.exports = {
// You may only need to add assetPrefix in the production.
assetPrefix: isProd ? 'https://cdn.mydomain.com' : ''
}
```
Note: Next.js will automatically use that prefix the scripts it loads, but this has no effect whatsoever on `/static` . If you want to serve those assets over the CDN, you'll have to introduce the prefix yourself. One way of introducing a prefix that works inside your components and varies by environment is documented [in this example ](https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration ).
2016-10-20 00:58:42 +00:00
## Production deployment
2016-10-05 23:35:00 +00:00
2017-03-15 02:38:00 +00:00
To deploy, instead of running `next` , you want to build for production usage ahead of time. Therefore, building and starting are separate commands:
2016-10-05 23:35:00 +00:00
2016-10-05 23:58:36 +00:00
```bash
2016-10-05 23:35:00 +00:00
next build
next start
```
2016-10-20 00:58:42 +00:00
For example, to deploy with [`now` ](https://zeit.co/now ) a `package.json` like follows is recommended:
2016-10-05 23:35:00 +00:00
2016-10-05 23:58:36 +00:00
```json
2016-10-05 23:35:00 +00:00
{
"name": "my-app",
"dependencies": {
"next": "latest"
},
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
}
}
```
2016-10-15 13:15:10 +00:00
2016-10-20 00:58:42 +00:00
Then run `now` and enjoy!
2017-03-15 02:40:10 +00:00
Next.js can be deployed to other hosting solutions too. Please have a look at the ['Deployment' ](https://github.com/zeit/next.js/wiki/Deployment ) section of the wiki.
2017-03-15 02:38:00 +00:00
2017-04-06 10:09:26 +00:00
Note: we recommend putting `.next` , or your custom dist folder (Please have a look at ['Custom Config' ](You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration. )), in `.npmignore` or `.gitignore` . Otherwise, use `files` or `now.files` to opt-into a whitelist of files you want to deploy (and obviously exclude `.next` or your custom dist folder)
2016-10-20 00:58:42 +00:00
2017-05-09 18:22:14 +00:00
## Recipes
- [Setting up 301 redirects ](https://www.raygesualdo.com/posts/301-redirects-with-nextjs/ )
2016-10-20 00:58:42 +00:00
## FAQ
2016-10-15 13:15:10 +00:00
2016-10-24 19:59:46 +00:00
< details >
< summary > Is this production ready?< / summary >
2017-03-24 19:50:56 +00:00
Next.js has been powering https://zeit.co since its inception.
2016-10-25 10:32:03 +00:00
2016-10-24 19:59:46 +00:00
We’ re ecstatic about both the developer experience and end-user performance, so we decided to share it with the community.
< / details >
2016-10-15 13:16:25 +00:00
2016-10-24 19:59:46 +00:00
< details >
< summary > How big is it?< / summary >
2016-12-20 22:57:11 +00:00
The client side bundle size should be measured in a per-app basis.
A small Next main bundle is around 65kb gzipped.
2016-10-24 19:59:46 +00:00
< / details >
< details >
< summary > Is this like `create-react-app` ?</ summary >
2016-10-25 10:32:03 +00:00
2016-10-24 19:59:46 +00:00
Yes and No.
Yes in that both make your life easier.
No in that it enforces a _structure_ so that we can do more advanced things like:
2016-10-25 06:09:45 +00:00
- Server side rendering
- Automatic code splitting
2016-10-24 19:59:46 +00:00
In addition, Next.js provides two built-in features that are critical for every single website:
2017-01-29 00:59:29 +00:00
- Routing with lazy component loading: `<Link>` (by importing `next/link` )
2016-10-25 06:09:45 +00:00
- A way for components to alter `<head>` : `<Head>` (by importing `next/head` )
2016-10-24 19:59:46 +00:00
2016-10-25 06:09:45 +00:00
If you want to create re-usable React components that you can embed in your Next.js app or other React applications, using `create-react-app` is a great idea. You can later `import` it and keep your codebase clean!
2016-10-24 19:59:46 +00:00
< / details >
< details >
2016-12-22 05:30:06 +00:00
< summary > How do I use CSS-in-JS solutions?< / summary >
2016-10-24 19:59:46 +00:00
2016-12-20 22:57:11 +00:00
Next.js bundles [styled-jsx ](https://github.com/zeit/styled-jsx ) supporting scoped css. However you can use a CSS-in-JS solution in your Next app by just including your favorite library [as mentioned before ](#css-in-js ) in the document.
2016-10-24 19:59:46 +00:00
< / details >
< details >
< summary > What syntactic features are transpiled? How do I change them?< / summary >
We track V8. Since V8 has wide support for ES6 and `async` and `await` , we transpile those. Since V8 doesn’ t support class decorators, we don’ t transpile those.
2016-10-26 10:04:01 +00:00
See [this ](https://github.com/zeit/next.js/blob/master/server/build/webpack.js#L79 ) and [this ](https://github.com/zeit/next.js/issues/26 )
2016-10-24 19:59:46 +00:00
< / details >
< details >
< summary > Why a new Router?< / summary >
Next.js is special in that:
- Routes don’ t need to be known ahead of time
2016-10-26 09:47:41 +00:00
- Routes are always lazy-loadable
2016-10-24 19:59:46 +00:00
- Top-level components can define `getInitialProps` that should _block_ the loading of the route (either when server-rendering or lazy-loading)
As a result, we were able to introduce a very simple approach to routing that consists of two pieces:
- Every top level component receives a `url` object to inspect the url or perform modifications to the history
- A `<Link />` component is used to wrap elements like anchors (`< a /> `) to perform client-side transitions
We tested the flexibility of the routing with some interesting scenarios. For an example, check out [nextgram ](https://github.com/zeit/nextgram ).
< / details >
< details >
< summary > How do I define a custom fancy route?< / summary >
2016-12-20 22:57:11 +00:00
We [added ](#custom-server-and-routing ) the ability to map between an arbitrary URL and any component by supplying a request handler.
2016-10-24 19:59:46 +00:00
2016-12-20 22:57:11 +00:00
On the client side, we have a parameter call `as` on `<Link>` that _decorates_ the URL differently from the URL it _fetches_ .
2016-10-24 19:59:46 +00:00
< / details >
< details >
< summary > How do I fetch data?< / summary >
It’ s up to you. `getInitialProps` is an `async` function (or a regular function that returns a `Promise` ). It can retrieve data from anywhere.
< / details >
2017-01-22 12:27:06 +00:00
< details >
< summary > Can I use it with GraphQL?< / summary >
Yes! Here's an example with [Apollo ](./examples/with-apollo ).
< / details >
2016-10-25 10:34:14 +00:00
< details >
< summary > Can I use it with Redux?< / summary >
2016-12-22 21:04:32 +00:00
Yes! Here's an [example ](./examples/with-redux )
2016-10-25 10:34:14 +00:00
< / details >
2016-10-24 19:59:46 +00:00
< details >
< summary > What is this inspired by?< / summary >
Many of the goals we set out to accomplish were the ones listed in [The 7 principles of Rich Web Applications ](http://rauchg.com/2014/7-principles-of-rich-web-applications/ ) by Guillermo Rauch.
The ease-of-use of PHP is a great inspiration. We feel Next.js is a suitable replacement for many scenarios where you otherwise would use PHP to output HTML.
Unlike PHP, we benefit from the ES6 module system and every file exports a **component or function** that can be easily imported for lazy evaluation or testing.
As we were researching options for server-rendering React that didn’ t involve a large number of steps, we came across [react-page ](https://github.com/facebookarchive/react-page ) (now deprecated), a similar approach to Next.js by the creator of React Jordan Walke.
< / details >
2017-02-06 13:19:34 +00:00
## Contributing
2017-02-17 13:36:47 +00:00
Please see our [contributing.md ](./contributing.md )
2017-02-06 13:19:34 +00:00
2016-10-24 19:40:29 +00:00
## Authors
2016-10-25 10:32:03 +00:00
- Naoyuki Kanezawa ([@nkzawa](https://twitter.com/nkzawa)) – ▲ZEIT
2016-10-25 18:42:57 +00:00
- Tony Kovanen ([@tonykovanen](https://twitter.com/tonykovanen)) – ▲ZEIT
2016-10-25 10:32:03 +00:00
- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) – ▲ZEIT
2016-10-24 19:40:29 +00:00
- Dan Zajdband ([@impronunciable](https://twitter.com/impronunciable)) – Knight-Mozilla / Coral Project
2017-01-10 20:55:48 +00:00
- Tim Neutkens ([@timneutkens](https://github.com/timneutkens))