README.md 69.8 KB
Newer Older
T
Tim Neutkens 已提交
1
[![Next.js](https://assets.zeit.co/image/upload/v1538361091/repositories/next-js/next-js.png)](https://nextjs.org)
G
Guillermo Rauch 已提交
2

3
[![NPM version](https://img.shields.io/npm/v/next.svg)](https://www.npmjs.com/package/next)
N
nkzawa 已提交
4
[![Build Status](https://travis-ci.org/zeit/next.js.svg?branch=master)](https://travis-ci.org/zeit/next.js)
H
Henrik Wenz 已提交
5
[![Build Status](https://dev.azure.com/nextjs/next.js/_apis/build/status/zeit.next.js)](https://dev.azure.com/nextjs/next.js/_build/latest?definitionId=3)
B
Benjamin Coe 已提交
6
[![Coverage Status](https://coveralls.io/repos/zeit/next.js/badge.svg?branch=master)](https://coveralls.io/r/zeit/next.js?branch=master)
M
Max Stoiber 已提交
7
[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/next-js)
S
Sébastien Dubois 已提交
8

R
Raven 已提交
9
**Visit [nextjs.org/learn](https://nextjs.org/learn) to get started with Next.js.**
10 11 12

---

13 14 15 16
**The below readme is the documentation for the `canary` (prerelease) branch. To view the documentation for the latest stable Next.js version visit [nextjs.org/docs](https://nextjs.org/docs)**

---

17 18 19 20 21 22 23 24 25 26
<!-- 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)
T
Tim Neutkens 已提交
27
    - [Importing CSS / Sass / Less / Stylus files](#importing-css--sass--less--stylus-files)
28 29 30 31 32
  - [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)
T
Tim Neutkens 已提交
33 34 35 36 37
      - [With URL object](#with-url-object)
      - [Replace instead of push url](#replace-instead-of-push-url)
      - [Using a component that supports `onClick`](#using-a-component-that-supports-onclick)
      - [Forcing the Link to expose `href` to its child](#forcing-the-link-to-expose-href-to-its-child)
      - [Disabling the scroll changes to top on page](#disabling-the-scroll-changes-to-top-on-page)
38
    - [Imperatively](#imperatively)
T
Tim Neutkens 已提交
39 40
    - [Intercepting `popstate`](#intercepting-popstate)
      - [With URL object](#with-url-object-1)
41
      - [Router Events](#router-events)
42
      - [Shallow Routing](#shallow-routing)
A
Arunoda Susiripala 已提交
43
    - [Using a Higher Order Component](#using-a-higher-order-component)
44 45 46 47
  - [Prefetching Pages](#prefetching-pages)
    - [With `<Link>`](#with-link-1)
    - [Imperatively](#imperatively-1)
  - [Custom server and routing](#custom-server-and-routing)
T
Tim Neutkens 已提交
48 49
    - [Disabling file-system routing](#disabling-file-system-routing)
    - [Dynamic assetPrefix](#dynamic-assetprefix)
50
  - [Dynamic Import](#dynamic-import)
T
Tim Neutkens 已提交
51 52 53 54 55
    - [1. Basic Usage (Also does SSR)](#1-basic-usage-also-does-ssr)
    - [2. With Custom Loading Component](#2-with-custom-loading-component)
    - [3. With No SSR](#3-with-no-ssr)
    - [4. With Multiple Modules At Once](#4-with-multiple-modules-at-once)
  - [Custom `<App>`](#custom-app)
56
  - [Custom `<Document>`](#custom-document)
57
    - [Customizing `renderPage`](#customizing-renderpage)
58
  - [Custom error handling](#custom-error-handling)
T
Tim Neutkens 已提交
59
  - [Reusing the built-in error page](#reusing-the-built-in-error-page)
60
  - [Custom configuration](#custom-configuration)
T
Tim Neutkens 已提交
61 62 63 64 65
    - [Setting a custom build directory](#setting-a-custom-build-directory)
    - [Disabling etag generation](#disabling-etag-generation)
    - [Configuring the onDemandEntries](#configuring-the-ondemandentries)
    - [Configuring extensions looked for when resolving pages in `pages`](#configuring-extensions-looked-for-when-resolving-pages-in-pages)
    - [Configuring the build ID](#configuring-the-build-id)
D
DevSide 已提交
66
    - [Configuring Next process script](#configuring-next-process-script)
67 68
  - [Customizing webpack config](#customizing-webpack-config)
  - [Customizing babel config](#customizing-babel-config)
69
  - [Exposing configuration to the server / client side](#exposing-configuration-to-the-server--client-side)
70
  - [Starting the server on alternative hostname](#starting-the-server-on-alternative-hostname)
71
  - [CDN support with Asset Prefix](#cdn-support-with-asset-prefix)
72
- [Production deployment](#production-deployment)
73
  - [Serverless deployment](#serverless-deployment)
74 75 76
    - [One Level Lower](#one-level-lower)
    - [Summary](#summary)
- [Browser support](#browser-support)
A
Arunoda Susiripala 已提交
77
- [Static HTML export](#static-html-export)
T
Tim Neutkens 已提交
78
  - [Usage](#usage)
79
  - [Copying custom files](#copying-custom-files)
T
Tim Neutkens 已提交
80
  - [Limitation](#limitation)
81
- [Multi Zones](#multi-zones)
T
Tim Neutkens 已提交
82 83
  - [How to define a zone](#how-to-define-a-zone)
  - [How to merge them](#how-to-merge-them)
84
- [Recipes](#recipes)
85
- [FAQ](#faq)
T
Tim Neutkens 已提交
86
- [Contributing](#contributing)
87 88 89
- [Authors](#authors)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
G
Guillermo Rauch 已提交
90

G
Guillermo Rauch 已提交
91 92
## How to use

93 94
### Setup

G
Guillermo Rauch 已提交
95 96
Install it:

T
Tim Neutkens 已提交
97
```bash
A
Arunoda Susiripala 已提交
98
npm install --save next react react-dom
T
Tim Neutkens 已提交
99 100
```

101 102 103 104 105
and add a script to your package.json like this:

```json
{
  "scripts": {
106 107 108
    "dev": "next",
    "build": "next build",
    "start": "next start"
109
  }
110 111 112
}
```

G
Guillermo Rauch 已提交
113
After that, the file-system is the main API. Every `.js` file becomes a route that gets automatically processed and rendered.
G
Guillermo Rauch 已提交
114

G
Guillermo Rauch 已提交
115
Populate `./pages/index.js` inside your project:
G
Guillermo Rauch 已提交
116

G
Guillermo Rauch 已提交
117
```jsx
118 119 120 121 122
function Home() {
  return <div>Welcome to next.js!</div>
}

export default Home
G
Guillermo Rauch 已提交
123 124
```

125
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>`.
G
Guillermo Rauch 已提交
126 127 128 129 130

So far, we get:

- Automatic transpilation and bundling (with webpack and babel)
- Hot code reloading
G
Guillermo Rauch 已提交
131
- Server rendering and indexing of `./pages`
132
- Static file serving. `./static/` is mapped to `/static/` (given you [create a `./static/` directory](#static-file-serving-eg-images) inside your project)
G
Guillermo Rauch 已提交
133

T
Tony Kovanen 已提交
134
To see how simple this is, check out the [sample app - nextgram](https://github.com/zeit/nextgram)
135

G
Guillermo Rauch 已提交
136
### Automatic code splitting
G
Guillermo Rauch 已提交
137

G
Guillermo Rauch 已提交
138
Every `import` you declare gets bundled and served with each page. That means pages never load unnecessary code!
G
Guillermo Rauch 已提交
139

G
Guillermo Rauch 已提交
140
```jsx
D
Dan Zajdband 已提交
141
import cowsay from 'cowsay-browser'
142

143 144 145 146 147 148 149 150 151
function CowsayHi() {
  return (
    <pre>
      {cowsay.say({ text: 'hi there!' })}
    </pre>
  )
}

export default CowsayHi
G
Guillermo Rauch 已提交
152 153 154 155
```

### CSS

G
Guillermo Rauch 已提交
156
#### Built-in CSS support
157

S
Shu Ding 已提交
158
<details>
159
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
160
  <ul>
161
    <li><a href="/examples/basic-css">Basic css</a></li>
S
Shu Ding 已提交
162 163 164 165
  </ul>
</details>

<p></p>
166

167
We bundle [styled-jsx](https://github.com/zeit/styled-jsx) to provide support for isolated scoped CSS. The aim is to support "shadow CSS" similar to Web Components, which unfortunately [do not support server-rendering and are JS-only](https://github.com/w3c/webcomponents/issues/71).
G
Guillermo Rauch 已提交
168

G
Guillermo Rauch 已提交
169
```jsx
170 171 172 173 174 175 176 177 178
function HelloWorld() {
  return (
    <div>
      Hello world
      <p>scoped!</p>
      <style jsx>{`
        p {
          color: blue;
        }
G
Guillermo Rauch 已提交
179
        div {
180
          background: red;
G
Guillermo Rauch 已提交
181
        }
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
        @media (max-width: 600px) {
          div {
            background: blue;
          }
        }
      `}</style>
      <style global jsx>{`
        body {
          background: black;
        }
      `}</style>
    </div>
  )
}

export default HelloWorld
G
Guillermo Rauch 已提交
198 199
```

200
Please see the [styled-jsx documentation](https://www.npmjs.com/package/styled-jsx) for more examples.
201

G
Guillermo Rauch 已提交
202 203
#### CSS-in-JS

S
Shu Ding 已提交
204
<details>
205 206
  <summary>
    <b>Examples</b>
S
Shu Ding 已提交
207 208
  </summary>
  <ul>
209 210 211 212 213 214
    <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-cxs">Cxs</a></li>
    <li><a href="/examples/with-aphrodite">Aphrodite</a></li>
    <li><a href="/examples/with-fela">Fela</a></li>
S
Shu Ding 已提交
215 216 217 218
  </ul>
</details>

<p></p>
N
Naoyuki Kanezawa 已提交
219

G
Guillermo Rauch 已提交
220
It's possible to use any existing CSS-in-JS solution. The simplest one is inline styles:
G
Guillermo Rauch 已提交
221

G
Guillermo Rauch 已提交
222
```jsx
223 224 225 226 227
function HiThere() {
  return <p style={{ color: 'red' }}>hi there</p>
}

export default HiThere
G
Guillermo Rauch 已提交
228 229
```

230
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.
G
Guillermo Rauch 已提交
231

232
#### Importing CSS / Sass / Less / Stylus files
T
Tim Neutkens 已提交
233

234
To support importing `.css`, `.scss`, `.less` or `.styl` files you can use these modules, which configure sensible defaults for server rendered applications.
T
Tim Neutkens 已提交
235

J
Juan Caicedo 已提交
236 237 238
- [@zeit/next-css](https://github.com/zeit/next-plugins/tree/master/packages/next-css)
- [@zeit/next-sass](https://github.com/zeit/next-plugins/tree/master/packages/next-sass)
- [@zeit/next-less](https://github.com/zeit/next-plugins/tree/master/packages/next-less)
239
- [@zeit/next-stylus](https://github.com/zeit/next-plugins/tree/master/packages/next-stylus)
T
Tim Neutkens 已提交
240

G
Guillermo Rauch 已提交
241
### Static file serving (e.g.: images)
242

G
Guillermo Rauch 已提交
243 244 245
Create a folder called `static` in your project root directory. From your code you can then reference those files with `/static/` URLs:

```jsx
246 247 248 249 250
function MyImage() {
  return <img src="/static/my-image.png" alt="my image" />
}

export default MyImage
G
Guillermo Rauch 已提交
251
```
252

253 254
_Note: Don't name the `static` directory anything else. The name is required and is the only directory that Next.js uses for serving static assets._

G
Guillermo Rauch 已提交
255
### Populating `<head>`
G
Guillermo Rauch 已提交
256

S
Shu Ding 已提交
257
<details>
258
  <summary><b>Examples</b></summary>
259
  <ul>
260 261
    <li><a href="/examples/head-elements">Head elements</a></li>
    <li><a href="/examples/layout-component">Layout component</a></li>
262
  </ul>
S
Shu Ding 已提交
263 264 265
</details>

<p></p>
266

G
Guillermo Rauch 已提交
267 268
We expose a built-in component for appending elements to the `<head>` of the page.

G
Guillermo Rauch 已提交
269
```jsx
G
Guillermo Rauch 已提交
270
import Head from 'next/head'
271

272 273 274 275 276 277 278 279 280 281 282 283 284
function IndexPage() {
  return (
    <div>
      <Head>
        <title>My page title</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
      </Head>
      <p>Hello world!</p>
    </div>
  )
}

export default IndexPage
G
Guillermo Rauch 已提交
285 286
```

287 288 289 290
To avoid duplicate tags in your `<head>` you can use the `key` property, which will make sure the tag is only rendered once:

```jsx
import Head from 'next/head'
291

292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
function IndexPage() {
  return (
    <div>
      <Head>
        <title>My page title</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" key="viewport" />
      </Head>
      <Head>
        <meta name="viewport" content="initial-scale=1.2, width=device-width" key="viewport" />
      </Head>
      <p>Hello world!</p>
    </div>
  )
}

export default IndexPage
308 309 310
```

In this case only the second `<meta name="viewport" />` is rendered.
311

G
Guillermo Rauch 已提交
312 313
_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_

314 315
_Note: `<title>` and `<meta>` elements need to be contained as **direct** children of the `<Head>` element, or wrapped into maximum one level of `<React.Fragment>`, otherwise the metatags won't be correctly picked up on clientside navigation._

G
Guillermo Rauch 已提交
316
### Fetching data and component lifecycle
G
Guillermo Rauch 已提交
317

S
Shu Ding 已提交
318
<details>
D
Dan Zajdband 已提交
319
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
320
  <ul>
321
    <li><a href="/examples/data-fetch">Data fetch</a></li>
S
Shu Ding 已提交
322 323 324 325
  </ul>
</details>

<p></p>
D
Dan Zajdband 已提交
326

G
Guillermo Rauch 已提交
327
When you need state, lifecycle hooks or **initial data population** you can export a `React.Component` (instead of a stateless function, like shown above):
G
Guillermo Rauch 已提交
328

G
Guillermo Rauch 已提交
329
```jsx
G
Guillermo Rauch 已提交
330
import React from 'react'
331

332
class HelloUA extends React.Component {
333 334 335
  static async getInitialProps({ req }) {
    const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
    return { userAgent }
G
Guillermo Rauch 已提交
336
  }
337 338 339 340 341 342 343

  render() {
    return (
      <div>
        Hello World {this.props.userAgent}
      </div>
    )
G
Guillermo Rauch 已提交
344 345
  }
}
346 347

export default HelloUA
G
Guillermo Rauch 已提交
348 349
```

G
Guillermo Rauch 已提交
350 351
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`.

352 353
Data returned from `getInitialProps` is serialized when server rendering, similar to a `JSON.stringify`. Make sure the returned object from `getInitialProps` is a plain `Object` and not using `Date`, `Map` or `Set`.

G
Guillermo Rauch 已提交
354
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.
355

356 357
_Note: `getInitialProps` can **not** be used in children components. Only in `pages`._

358
<br/>
A
Arunoda Susiripala 已提交
359

360 361
> If you are using some server only modules inside `getInitialProps`, make sure to [import them properly](https://arunoda.me/blog/ssr-and-server-only-modules).
> Otherwise, it'll slow down your app.
A
Arunoda Susiripala 已提交
362

363 364
<br/>

365 366 367
You can also define the `getInitialProps` lifecycle method for stateless components:

```jsx
368 369 370
function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}
371 372 373 374 375 376 377 378 379 380

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

G
Guillermo Rauch 已提交
381
`getInitialProps` receives a context object with the following properties:
382 383 384

- `pathname` - path section of URL
- `query` - query string section of URL parsed as an object
A
Arunoda Susiripala 已提交
385
- `asPath` - `String` of the actual path (including the query) shows in the browser
386 387
- `req` - HTTP request object (server only)
- `res` - HTTP response object (server only)
388
- `jsonPageRes` - [Fetch Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) object (client only)
389 390
- `err` - Error object if any error is encountered during the rendering

G
Guillermo Rauch 已提交
391 392
### Routing

393 394
Next.js does not ship a routes manifest with every possible route in the application, so the current page is not aware of any other pages on the client side. All subsequent routes get lazy-loaded, for scalability sake.

395 396
#### With `<Link>`

S
Shu Ding 已提交
397
<details>
G
Guillermo Rauch 已提交
398
  <summary><b>Examples</b></summary>
399
  <ul>
400
    <li><a href="/examples/hello-world">Hello World</a></li>
401
  </ul>
S
Shu Ding 已提交
402 403 404
</details>

<p></p>
G
Guillermo Rauch 已提交
405

406 407 408 409 410
Client-side transitions between routes can be enabled via a `<Link>` component.

**Basic Example**

Consider these two pages:
G
Guillermo Rauch 已提交
411

G
Guillermo Rauch 已提交
412
```jsx
G
Guillermo Rauch 已提交
413
// pages/index.js
G
Guillermo Rauch 已提交
414
import Link from 'next/link'
415

416 417 418 419 420 421 422 423 424 425 426 427 428
function Home() {
  return (
    <div>
      Click{' '}
      <Link href="/about">
        <a>here</a>
      </Link>{' '}
      to read more
    </div>
  )
}

export default Home
G
Guillermo Rauch 已提交
429 430
```

G
Guillermo Rauch 已提交
431
```jsx
G
Guillermo Rauch 已提交
432
// pages/about.js
433 434 435 436 437
function About() {
  return <p>Welcome to About!</p>
}

export default About
G
Guillermo Rauch 已提交
438 439
```

440 441 442 443 444
**Custom routes (using props from URL)**

 `<Link>` component has two main props:

* `href`: the path inside `pages` directory + query string.
K
Kris Luminar 已提交
445
* `as`: the path that will be rendered in the browser URL bar.
446 447 448 449 450 451 452 453

Example:

1. Consider you have the URL `/post/:slug`.

2. You created the `pages/post.js`

    ```jsx
454
    class Post extends React.Component {
455 456 457 458 459 460 461 462
      static async getInitialProps({query}) {
        console.log('SLUG', query.slug)
        return {}
      }
      render() {
        return <h1>My blog post</h1>
      }
    }
463 464

    export default Post
465 466 467 468 469 470 471 472 473 474 475 476 477
    ```
3. You add the route to `express` (or any other server) on `server.js` file (this is only for SSR). This will route the url `/post/:slug` to `pages/post.js` and provide `slug` as part of query in getInitialProps.

    ```jsx
    server.get("/post/:slug", (req, res) => {
      return app.render(req, res, "/post", { slug: req.params.slug })
    })
    ```
4. For client side routing, use `next/link`:
    ```jsx
    <Link href="/post?slug=something" as="/post/something">
    ```

478
__Note: use [`<Link prefetch>`](#prefetching-pages) for maximum performance, to link and prefetch in the background at the same time__
G
Guillermo Rauch 已提交
479

G
Guillermo Rauch 已提交
480
Client-side routing behaves exactly like the browser:
G
Guillermo Rauch 已提交
481 482 483

1. The component is fetched
2. If it defines `getInitialProps`, data is fetched. If an error occurs, `_error.js` is rendered
484
3. After 1 and 2 complete, `pushState` is performed and the new component is rendered
G
Guillermo Rauch 已提交
485

486
To inject the `pathname`, `query` or `asPath` in your component, you can use [withRouter](#using-a-higher-order-component).
487

488 489
##### With URL object

S
Shu Ding 已提交
490
<details>
491 492
  <summary><b>Examples</b></summary>
  <ul>
493
    <li><a href="/examples/with-url-object-routing">With URL Object Routing</a></li>
494
  </ul>
S
Shu Ding 已提交
495 496 497
</details>

<p></p>
498 499 500 501 502 503

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'
504

505 506 507 508 509 510 511 512 513 514 515 516 517
function Home() {
  return (
    <div>
      Click{' '}
      <Link href={{ pathname: '/about', query: { name: 'Zeit' } }}>
        <a>here</a>
      </Link>{' '}
      to read more
    </div>
  )
}

export default Home
518 519 520 521
```

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

522 523
##### Replace instead of push url

D
Dan Zajdband 已提交
524 525 526 527 528
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'
529

530 531 532 533 534 535 536 537 538 539 540 541 542
function Home() {
  return (
    <div>
      Click{' '}
      <Link href="/about" replace>
        <a>here</a>
      </Link>{' '}
      to read more
    </div>
  )
}

export default Home
D
Dan Zajdband 已提交
543 544
```

545
##### Using a component that supports `onClick`
546 547 548 549 550 551

`<Link>` supports any component that supports the `onClick` event. In case you don't provide an `<a>` tag, it will only add the `onClick` event handler and won't pass the `href` property.

```jsx
// pages/index.js
import Link from 'next/link'
552

553 554 555 556 557 558 559 560 561 562 563 564
function Home() {
  return (
    <div>
      Click{' '}
      <Link href="/about">
        <img src="/static/image.png" alt="image" />
      </Link>
    </div>
  )
}

export default Home
565 566
```

567
##### Forcing the Link to expose `href` to its child
568

B
Ben Murden 已提交
569
If child is an `<a>` tag and doesn't have a href attribute we specify it so that the repetition is not needed by the user. However, sometimes, you’ll want to pass an `<a>` tag inside of a wrapper and the `Link` won’t recognize it as a *hyperlink*, and, consequently, won’t transfer its `href` to the child. In cases like that, you should define a boolean `passHref` property to the `Link`, forcing it to expose its `href` property to the child.
570

571 572
**Please note**: using a tag other than `a` and failing to pass `passHref` may result in links that appear to navigate correctly, but, when being crawled by search engines, will not be recognized as links (owing to the lack of `href` attribute). This may result in negative effects on your sites SEO.

573 574 575
```jsx
import Link from 'next/link'
import Unexpected_A from 'third-library'
576

577 578 579 580 581 582 583 584 585 586 587
function NavLink({ href, name }) {
  return (
    <Link href={href} passHref>
      <Unexpected_A>
        {name}
      </Unexpected_A>
    </Link>
  )
}

export default NavLink
588 589
```

J
Jimmy Moon 已提交
590 591 592 593 594 595 596 597 598
##### Disabling the scroll changes to top on page

The default behaviour of `<Link>` is to scroll to the top of the page. When there is a hash defined it will scroll to the specific id, just like a normal `<a>` tag. To prevent scrolling to the top / hash `scroll={false}` can be added to `<Link>`:

```jsx
<Link scroll={false} href="/?counter=10"><a>Disables scrolling</a></Link>
<Link href="/?counter=10"><a>Changes with scrolling to top</a></Link>
```

599
#### Imperatively
600

S
Shu Ding 已提交
601
<details>
602 603
  <summary><b>Examples</b></summary>
  <ul>
604 605
    <li><a href="/examples/using-router">Basic routing</a></li>
    <li><a href="/examples/with-loading">With a page loading indicator</a></li>
606
  </ul>
S
Shu Ding 已提交
607 608 609
</details>

<p></p>
610

G
Guillermo Rauch 已提交
611
You can also do client-side page transitions using the `next/router`
612 613 614 615

```jsx
import Router from 'next/router'

616 617 618 619 620 621 622 623 624
function ReadMore() {
  return (
    <div>
      Click <span onClick={() => Router.push('/about')}>here</span> to read more
    </div>
  )
}

export default ReadMore
625 626
```

627 628 629
#### Intercepting `popstate`

In some cases (for example, if using a [custom router](#custom-server-and-routing)), you may wish
630
to listen to [`popstate`](https://developer.mozilla.org/en-US/docs/Web/Events/popstate) and react before the router acts on it.
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647
For example, you could use this to manipulate the request, or force an SSR refresh.

```jsx
import Router from 'next/router'

Router.beforePopState(({ url, as, options }) => {
  // I only want to allow these two routes!
  if (as !== "/" || as !== "/other") {
    // Have SSR render bad routes as a 404.
    window.location.href = as
    return false
  }

  return true
});
```

648
If the function you pass into `beforePopState` returns `false`, `Router` will not handle `popstate`;
649 650 651
you'll be responsible for handling it, in that case.
See [Disabling File-System Routing](#disabling-file-system-routing).

652 653 654 655 656
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 `{}`
A
Arunoda Susiripala 已提交
657
- `asPath` - `String` of the actual path (including the query) shows in the browser
658 659
- `push(url, as=url)` - performs a `pushState` call with the given url
- `replace(url, as=url)` - performs a `replaceState` call with the given url
660
- `beforePopState(cb=function)` - intercept popstate before router processes the event.
661

G
Guillermo Rauch 已提交
662
The second `as` parameter for `push` and `replace` is an optional _decoration_ of the URL. Useful if you configured custom routes on the server.
663

664
##### With URL object
665
You can use an URL object the same way you use it in a `<Link>` component to `push` and `replace` an URL.
666 667 668 669

```jsx
import Router from 'next/router'

670
const handler = () => {
671 672 673 674
  Router.push({
    pathname: '/about',
    query: { name: 'Zeit' }
  })
675
}
676

677 678 679 680 681 682 683 684 685
function ReadMore() {
    return (
    <div>
      Click <span onClick={handler}>here</span> to read more
    </div>
  )
}

export default ReadMore
686 687
```

688
This uses the same exact parameters as in the `<Link>` component.
689

690 691 692 693 694
##### Router Events

You can also listen to different events happening inside the Router.
Here's a list of supported events:

695 696 697 698 699 700
- `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
- `beforeHistoryChange(url)` - Fires just before changing the browser's history
- `hashChangeStart(url)` - Fires when the hash will change but not the page
- `hashChangeComplete(url)` - Fires when the hash has changed but not the page
701 702 703

> 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`.

704
Here's how to properly listen to the router event `routeChangeStart`:
705 706

```js
707
const handleRouteChange = url => {
708 709
  console.log('App is changing to: ', url)
}
710 711

Router.events.on('routeChangeStart', handleRouteChange)
712 713
```

714
If you no longer want to listen to that event, you can unsubscribe with the `off` method:
715 716

```js
717
Router.events.off('routeChangeStart', handleRouteChange)
718 719
```

720
If a route load is cancelled (for example by clicking two links rapidly in succession), `routeChangeError` will fire. The passed `err` will contain a `cancelled` property set to `true`.
721 722

```js
723
Router.events.on('routeChangeError', (err, url) => {
724
  if (err.cancelled) {
G
Guillermo Rauch 已提交
725
    console.log(`Route to ${url} was cancelled!`)
726
  }
727
})
728 729
```

730 731
##### Shallow Routing

S
Shu Ding 已提交
732
<details>
733 734
  <summary><b>Examples</b></summary>
  <ul>
735
    <li><a href="/examples/with-shallow-routing">Shallow Routing</a></li>
736
  </ul>
S
Shu Ding 已提交
737 738 739
</details>

<p></p>
740

741
Shallow routing allows you to change the URL without running `getInitialProps`. You'll receive the updated `pathname` and the `query` via the `router` prop (injected using [`withRouter`](#using-a-higher-order-component)), without losing state.
742

743
You can do this by invoking either `Router.push` or `Router.replace` with the `shallow: true` option. Here's an example:
744

745
```js
746 747 748 749 750 751
// Current URL is "/"
const href = '/?counter=10'
const as = href
Router.push(href, as, { shallow: true })
```

752
Now, the URL is updated to `/?counter=10`. You can see the updated URL with `this.props.router.query` inside the `Component` (make sure you are using [`withRouter`](#using-a-higher-order-component) around your `Component` to inject the `router` prop).
753

754
You can watch for URL changes via [`componentDidUpdate`](https://reactjs.org/docs/react-component.html#componentdidupdate) hook as shown below:
755

756
```js
757 758 759 760 761 762
componentDidUpdate(prevProps) {
  const { pathname, query } = this.props.router
  // verify props have changed to avoid an infinite loop
  if (query.id !== prevProps.router.query.id) {
    // fetch data based on the new query
  }
763 764 765 766
}
```

> NOTES:
767
>
F
Fabio Espinosa 已提交
768
> Shallow routing works **only** for same page URL changes. For an example, let's assume we have another page called `about`, and you run this:
769
> ```js
J
Jeffrey Young 已提交
770
> Router.push('/?counter=10', '/about?counter=10', { shallow: true })
771
> ```
B
Ben Hadfield 已提交
772
> 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.
773

A
Arunoda Susiripala 已提交
774 775
#### Using a Higher Order Component

S
Shu Ding 已提交
776
<details>
A
Arunoda Susiripala 已提交
777 778
  <summary><b>Examples</b></summary>
  <ul>
779
    <li><a href="/examples/using-with-router">Using the `withRouter` utility</a></li>
A
Arunoda Susiripala 已提交
780
  </ul>
S
Shu Ding 已提交
781 782 783
</details>

<p></p>
A
Arunoda Susiripala 已提交
784 785 786 787 788 789

If you want to access the `router` object inside any component in your app, you can use the `withRouter` Higher-Order Component. Here's how to use it:

```jsx
import { withRouter } from 'next/router'

790
function ActiveLink({ children, router, href }) {
A
Arunoda Susiripala 已提交
791 792
  const style = {
    marginRight: 10,
H
Homer Chen 已提交
793
    color: router.pathname === href ? 'red' : 'black'
A
Arunoda Susiripala 已提交
794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
  }

  const handleClick = (e) => {
    e.preventDefault()
    router.push(href)
  }

  return (
    <a href={href} onClick={handleClick} style={style}>
      {children}
    </a>
  )
}

export default withRouter(ActiveLink)
```

The above `router` object comes with an API similar to [`next/router`](#imperatively).

813 814
### Prefetching Pages

815
⚠️ This is a production only feature ⚠️
816

S
Shu Ding 已提交
817
<details>
818
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
819
  <ul>
820
    <li><a href="/examples/with-prefetching">Prefetching</a></li>
S
Shu Ding 已提交
821 822 823 824
  </ul>
</details>

<p></p>
825

826
Next.js has an API which allows you to prefetch pages.
827

828
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).
829

830
> With prefetching Next.js only downloads JS code. When the page is getting rendered, you may need to wait for the data.
831

G
Guillermo Rauch 已提交
832
#### With `<Link>`
833

834
You can add `prefetch` prop to any `<Link>` and Next.js will prefetch those pages in the background.
835 836

```jsx
837 838
import Link from 'next/link'

839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863
function Header() { 
  return (
    <nav>
      <ul>
        <li>
          <Link prefetch href="/">
            <a>Home</a>
          </Link>
        </li>
        <li>
          <Link prefetch href="/about">
            <a>About</a>
          </Link>
        </li>
        <li>
          <Link prefetch href="/contact">
            <a>Contact</a>
          </Link>
        </li>
      </ul>
    </nav>
  )
}

export default Header
864 865
```

G
Guillermo Rauch 已提交
866
#### Imperatively
867

868
Most prefetching needs are addressed by `<Link />`, but we also expose an imperative API for advanced usage:
869 870

```jsx
871
import { withRouter } from 'next/router'
872

873 874 875 876 877 878 879 880 881 882 883 884 885
function MyLink({ router }) { 
  return (
    <div>
      <a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}>
        A route transition will happen after 100ms
      </a>
      {// but we can prefetch it!
      router.prefetch('/dynamic')}
    </div>
  )
}

export default withRouter(MyLink)
G
Guillermo Rauch 已提交
886
```
887

888 889 890 891
The router instance should be only used inside the client side of your app though. In order to prevent any error regarding this subject, when rendering the Router on the server side, use the imperatively prefetch method in the `componentDidMount()` lifecycle method.

```jsx
import React from 'react'
892
import { withRouter } from 'next/router'
893

894
class MyLink extends React.Component {
895
  componentDidMount() {
896 897
    const { router } = this.props
    router.prefetch('/dynamic')
898
  }
899

900
  render() {
901
    const { router } = this.props
902

903 904
    return (
       <div>
905
        <a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}>
906 907
          A route transition will happen after 100ms
        </a>
908
      </div>
909 910 911
    )
  }
}
912 913

export default withRouter(MyLink)
914 915
```

G
Guillermo Rauch 已提交
916 917
### Custom server and routing

S
Shu Ding 已提交
918
<details>
919
  <summary><b>Examples</b></summary>
D
Dan Zajdband 已提交
920
  <ul>
921 922 923 924 925 926
    <li><a href="/examples/custom-server">Basic custom server</a></li>
    <li><a href="/examples/custom-server-express">Express integration</a></li>
    <li><a href="/examples/custom-server-hapi">Hapi integration</a></li>
    <li><a href="/examples/custom-server-koa">Koa integration</a></li>
    <li><a href="/examples/parameterized-routing">Parameterized routing</a></li>
    <li><a href="/examples/ssr-caching">SSR caching</a></li>
D
Dan Zajdband 已提交
927
  </ul>
S
Shu Ding 已提交
928 929 930
</details>

<p></p>
931

932 933 934 935 936 937 938 939 940 941 942 943 944
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.

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"
  }
}
```
G
Guillermo Rauch 已提交
945 946 947

This example makes `/a` resolve to `./pages/b`, and `/b` resolve to `./pages/a`:

G
Guillermo Rauch 已提交
948
```js
949
// This file doesn't go through babel or webpack transformation.
950 951
// Make sure the syntax and sources this file requires are compatible with the current node version you are running
// See https://github.com/zeit/next.js/issues/1245 for discussions on Universal Webpack or universal Babel
G
Guillermo Rauch 已提交
952 953 954 955
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

956 957
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
G
Guillermo Rauch 已提交
958 959 960 961
const handle = app.getRequestHandler()

app.prepare().then(() => {
  createServer((req, res) => {
962 963
    // Be sure to pass `true` as the second argument to `url.parse`.
    // This tells it to parse the query portion of the URL.
964 965
    const parsedUrl = parse(req.url, true)
    const { pathname, query } = parsedUrl
G
Guillermo Rauch 已提交
966 967 968 969 970 971

    if (pathname === '/a') {
      app.render(req, res, '/b', query)
    } else if (pathname === '/b') {
      app.render(req, res, '/a', query)
    } else {
972
      handle(req, res, parsedUrl)
G
Guillermo Rauch 已提交
973
    }
974
  }).listen(3000, err => {
G
Guillermo Rauch 已提交
975 976 977 978 979 980
    if (err) throw err
    console.log('> Ready on http://localhost:3000')
  })
})
```

G
Guillermo Rauch 已提交
981 982 983 984
The `next` API is as follows:
- `next(opts: object)`

Supported options:
985 986
- `dev` (`bool`) whether to launch Next.js in dev mode - default `false`
- `dir` (`string`) where the Next project is located - default `'.'`
987
- `quiet` (`bool`) Hide error messages containing server information - default `false`
988
- `conf` (`object`) the same object you would use in `next.config.js` - default `{}`
G
Guillermo Rauch 已提交
989

990 991
Then, change your `start` script to `NODE_ENV=production node server.js`.

992
#### Disabling file-system routing
K
Kanjie Lu 已提交
993
By default, `Next` will serve each file in `/pages` under a pathname matching the filename (eg, `/pages/some-file.js` is served at `site.com/some-file`.
994

995
If your project uses custom routing, this behavior may result in the same content being served from multiple paths, which can present problems with SEO and UX.
996

997
To disable this behavior & prevent routing based on files in `/pages`, simply set the following option in your `next.config.js`:
998 999 1000 1001 1002 1003 1004 1005

```js
// next.config.js
module.exports = {
  useFileSystemPublicRoutes: false
}
```

1006 1007 1008 1009 1010 1011 1012
Note that `useFileSystemPublicRoutes` simply disables filename routes from SSR; client-side routing
may still access those paths. If using this option, you should guard against navigation to routes
you do not want programmatically.

You may also wish to configure the client-side Router to disallow client-side redirects to filename
routes; please refer to [Intercepting `popstate`](#intercepting-popstate).

1013 1014 1015 1016 1017 1018 1019 1020 1021
#### Dynamic assetPrefix

Sometimes we need to set the `assetPrefix` dynamically. This is useful when changing the `assetPrefix` based on incoming requests.
For that, we can use `app.setAssetPrefix`.

Here's an example usage of it:

```js
const next = require('next')
1022
const http = require('http')
1023 1024 1025

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
S
S. Suzuki 已提交
1026
const handleNextRequests = app.getRequestHandler()
1027 1028

app.prepare().then(() => {
1029
  const server = new http.Server((req, res) => {
1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
    // Add assetPrefix support based on the hostname
    if (req.headers.host === 'my-app.com') {
      app.setAssetPrefix('http://cdn.com/myapp')
    } else {
      app.setAssetPrefix('')
    }

    handleNextRequests(req, res)
  })

  server.listen(port, (err) => {
    if (err) {
      throw err
    }

    console.log(`> Ready on http://localhost:${port}`)
  })
})

```
1050

A
Arunoda Susiripala 已提交
1051 1052
### Dynamic Import

S
Shu Ding 已提交
1053
<details>
A
Arunoda Susiripala 已提交
1054 1055
  <summary><b>Examples</b></summary>
  <ul>
1056
    <li><a href="/examples/with-dynamic-import">With Dynamic Import</a></li>
A
Arunoda Susiripala 已提交
1057
  </ul>
S
Shu Ding 已提交
1058 1059 1060
</details>

<p></p>
A
Arunoda Susiripala 已提交
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071

Next.js supports TC39 [dynamic import proposal](https://github.com/tc39/proposal-dynamic-import) for JavaScript.
With that, you could import JavaScript modules (inc. React Components) dynamically and work with them.

You can think dynamic imports as another way to split your code into manageable chunks.
Since Next.js supports dynamic imports with SSR, you could do amazing things with it.

Here are a few ways to use dynamic imports.

#### 1. Basic Usage (Also does SSR)

1072
```jsx
A
Arunoda Susiripala 已提交
1073
import dynamic from 'next/dynamic'
1074

1075
const DynamicComponent = dynamic(() => import('../components/hello'))
A
Arunoda Susiripala 已提交
1076

1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
function Home() {
  return (
    <div>
      <Header />
      <DynamicComponent />
      <p>HOME PAGE is here!</p>
    </div>
  )
} 

export default Home
A
Arunoda Susiripala 已提交
1088 1089 1090 1091
```

#### 2. With Custom Loading Component

1092
```jsx
A
Arunoda Susiripala 已提交
1093
import dynamic from 'next/dynamic'
1094

1095
const DynamicComponentWithCustomLoading = dynamic(() => import('../components/hello2'), {
1096 1097
  loading: () => <p>...</p>
})
A
Arunoda Susiripala 已提交
1098

1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109
function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithCustomLoading />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
A
Arunoda Susiripala 已提交
1110 1111 1112 1113
```

#### 3. With No SSR

1114
```jsx
A
Arunoda Susiripala 已提交
1115 1116
import dynamic from 'next/dynamic'

1117
const DynamicComponentWithNoSSR = dynamic(() => import('../components/hello3'), {
1118 1119 1120
  ssr: false
})

1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
A
Arunoda Susiripala 已提交
1132 1133
```

1134
#### 4. With Multiple Modules At Once
A
Arunoda Susiripala 已提交
1135

1136
```jsx
1137 1138 1139
import dynamic from 'next/dynamic'

const HelloBundle = dynamic({
1140
  modules: () => {
1141
    const components = {
1142 1143
      Hello1: () => import('../components/hello1'),
      Hello2: () => import('../components/hello2')
1144 1145 1146 1147
    }

    return components
  },
1148
  render: (props, { Hello1, Hello2 }) =>
1149
    <div>
1150 1151 1152
      <h1>
        {props.title}
      </h1>
1153 1154 1155
      <Hello1 />
      <Hello2 />
    </div>
A
Arunoda Susiripala 已提交
1156 1157
})

1158 1159 1160 1161 1162
function DynamicBundle() {
  return <HelloBundle title="Dynamic Bundle" />
}

export default DynamicBundle
A
Arunoda Susiripala 已提交
1163 1164
```

T
Tim Neutkens 已提交
1165 1166
### Custom `<App>`

S
Shu Ding 已提交
1167
<details>
T
Tim Neutkens 已提交
1168
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1169
  <ul>
1170 1171
    <li><a href="/examples/with-app-layout">Using `_app.js` for layout</a></li>
    <li><a href="/examples/with-componentdidcatch">Using `_app.js` to override `componentDidCatch`</a></li>
S
Shu Ding 已提交
1172 1173 1174 1175
  </ul>
</details>

<p></p>
T
Tim Neutkens 已提交
1176

C
Christian Nwamba 已提交
1177
Next.js uses the `App` component to initialize pages. You can override it and control the page initialization. Which allows you to do amazing things like:
T
Tim Neutkens 已提交
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187

- Persisting layout between page changes
- Keeping state when navigating pages
- Custom error handling using `componentDidCatch`
- Inject additional data into pages (for example by processing GraphQL queries)

To override, create the `./pages/_app.js` file and override the App class as shown below:

```js
import React from 'react'
1188
import App, { Container } from 'next/app'
T
Tim Neutkens 已提交
1189

1190
class MyApp extends App {
1191
  static async getInitialProps({ Component, ctx }) {
T
Tim Neutkens 已提交
1192 1193 1194 1195 1196 1197
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx)
    }

1198
    return { pageProps }
T
Tim Neutkens 已提交
1199 1200 1201
  }

  render () {
1202 1203 1204 1205 1206 1207 1208
    const { Component, pageProps } = this.props

    return (
      <Container>
        <Component {...pageProps} />
      </Container>
    )
T
Tim Neutkens 已提交
1209 1210
  }
}
1211 1212

export default MyApp
T
Tim Neutkens 已提交
1213 1214
```

G
Guillermo Rauch 已提交
1215 1216
### Custom `<Document>`

S
Shu Ding 已提交
1217
<details>
1218
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1219
  <ul>
1220 1221
    <li><a href="/examples/with-styled-components">Styled components custom document</a></li>
    <li><a href="/examples/with-amp">Google AMP</a></li>
S
Shu Ding 已提交
1222 1223 1224 1225
  </ul>
</details>

<p></p>
1226

T
Tim Neutkens 已提交
1227 1228
- Is rendered on the server side
- Is used to change the initial server side rendered document markup
1229
- Commonly used to implement server side rendering for css-in-js libraries like [styled-components](/examples/with-styled-components) or [emotion](/examples/with-emotion). [styled-jsx](https://github.com/zeit/styled-jsx) is included with Next.js by default.
T
Tim Neutkens 已提交
1230

1231
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:
G
Guillermo Rauch 已提交
1232 1233

```jsx
1234 1235 1236
// _document is only rendered on the server side and not on the client side
// Event handlers like onClick can't be added to this file

1237
// ./pages/_document.js
张俊锋 已提交
1238
import Document, { Head, Main, NextScript } from 'next/document'
G
Guillermo Rauch 已提交
1239

1240
class MyDocument extends Document {
T
Tim Neutkens 已提交
1241 1242 1243
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
G
Guillermo Rauch 已提交
1244 1245
  }

1246
  render() {
G
Guillermo Rauch 已提交
1247
    return (
1248 1249 1250 1251 1252 1253 1254 1255 1256
      <html>
        <Head>
          <style>{`body { margin: 0 } /* custom! */`}</style>
        </Head>
        <body className="custom_class">
          <Main />
          <NextScript />
        </body>
      </html>
G
Guillermo Rauch 已提交
1257 1258 1259
    )
  }
}
1260 1261

export default MyDocument
G
Guillermo Rauch 已提交
1262 1263
```

1264 1265
All of `<Head />`, `<Main />` and `<NextScript />` are required for page to be properly rendered.

1266 1267
__Note: React-components outside of `<Main />` will not be initialised by the browser. Do _not_ add application logic here. If you need shared components in all your pages (like a menu or a toolbar), take a look at the `App` component instead.__

G
Guillermo Rauch 已提交
1268
The `ctx` object is equivalent to the one received in all [`getInitialProps`](#fetching-data-and-component-lifecycle) hooks, with one addition:
G
Guillermo Rauch 已提交
1269 1270 1271

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

1272 1273 1274 1275 1276 1277 1278 1279 1280
#### Customizing `renderPage`
🚧 It should be noted that the only reason you should be customizing `renderPage` is for usage with css-in-js libraries
that need to wrap the application to properly work with server-rendering. 🚧

- It takes as argument an options object for further customization

```js
import Document from 'next/document'

1281
class MyDocument extends Document {
1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
  static async getInitialProps(ctx) {
    const originalRenderPage = ctx.renderPage

    ctx.renderPage = () => originalRenderPage({
      // useful for wrapping the whole react tree
      enhanceApp: App => App,
      // userful for wrapping in a per-page basis
      enhanceComponent: Component => Component
    })

    // Run the parent `getInitialProps` using `ctx` that now includes our custom `renderPage`
    const initialProps = await Document.getInitialProps(ctx)

    return initialProps
  }
}
1298 1299

export default MyDocument
1300
```
1301

G
Guillermo Rauch 已提交
1302
### Custom error handling
1303

F
Fabio Espinosa 已提交
1304
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` in the pages folder:
1305

D
Dovydas Navickas 已提交
1306
⚠️ The `pages/_error.js` component is only used in production. In development you get an error with call stack to know where the error originated from. ⚠️
S
Sean Connolly 已提交
1307

1308 1309
```jsx
import React from 'react'
1310

1311
class Error extends React.Component {
1312 1313
  static getInitialProps({ res, err }) {
    const statusCode = res ? res.statusCode : err ? err.statusCode : null;
1314 1315 1316
    return { statusCode }
  }

1317
  render() {
1318
    return (
1319 1320 1321 1322 1323
      <p>
        {this.props.statusCode
          ? `An error ${this.props.statusCode} occurred on server`
          : 'An error occurred on client'}
      </p>
1324 1325 1326
    )
  }
}
1327 1328

export default Error
1329 1330
```

J
Jure Triglav 已提交
1331
### Reusing the built-in error page
T
Tim Neutkens 已提交
1332

J
Jure Triglav 已提交
1333
If you want to render the built-in error page you can by using `next/error`:
T
Tim Neutkens 已提交
1334 1335 1336 1337

```jsx
import React from 'react'
import Error from 'next/error'
1338
import fetch from 'isomorphic-unfetch'
T
Tim Neutkens 已提交
1339

1340
class Page extends React.Component {
1341
  static async getInitialProps() {
T
Tim Neutkens 已提交
1342
    const res = await fetch('https://api.github.com/repos/zeit/next.js')
1343
    const errorCode = res.statusCode > 200 ? res.statusCode : false
T
Tim Neutkens 已提交
1344
    const json = await res.json()
1345

1346
    return { errorCode, stars: json.stargazers_count }
T
Tim Neutkens 已提交
1347 1348
  }

1349
  render() {
1350 1351
    if (this.props.errorCode) {
      return <Error statusCode={this.props.errorCode} />
T
Tim Neutkens 已提交
1352 1353 1354
    }

    return (
1355 1356 1357
      <div>
        Next stars: {this.props.stars}
      </div>
T
Tim Neutkens 已提交
1358 1359 1360
    )
  }
}
1361 1362

export default Page
T
Tim Neutkens 已提交
1363 1364
```

1365
> If you have created a custom error page you have to import your own `_error` component from `./_error` instead of `next/error`
T
Tim Neutkens 已提交
1366

G
Guillermo Rauch 已提交
1367
### Custom configuration
G
Guillermo Rauch 已提交
1368

1369
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`).
G
Guillermo Rauch 已提交
1370 1371 1372

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.

1373
```js
G
Guillermo Rauch 已提交
1374 1375 1376 1377 1378 1379
// next.config.js
module.exports = {
  /* config options here */
}
```

1380 1381 1382
Or use a function:

```js
C
Carlo Palinckx 已提交
1383
module.exports = (phase, {defaultConfig}) => {
1384 1385 1386 1387 1388 1389
  return {
    /* config options here */
  }
}
```

1390
`phase` is the current context in which the configuration is loaded. You can see all phases here: [constants](/packages/next-server/lib/constants.js)
1391 1392 1393 1394
Phases can be imported from `next/constants`:

```js
const {PHASE_DEVELOPMENT_SERVER} = require('next/constants')
1395
module.exports = (phase, {defaultConfig}) => {
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407
  if(phase === PHASE_DEVELOPMENT_SERVER) {
    return {
      /* development only config options here */
    }
  }

  return {
    /* config options for all phases except development here */
  }
}
```

1408 1409 1410 1411
#### 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.

1412
```js
1413 1414 1415 1416 1417 1418
// next.config.js
module.exports = {
  distDir: 'build'
}
```

1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429
#### Disabling etag generation

You can disable etag generation for HTML pages depending on your cache strategy. If no configuration is specified then Next will generate etags for every page.

```js
// next.config.js
module.exports = {
  generateEtags: false
}
```

1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440
#### Configuring the onDemandEntries

Next exposes some options that give you some control over how the server will dispose or keep in memories pages built:

```js
module.exports = {
  onDemandEntries: {
    // period (in ms) where the server will keep pages in the buffer
    maxInactiveAge: 25 * 1000,
    // number of pages that should be kept simultaneously without being disposed
    pagesBufferLength: 2,
1441 1442
    // optionally configure a port for the onDemandEntries WebSocket, not needed by default
    websocketPort: 3001,
1443 1444 1445 1446
    // optionally configure a proxy path for the onDemandEntries WebSocket, not need by default
    websocketProxyPath: '/hmr',
    // optionally configure a proxy port for the onDemandEntries WebSocket, not need by default
    websocketProxyPort: 7002,
1447
  },
1448 1449 1450
}
```

1451 1452
This is development-only feature. If you want to cache SSR pages in production, please see [SSR-caching](https://github.com/zeit/next.js/tree/canary/examples/ssr-caching) example.

T
Tim Neutkens 已提交
1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463
#### Configuring extensions looked for when resolving pages in `pages`

Aimed at modules like [`@zeit/next-typescript`](https://github.com/zeit/next-plugins/tree/master/packages/next-typescript), that add support for pages ending in `.ts`. `pageExtensions` allows you to configure the extensions looked for in the `pages` directory when resolving pages.

```js
// next.config.js
module.exports = {
  pageExtensions: ['jsx', 'js']
}
```

1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
#### Configuring the build ID

Next.js uses a constant generated at build time to identify which version of your application is being served. This can cause problems in multi-server deployments when `next build` is ran on every server. In order to keep a static build id between builds you can provide the `generateBuildId` function:

```js
// next.config.js
module.exports = {
  generateBuildId: async () => {
    // For example get the latest git commit hash here
    return 'my-build-id'
  }
}
```

1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492
To fall back to the default of generating a unique id return `null` from the function:

```js
module.exports = {
  generateBuildId: async () => {
    // When process.env.YOUR_BUILD_ID is undefined we fall back to the default
    if(process.env.YOUR_BUILD_ID) {
      return process.env.YOUR_BUILD_ID
    }

    return null
  }
}
```

D
DevSide 已提交
1493 1494
#### Configuring next process script

1495
You can pass any node arguments to `next` CLI command.
D
DevSide 已提交
1496 1497

```bash
1498 1499 1500 1501 1502 1503 1504 1505
NODE_OPTIONS="--throw-deprecation" next
NODE_OPTIONS="-r esm" next
```

`--inspect` is a special case since it binds to a port and can't double-bind to the child process the `next` CLI creates.

```
next start --inspect
D
DevSide 已提交
1506 1507
```

G
Guillermo Rauch 已提交
1508 1509
### Customizing webpack config

S
Shu Ding 已提交
1510
<details>
1511
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1512
  <ul>
1513
    <li><a href="/examples/with-webpack-bundle-analyzer">Custom webpack bundle analyzer</a></li>
S
Shu Ding 已提交
1514 1515 1516 1517
  </ul>
</details>

<p></p>
1518

1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542
Some commonly asked for features are available as modules:

- [@zeit/next-css](https://github.com/zeit/next-plugins/tree/master/packages/next-css)
- [@zeit/next-sass](https://github.com/zeit/next-plugins/tree/master/packages/next-sass)
- [@zeit/next-less](https://github.com/zeit/next-plugins/tree/master/packages/next-less)
- [@zeit/next-preact](https://github.com/zeit/next-plugins/tree/master/packages/next-preact)
- [@zeit/next-typescript](https://github.com/zeit/next-plugins/tree/master/packages/next-typescript)

*Warning: The `webpack` function is executed twice, once for the server and once for the client. This allows you to distinguish between client and server configuration using the `isServer` property*

Multiple configurations can be combined together with function composition. For example:

```js
const withTypescript = require('@zeit/next-typescript')
const withSass = require('@zeit/next-sass')

module.exports = withTypescript(withSass({
  webpack(config, options) {
    // Further custom configuration here
    return config
  }
}))
```

G
Guillermo Rauch 已提交
1543
In order to extend our usage of `webpack`, you can define a function that extends its config via `next.config.js`.
G
Guillermo Rauch 已提交
1544 1545

```js
1546
// next.config.js is not transformed by Babel. So you can only use javascript features supported by your version of Node.js.
1547 1548

module.exports = {
T
Tim Neutkens 已提交
1549
  webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
1550 1551 1552 1553
    // Perform customizations to webpack config
    // Important: return the modified config
    return config
  },
1554
  webpackDevMiddleware: config => {
1555 1556
    // Perform customizations to webpack dev middleware config
    // Important: return the modified config
1557 1558 1559 1560 1561
    return config
  }
}
```

P
Pieter De Decker 已提交
1562
The second argument to `webpack` is an object containing properties useful when customizing its configuration:
T
Tim Neutkens 已提交
1563

1564 1565 1566 1567 1568 1569
- `buildId` - `String` the build id used as a unique identifier between builds
- `dev` - `Boolean` shows if the compilation is done in development mode
- `isServer` - `Boolean` shows if the resulting configuration will be used for server side (`true`), or client size compilation (`false`).
- `defaultLoaders` - `Object` Holds loader objects Next.js uses internally, so that you can use them in custom configuration
  - `babel` - `Object` the `babel-loader` configuration for Next.js.
  - `hotSelfAccept` - `Object` the `hot-self-accept-loader` configuration. This loader should only be used for advanced use cases. For example [`@zeit/next-typescript`](https://github.com/zeit/next-plugins/tree/master/packages/next-typescript) adds it for top-level typescript pages.
1570

1571
Example usage of `defaultLoaders.babel`:
1572 1573

```js
1574
// Example next.config.js for adding a loader that depends on babel-loader
1575
// This source was taken from the @zeit/next-mdx plugin source:
1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588
// https://github.com/zeit/next-plugins/blob/master/packages/next-mdx
module.exports = {
  webpack: (config, {}) => {
    config.module.rules.push({
      test: /\.mdx/,
      use: [
        options.defaultLoaders.babel,
        {
          loader: '@mdx-js/loader',
          options: pluginOptions.options
        }
      ]
    })
1589 1590 1591

    return config
  }
1592
}
1593 1594
```

1595 1596
### Customizing babel config

S
Shu Ding 已提交
1597
<details>
1598
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1599
  <ul>
1600
    <li><a href="/examples/with-custom-babel-config">Custom babel configuration</a></li>
S
Shu Ding 已提交
1601 1602 1603 1604
  </ul>
</details>

<p></p>
1605

1606 1607 1608 1609 1610 1611 1612
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:
1613

1614
```json
1615
{
1616 1617
  "presets": ["next/babel"],
  "plugins": []
G
Guillermo Rauch 已提交
1618 1619 1620
}
```

1621 1622 1623 1624 1625 1626 1627 1628 1629
The `next/babel` preset includes everything needed to transpile React applications. This includes:

- preset-env
- preset-react
- plugin-proposal-class-properties
- plugin-proposal-object-rest-spread
- plugin-transform-runtime
- styled-jsx

1630
These presets / plugins **should not** be added to your custom `.babelrc`. Instead, you can configure them on the `next/babel` preset:
1631 1632 1633 1634 1635 1636 1637

```json
{
  "presets": [
    ["next/babel", {
      "preset-env": {},
      "transform-runtime": {},
1638 1639
      "styled-jsx": {},
      "class-properties": {}
1640 1641 1642 1643 1644 1645 1646 1647
    }]
  ],
  "plugins": []
}
```

The `modules` option on `"preset-env"` should be kept to `false` otherwise webpack code splitting is disabled.

1648
### Exposing configuration to the server / client side
1649

1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675
There is a common need in applications to provide configuration values.

Next.js supports 2 ways of providing configuration:

- Build-time configuration
- Runtime configuration

#### Build time configuration

The way build-time configuration works is by inlining the provided values into the Javascript bundle.

You can add the `env` key in `next.config.js`:

```js
// next.config.js
module.exports = {
  env: {
    customKey: 'value'
  }
}
```

This will allow you to use `process.env.customKey` in your code. For example:

```jsx
// pages/index.js
1676
function Index() {
1677 1678
  return <h1>The value of customEnv is: {process.env.customEnv}</h1>
}
1679 1680

export default Index
1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
```

#### Runtime configuration

> :warning: Note that this option is not available when using `target: 'serverless'`

> :warning: Generally you want to use build-time configuration to provide your configuration. 
The reason for this is that runtime configuration adds a small rendering / initialization overhead.

The `next/config` module gives your app access to the `publicRuntimeConfig` and `serverRuntimeConfig` stored in your `next.config.js`. 

Place any server-only runtime config under a `serverRuntimeConfig` property.

Anything accessible to both client and server-side code should be under `publicRuntimeConfig`.
1695 1696 1697 1698

```js
// next.config.js
module.exports = {
1699
  serverRuntimeConfig: { // Will only be available on the server side
1700 1701
    mySecret: 'secret',
    secondSecret: process.env.SECOND_SECRET // Pass through env variables
1702 1703
  },
  publicRuntimeConfig: { // Will be available on both server and client
1704
    staticFolder: '/static',
1705 1706 1707 1708 1709 1710 1711
  }
}
```

```js
// pages/index.js
import getConfig from 'next/config'
1712 1713
// Only holds serverRuntimeConfig and publicRuntimeConfig from next.config.js nothing else.
const {serverRuntimeConfig, publicRuntimeConfig} = getConfig()
1714 1715 1716

console.log(serverRuntimeConfig.mySecret) // Will only be available on the server side
console.log(publicRuntimeConfig.staticFolder) // Will be available on both server and client
1717

1718 1719 1720 1721 1722 1723 1724 1725 1726
function MyImage() {
  return (
    <div>
      <img src={`${publicRuntimeConfig.staticFolder}/logo.png`} alt="logo" />
    </div>
  )
}

export default MyImage
1727 1728
```

1729 1730 1731 1732
### Starting the server on alternative hostname

To start the development server using a different default hostname you can use `--hostname hostname_here` or `-H hostname_here` option with next dev. This will start a TCP server listening for connections on the provided host.

1733 1734 1735 1736 1737
### 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
C
Craig Mulligan 已提交
1738
const isProd = process.env.NODE_ENV === 'production'
1739 1740 1741 1742 1743 1744
module.exports = {
  // You may only need to add assetPrefix in the production.
  assetPrefix: isProd ? 'https://cdn.mydomain.com' : ''
}
```

1745
Note: Next.js will automatically use that prefix in 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).
1746

1747 1748
If your CDN is on a separate domain and you would like assets to be requested using a [CORS aware request](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) you can set a config option for that.

1749
```js
1750 1751 1752 1753
// next.config.js
module.exports = {
  crossOrigin: 'anonymous'
}
1754
```
G
Guillermo Rauch 已提交
1755
## Production deployment
G
Guillermo Rauch 已提交
1756

1757
To deploy, instead of running `next`, you want to build for production usage ahead of time. Therefore, building and starting are separate commands:
G
Guillermo Rauch 已提交
1758

G
Guillermo Rauch 已提交
1759
```bash
G
Guillermo Rauch 已提交
1760 1761 1762 1763
next build
next start
```

G
Guillermo Rauch 已提交
1764
For example, to deploy with [`now`](https://zeit.co/now) a `package.json` like follows is recommended:
G
Guillermo Rauch 已提交
1765

G
Guillermo Rauch 已提交
1766
```json
G
Guillermo Rauch 已提交
1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778
{
  "name": "my-app",
  "dependencies": {
    "next": "latest"
  },
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}
```
G
Guillermo Rauch 已提交
1779

G
Guillermo Rauch 已提交
1780 1781
Then run `now` and enjoy!

A
Arunoda Susiripala 已提交
1782
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.
1783

1784 1785
Note: `NODE_ENV` is properly configured by the `next` subcommands, if absent, to maximize performance. if you’re using Next.js [programmatically](#custom-server-and-routing), it’s your responsibility to set `NODE_ENV=production` manually!

1786
Note: we recommend putting `.next`, or your [custom dist folder](https://github.com/zeit/next.js#custom-configuration), in `.gitignore` or `.npmignore`. Otherwise, use `files` or `now.files` to opt-into a whitelist of files you want to deploy, excluding `.next` or your custom dist folder.
G
Guillermo Rauch 已提交
1787

1788 1789 1790 1791 1792
### Serverless deployment

<details>
  <summary><b>Examples</b></summary>
  <ul>
1793 1794
    <li><a href="https://github.com/zeit/now-examples/tree/master/nextjs">now.sh</a></li>
    <li><a href="https://github.com/TejasQ/anna-artemov.now.sh">anna-artemov.now.sh</a></li>
1795 1796 1797 1798
    <li>We encourage contributing more examples to this section</li>
  </ul>
</details>

1799
Serverless deployment dramatically improves reliability and scalability by splitting your application into smaller parts (also called [**lambdas**](https://zeit.co/docs/v2/deployments/concepts/lambdas/)). In the case of Next.js, each page in the `pages` directory becomes a serverless lambda.
1800

1801 1802 1803
There are [a number of benefits](https://zeit.co/blog/serverless-express-js-lambdas-with-now-2#benefits-of-serverless-express) to serverless. The referenced link talks about some of them in the context of Express, but the principles apply universally: serverless allows for distributed points of failure, infinite scalability, and is incredibly affordable with a "pay for what you use" model.

To enable **serverless mode** in Next.js, add the `serverless` build `target` in `next.config.js`:
1804 1805 1806 1807

```js
// next.config.js
module.exports = {
1808 1809
  target: "serverless",
};
1810 1811
```

1812
The `serverless` target will output a single lambda per page. This file is completely standalone and doesn't require any dependencies to run:
1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824

- `pages/index.js` => `.next/serverless/pages/index.js`
- `pages/about.js` => `.next/serverless/pages/about.js`

The signature of the Next.js Serverless function is similar to the Node.js HTTP server callback:

```ts
export function render(req: http.IncomingMessage, res: http.ServerResponse) => void
```

- [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
- [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse)
1825
- `void` refers to the function not having a return value and is equivalent to JavaScript's `undefined`. Calling the function will finish the request.
1826

1827 1828 1829
#### One Level Lower

Next.js provides low-level APIs for serverless deployments as hosting platforms have different function signatures. In general you will want to wrap the output of a Next.js serverless build with a compatability layer.
1830 1831 1832 1833

For example if the platform supports the Node.js [`http.Server`](https://nodejs.org/api/http.html#http_class_http_server) class:

```js
1834
const http = require("http");
1835
const page = require("./.next/serverless/pages/about.js");
1836 1837
const server = new http.Server((req, res) => page.render(req, res));
server.listen(3000, () => console.log("Listening on http://localhost:3000"));
1838 1839 1840 1841
```

For specific platform examples see [the examples section above](#serverless-deployment).

1842
#### Summary
1843

1844 1845 1846 1847
- Low-level API for implementing serverless deployment
- Every page in the `pages` directory becomes a serverless function (lambda)
- Creates the smallest possible serverless function (50Kb base zip size)
- Optimized for fast [cold start](https://zeit.co/blog/serverless-ssr#cold-start) of the function
1848 1849 1850 1851 1852
- The serverless function has 0 dependencies (they are included in the function bundle)
- Uses the [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) and [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) from Node.js
- opt-in using `target: 'serverless'` in `next.config.js`
- Does not load `next.config.js` when executing the function, note that this means `publicRuntimeConfig` / `serverRuntimeConfig` are not supported

1853 1854
## Browser support

1855
Next.js supports IE11 and all modern browsers out of the box using [`@babel/preset-env`](https://new.babeljs.io/docs/en/next/babel-preset-env.html). In order to support IE11 Next.js adds a global `Promise` polyfill. In cases where your own code or any external NPM dependencies you are using requires features not supported by your target browsers you will need to implement polyfills.
1856 1857 1858

The [polyfills](https://github.com/zeit/next.js/tree/canary/examples/with-polyfills) example demonstrates the recommended approach to implement polyfills.

A
Arunoda Susiripala 已提交
1859 1860
## Static HTML export

S
Shu Ding 已提交
1861
<details>
1862
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1863
  <ul>
1864
    <li><a href="/examples/with-static-export">Static export</a></li>
S
Shu Ding 已提交
1865 1866 1867 1868
  </ul>
</details>

<p></p>
1869

1870 1871 1872 1873 1874 1875 1876 1877 1878 1879
`next export` is a way to run your Next.js app as a standalone static app without the need for a Node.js server.
The exported app supports almost every feature of Next.js, including dynamic urls, prefetching, preloading and dynamic imports.

The way `next export` works is by pre-rendering all pages possible to HTML. It does so based on a mapping of `pathname` key to page object. This mapping is called the `exportPathMap`.

The page object has 2 values:

- `page` - `String` the page inside the `pages` directory to render
- `query` - `Object` the `query` object passed to `getInitialProps` when pre-rendering. Defaults to `{}`

A
Arunoda Susiripala 已提交
1880 1881 1882

### Usage

1883 1884 1885 1886 1887 1888 1889
Simply develop your app as you normally do with Next.js. Then run:

```
next build
next export
```

1890
By default `next export` doesn't require any configuration. It will generate a default `exportPathMap` containing the routes to pages inside the `pages` directory. This default mapping is available as `defaultPathMap` in the example below.
1891 1892 1893

If your application has dynamic routes you can add a dynamic `exportPathMap` in `next.config.js`.
This function is asynchronous and gets the default `exportPathMap` as a parameter.
A
Arunoda Susiripala 已提交
1894 1895 1896 1897

```js
// next.config.js
module.exports = {
1898
  exportPathMap: async function (defaultPathMap) {
A
Arunoda Susiripala 已提交
1899
    return {
1900 1901
      '/': { page: '/' },
      '/about': { page: '/about' },
1902
      '/readme.md': { page: '/readme' },
1903 1904 1905
      '/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
      '/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
      '/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } }
A
Arunoda Susiripala 已提交
1906
    }
1907
  }
A
Arunoda Susiripala 已提交
1908 1909 1910
}
```

1911 1912
> Note that if the path ends with a directory, it will be exported as `/dir-name/index.html`, but if it ends with an extension, it will be exported as the specified filename, e.g. `/readme.md` above. If you use a file extension other than `.html`, you may need to set the `Content-Type` header to `text/html` when serving this content.

A
Arunoda Susiripala 已提交
1913 1914
Then simply run these commands:

S
Shu Ding 已提交
1915
```bash
A
Arunoda Susiripala 已提交
1916 1917 1918 1919 1920 1921 1922 1923
next build
next export
```

For that you may need to add a NPM script to `package.json` like this:

```json
{
1924
  "scripts": {
1925 1926
    "build": "next build",
    "export": "npm run build && next export"
1927
  }
A
Arunoda Susiripala 已提交
1928 1929 1930 1931 1932
}
```

And run it at once with:

S
Shu Ding 已提交
1933
```bash
1934
npm run export
A
Arunoda Susiripala 已提交
1935 1936
```

1937
Then you have a static version of your app in the `out` directory.
A
Arunoda Susiripala 已提交
1938 1939 1940

> You can also customize the output directory. For that run `next export -h` for the help.

1941
Now you can deploy the `out` directory to any static hosting service. Note that there is an additional step for deploying to GitHub Pages, [documented here](https://github.com/zeit/next.js/wiki/Deploying-a-Next.js-app-into-GitHub-Pages).
A
Arunoda Susiripala 已提交
1942

1943
For an example, simply visit the `out` directory and run following command to deploy your app to [ZEIT Now](https://zeit.co/now).
A
Arunoda Susiripala 已提交
1944

S
Shu Ding 已提交
1945
```bash
A
Arunoda Susiripala 已提交
1946 1947 1948
now
```

1949 1950 1951
### Copying custom files

In case you have to copy custom files like a robots.txt or generate a sitemap.xml you can do this inside of `exportPathMap`.
1952
`exportPathMap` gets a few contextual parameter to aid you with creating/copying files:
1953 1954 1955 1956 1957 1958 1959 1960 1961 1962

- `dev` - `true` when `exportPathMap` is being called in development. `false` when running `next export`. In development `exportPathMap` is used to define routes and behavior like copying files is not required.
- `dir` - Absolute path to the project directory
- `outDir` - Absolute path to the `out` directory (configurable with `-o` or `--outdir`). When `dev` is `true` the value of `outDir` will be `null`.
- `distDir` - Absolute path to the `.next` directory (configurable using the `distDir` config key)
- `buildId` - The buildId the export is running for

```js
// next.config.js
const fs = require('fs')
1963 1964
const { join } = require('path')
const { promisify } = require('util')
1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978
const copyFile = promisify(fs.copyFile)

module.exports = {
  exportPathMap: async function (defaultPathMap, {dev, dir, outDir, distDir, buildId}) {
    if (dev) {
      return defaultPathMap
    }
    // This will copy robots.txt from your project root into the out directory
    await copyFile(join(dir, 'robots.txt'), join(outDir, 'robots.txt'))
    return defaultPathMap
  }
}
```

A
Arunoda Susiripala 已提交
1979 1980
### Limitation

1981
With `next export`, we build a HTML version of your app. At export time we will run `getInitialProps` of your pages.
A
Arunoda Susiripala 已提交
1982

1983
The `req` and `res` fields of the `context` object passed to `getInitialProps` are not available as there is no server running.
A
Arunoda Susiripala 已提交
1984

1985
> You won't be able to render HTML dynamically when static exporting, as we pre-build the HTML files. If you want to do dynamic rendering use `next start` or the custom server API
A
Arunoda Susiripala 已提交
1986

1987 1988
## Multi Zones

S
Shu Ding 已提交
1989
<details>
1990
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1991
  <ul>
1992
    <li><a href="/examples/with-zones">With Zones</a></li>
S
Shu Ding 已提交
1993 1994 1995 1996
  </ul>
</details>

<p></p>
1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030

A zone is a single deployment of a Next.js app. Just like that, you can have multiple zones. Then you can merge them as a single app.

For an example, you can have two zones like this:

* https://docs.my-app.com for serving `/docs/**`
* https://ui.my-app.com for serving all other pages

With multi zones support, you can merge both these apps into a single one. Which allows your customers to browse it using a single URL. But you can develop and deploy both apps independently.

> This is exactly the same concept as microservices, but for frontend apps.

### How to define a zone

There are no special zones related APIs. You only need to do following things:

* Make sure to keep only the pages you need in your app. (For an example, https://ui.my-app.com should not contain pages for `/docs/**`)
* Make sure your app has an [assetPrefix](https://github.com/zeit/next.js#cdn-support-with-asset-prefix). (You can also define the assetPrefix [dynamically](https://github.com/zeit/next.js#dynamic-assetprefix).)

### How to merge them

You can merge zones using any HTTP proxy.

You can use [micro proxy](https://github.com/zeit/micro-proxy) as your local proxy server. It allows you to easily define routing rules like below:

```json
{
  "rules": [
    {"pathname": "/docs**", "method":["GET", "POST", "OPTIONS"], "dest": "https://docs.my-app.com"},
    {"pathname": "/**", "dest": "https://ui.my-app.com"}
  ]
}
```

2031
For the production deployment, you can use the [path alias](https://zeit.co/docs/features/path-aliases) feature if you are using [ZEIT now](https://zeit.co/now). Otherwise, you can configure your existing proxy server to route HTML pages using a set of rules as shown above.
2032

2033 2034 2035
## Recipes

- [Setting up 301 redirects](https://www.raygesualdo.com/posts/301-redirects-with-nextjs/)
2036
- [Dealing with SSR and server only modules](https://arunoda.me/blog/ssr-and-server-only-modules)
K
Kelly Burke 已提交
2037
- [Building with React-Material-UI-Next-Express-Mongoose-Mongodb](https://github.com/builderbook/builderbook)
2038
- [Build a SaaS Product with React-Material-UI-Next-MobX-Express-Mongoose-MongoDB-TypeScript](https://github.com/async-labs/saas)
2039

G
Guillermo Rauch 已提交
2040
## FAQ
G
Guillermo Rauch 已提交
2041

G
Guillermo Rauch 已提交
2042 2043
<details>
  <summary>Is this production ready?</summary>
2044
  Next.js has been powering https://zeit.co since its inception.
D
Dan Zajdband 已提交
2045

G
Guillermo Rauch 已提交
2046 2047
  We’re ecstatic about both the developer experience and end-user performance, so we decided to share it with the community.
</details>
G
Guillermo Rauch 已提交
2048

S
Shu Ding 已提交
2049 2050
<p></p>

G
Guillermo Rauch 已提交
2051 2052 2053
<details>
  <summary>How big is it?</summary>

2054 2055
The client side bundle size should be measured in a per-app basis.
A small Next main bundle is around 65kb gzipped.
G
Guillermo Rauch 已提交
2056 2057 2058

</details>

S
Shu Ding 已提交
2059 2060
<p></p>

G
Guillermo Rauch 已提交
2061 2062
<details>
  <summary>Is this like `create-react-app`?</summary>
D
Dan Zajdband 已提交
2063

G
Guillermo Rauch 已提交
2064 2065 2066 2067 2068
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:
G
Guillermo Rauch 已提交
2069 2070
- Server side rendering
- Automatic code splitting
G
Guillermo Rauch 已提交
2071 2072

In addition, Next.js provides two built-in features that are critical for every single website:
2073
- Routing with lazy component loading: `<Link>` (by importing `next/link`)
G
Guillermo Rauch 已提交
2074
- A way for components to alter `<head>`: `<Head>` (by importing `next/head`)
G
Guillermo Rauch 已提交
2075

G
Guillermo Rauch 已提交
2076
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!
G
Guillermo Rauch 已提交
2077 2078 2079

</details>

S
Shu Ding 已提交
2080 2081
<p></p>

G
Guillermo Rauch 已提交
2082
<details>
G
Guillermo Rauch 已提交
2083
  <summary>How do I use CSS-in-JS solutions?</summary>
G
Guillermo Rauch 已提交
2084

T
Tim Neutkens 已提交
2085
Next.js bundles [styled-jsx](https://github.com/zeit/styled-jsx) supporting scoped css. However you can use any CSS-in-JS solution in your Next app by just including your favorite library [as mentioned before](#css-in-js) in the document.
G
Guillermo Rauch 已提交
2086 2087
</details>

S
Shu Ding 已提交
2088 2089
<p></p>

G
Guillermo Rauch 已提交
2090 2091 2092 2093 2094
<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.

2095
See the  documentation about [customizing the babel config](#customizing-babel-config) and [next/preset](/packages/next/build/babel/preset.js) for more information.
G
Guillermo Rauch 已提交
2096 2097 2098

</details>

S
Shu Ding 已提交
2099 2100
<p></p>

G
Guillermo Rauch 已提交
2101 2102 2103 2104 2105 2106
<details>
  <summary>Why a new Router?</summary>

Next.js is special in that:

- Routes don’t need to be known ahead of time
N
nkzawa 已提交
2107
- Routes are always lazy-loadable
G
Guillermo Rauch 已提交
2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118
- 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>

S
Shu Ding 已提交
2119 2120
<p></p>

G
Guillermo Rauch 已提交
2121 2122 2123
<details>
<summary>How do I define a custom fancy route?</summary>

2124
We [added](#custom-server-and-routing) the ability to map between an arbitrary URL and any component by supplying a request handler.
G
Guillermo Rauch 已提交
2125

2126
On the client side, we have a parameter call `as` on `<Link>` that _decorates_ the URL differently from the URL it _fetches_.
G
Guillermo Rauch 已提交
2127 2128
</details>

S
Shu Ding 已提交
2129 2130
<p></p>

G
Guillermo Rauch 已提交
2131 2132 2133 2134 2135 2136
<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>

S
Shu Ding 已提交
2137 2138
<p></p>

A
Adam Soffer 已提交
2139 2140 2141
<details>
  <summary>Can I use it with GraphQL?</summary>

2142
Yes! Here's an example with [Apollo](/examples/with-apollo).
A
Adam Soffer 已提交
2143 2144 2145

</details>

S
Shu Ding 已提交
2146 2147
<p></p>

G
Guillermo Rauch 已提交
2148 2149 2150
<details>
<summary>Can I use it with Redux?</summary>

2151
Yes! Here's an [example](/examples/with-redux)
G
Guillermo Rauch 已提交
2152 2153
</details>

S
Shu Ding 已提交
2154 2155
<p></p>

T
Tim Neutkens 已提交
2156 2157 2158
<details>
<summary>Can I use Next with my favorite Javascript library or toolkit?</summary>

2159
Since our first release we've had **many** example contributions, you can check them out in the [examples](/examples) directory
T
Tim Neutkens 已提交
2160 2161
</details>

S
Shu Ding 已提交
2162 2163
<p></p>

G
Guillermo Rauch 已提交
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176
<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>

S
Shu Ding 已提交
2177 2178
<p></p>

T
Tim Neutkens 已提交
2179 2180
## Contributing

T
Tim Neutkens 已提交
2181
Please see our [contributing.md](/contributing.md)
T
Tim Neutkens 已提交
2182

G
Guillermo Rauch 已提交
2183 2184
## Authors

2185
- Arunoda Susiripala ([@arunoda](https://twitter.com/arunoda)) – [ZEIT](https://zeit.co)
2186
- Tim Neutkens ([@timneutkens](https://twitter.com/timneutkens)) – [ZEIT](https://zeit.co)
2187 2188 2189
- Naoyuki Kanezawa ([@nkzawa](https://twitter.com/nkzawa)) – [ZEIT](https://zeit.co)
- Tony Kovanen ([@tonykovanen](https://twitter.com/tonykovanen)) – [ZEIT](https://zeit.co)
- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) – [ZEIT](https://zeit.co)
P
Paul O’Shannessy 已提交
2190
- Dan Zajdband ([@impronunciable](https://twitter.com/impronunciable)) – Knight-Mozilla / Coral Project