README.md 76.9 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)
51 52 53 54 55
    - [Basic Usage (Also does SSR)](#basic-usage-also-does-ssr)
    - [With Named Exports](#with-named-exports)
    - [With Custom Loading Component](#with-custom-loading-component)
    - [With No SSR](#with-no-ssr)
    - [With Multiple Modules At Once](#with-multiple-modules-at-once)
T
Tim Neutkens 已提交
56
  - [Custom `<App>`](#custom-app)
57
  - [Custom `<Document>`](#custom-document)
58
    - [Customizing `renderPage`](#customizing-renderpage)
59
  - [Custom error handling](#custom-error-handling)
T
Tim Neutkens 已提交
60
  - [Reusing the built-in error page](#reusing-the-built-in-error-page)
61
  - [Custom configuration](#custom-configuration)
T
Tim Neutkens 已提交
62 63 64 65 66
    - [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 已提交
67
    - [Configuring Next process script](#configuring-next-process-script)
68 69
  - [Customizing webpack config](#customizing-webpack-config)
  - [Customizing babel config](#customizing-babel-config)
70
  - [Exposing configuration to the server / client side](#exposing-configuration-to-the-server--client-side)
71
  - [Starting the server on alternative hostname](#starting-the-server-on-alternative-hostname)
72
  - [CDN support with Asset Prefix](#cdn-support-with-asset-prefix)
73
- [Production deployment](#production-deployment)
74
  - [Serverless deployment](#serverless-deployment)
75 76 77
    - [One Level Lower](#one-level-lower)
    - [Summary](#summary)
- [Browser support](#browser-support)
78 79
- [Typescript](#typescript)
  - [Exported types](#exported-types)
J
JJ Kasper 已提交
80
- [AMP Support](#amp-support)
A
Arunoda Susiripala 已提交
81
- [Static HTML export](#static-html-export)
T
Tim Neutkens 已提交
82
  - [Usage](#usage)
83
  - [Copying custom files](#copying-custom-files)
T
Tim Neutkens 已提交
84
  - [Limitation](#limitation)
85
- [Multi Zones](#multi-zones)
T
Tim Neutkens 已提交
86 87
  - [How to define a zone](#how-to-define-a-zone)
  - [How to merge them](#how-to-merge-them)
88
- [Recipes](#recipes)
89
- [FAQ](#faq)
T
Tim Neutkens 已提交
90
- [Contributing](#contributing)
91 92 93
- [Authors](#authors)

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

G
Guillermo Rauch 已提交
95 96
## How to use

97 98
### Setup

G
Guillermo Rauch 已提交
99 100
Install it:

T
Tim Neutkens 已提交
101
```bash
A
Arunoda Susiripala 已提交
102
npm install --save next react react-dom
T
Tim Neutkens 已提交
103 104
```

105 106 107 108 109
and add a script to your package.json like this:

```json
{
  "scripts": {
110 111 112
    "dev": "next",
    "build": "next build",
    "start": "next start"
113
  }
114 115 116
}
```

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

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

G
Guillermo Rauch 已提交
121
```jsx
122
function Home() {
123
  return <div>Welcome to Next.js!</div>
124 125 126
}

export default Home
G
Guillermo Rauch 已提交
127 128
```

129
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 已提交
130 131 132 133 134

So far, we get:

- Automatic transpilation and bundling (with webpack and babel)
- Hot code reloading
G
Guillermo Rauch 已提交
135
- Server rendering and indexing of `./pages`
136
- 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 已提交
137

138

G
Guillermo Rauch 已提交
139
### Automatic code splitting
G
Guillermo Rauch 已提交
140

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

G
Guillermo Rauch 已提交
143
```jsx
D
Dan Zajdband 已提交
144
import cowsay from 'cowsay-browser'
145

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

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

### CSS

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

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

164

165
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 已提交
166

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

export default HelloWorld
G
Guillermo Rauch 已提交
196 197
```

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

G
Guillermo Rauch 已提交
200 201
#### CSS-in-JS

S
Shu Ding 已提交
202
<details>
203 204
  <summary>
    <b>Examples</b>
S
Shu Ding 已提交
205 206
  </summary>
  <ul>
207 208 209 210 211 212
    <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 已提交
213 214 215
  </ul>
</details>

N
Naoyuki Kanezawa 已提交
216

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

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

export default HiThere
G
Guillermo Rauch 已提交
225 226
```

J
Joshua Scott 已提交
227
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>`](#custom-document) component that wraps each page.
G
Guillermo Rauch 已提交
228

229
#### Importing CSS / Sass / Less / Stylus files
T
Tim Neutkens 已提交
230

231
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 已提交
232

J
Juan Caicedo 已提交
233 234 235
- [@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)
236
- [@zeit/next-stylus](https://github.com/zeit/next-plugins/tree/master/packages/next-stylus)
T
Tim Neutkens 已提交
237

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

240 241 242 243 244 245 246
<details>
  <summary><b>Examples</b></summary>
  <ul>
    <li><a href="/examples/public-file-serving">Public file serving</a></li>
  </ul>
</details>

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

```jsx
250 251 252 253 254
function MyImage() {
  return <img src="/static/my-image.png" alt="my image" />
}

export default MyImage
G
Guillermo Rauch 已提交
255
```
256

257 258 259
To serve static files from the root directory you can add a folder called `public` and reference those files from the root, e.g: `/robots.txt`

_Note: Don't name the `static` or `public` directory anything else. The names can't be changed and are the only directories that Next.js uses for serving static assets_
260

G
Guillermo Rauch 已提交
261
### Populating `<head>`
G
Guillermo Rauch 已提交
262

S
Shu Ding 已提交
263
<details>
264
  <summary><b>Examples</b></summary>
265
  <ul>
266 267
    <li><a href="/examples/head-elements">Head elements</a></li>
    <li><a href="/examples/layout-component">Layout component</a></li>
268
  </ul>
S
Shu Ding 已提交
269 270
</details>

271

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

G
Guillermo Rauch 已提交
274
```jsx
G
Guillermo Rauch 已提交
275
import Head from 'next/head'
276

277 278 279 280 281 282 283 284 285 286 287 288 289
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 已提交
290 291
```

292 293 294 295
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'
296

297 298 299 300 301
function IndexPage() {
  return (
    <div>
      <Head>
        <title>My page title</title>
302 303 304 305 306
        <meta
          name="viewport"
          content="initial-scale=1.0, width=device-width"
          key="viewport"
        />
307 308
      </Head>
      <Head>
309 310 311 312 313
        <meta
          name="viewport"
          content="initial-scale=1.2, width=device-width"
          key="viewport"
        />
314 315 316 317 318 319 320
      </Head>
      <p>Hello world!</p>
    </div>
  )
}

export default IndexPage
321 322 323
```

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

325
_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._
G
Guillermo Rauch 已提交
326

327 328
_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 已提交
329
### Fetching data and component lifecycle
G
Guillermo Rauch 已提交
330

S
Shu Ding 已提交
331
<details>
D
Dan Zajdband 已提交
332
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
333
  <ul>
334
    <li><a href="/examples/data-fetch">Data fetch</a></li>
S
Shu Ding 已提交
335 336 337
  </ul>
</details>

D
Dan Zajdband 已提交
338

G
Guillermo Rauch 已提交
339
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 已提交
340

G
Guillermo Rauch 已提交
341
```jsx
G
Guillermo Rauch 已提交
342
import React from 'react'
343

344
class HelloUA extends React.Component {
345 346 347
  static async getInitialProps({ req }) {
    const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
    return { userAgent }
G
Guillermo Rauch 已提交
348
  }
349 350

  render() {
351
    return <div>Hello World {this.props.userAgent}</div>
G
Guillermo Rauch 已提交
352 353
  }
}
354 355

export default HelloUA
G
Guillermo Rauch 已提交
356 357
```

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

360 361
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 已提交
362
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.
363

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

366
<br/>
A
Arunoda Susiripala 已提交
367

368 369
> 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 已提交
370

371 372
<br/>

373 374 375
You can also define the `getInitialProps` lifecycle method for stateless components:

```jsx
376 377 378
function Page({ stars }) {
  return <div>Next stars: {stars}</div>
}
379 380 381 382 383 384 385 386 387 388

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 已提交
389
`getInitialProps` receives a context object with the following properties:
390 391 392

- `pathname` - path section of URL
- `query` - query string section of URL parsed as an object
A
Arunoda Susiripala 已提交
393
- `asPath` - `String` of the actual path (including the query) shows in the browser
394 395 396 397
- `req` - HTTP request object (server only)
- `res` - HTTP response object (server only)
- `err` - Error object if any error is encountered during the rendering

G
Guillermo Rauch 已提交
398 399
### Routing

400 401
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.

402 403
#### With `<Link>`

S
Shu Ding 已提交
404
<details>
G
Guillermo Rauch 已提交
405
  <summary><b>Examples</b></summary>
406
  <ul>
407
    <li><a href="/examples/hello-world">Hello World</a></li>
408
  </ul>
S
Shu Ding 已提交
409 410
</details>

G
Guillermo Rauch 已提交
411

412 413 414 415 416
Client-side transitions between routes can be enabled via a `<Link>` component.

**Basic Example**

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

G
Guillermo Rauch 已提交
418
```jsx
G
Guillermo Rauch 已提交
419
// pages/index.js
G
Guillermo Rauch 已提交
420
import Link from 'next/link'
421

422 423 424 425 426 427 428 429 430 431 432 433 434
function Home() {
  return (
    <div>
      Click{' '}
      <Link href="/about">
        <a>here</a>
      </Link>{' '}
      to read more
    </div>
  )
}

export default Home
G
Guillermo Rauch 已提交
435 436
```

G
Guillermo Rauch 已提交
437
```jsx
G
Guillermo Rauch 已提交
438
// pages/about.js
439 440 441 442 443
function About() {
  return <p>Welcome to About!</p>
}

export default About
G
Guillermo Rauch 已提交
444 445
```

446 447
**Custom routes (using props from URL)**

448
`<Link>` component has two main props:
449

450 451
- `href`: the path inside `pages` directory + query string.
- `as`: the path that will be rendered in the browser URL bar.
452 453 454 455 456 457 458

Example:

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

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

459 460 461 462 463 464 465 466 467 468 469 470 471
   ```jsx
   class Post extends React.Component {
     static async getInitialProps({ query }) {
       console.log('SLUG', query.slug)
       return {}
     }
     render() {
       return <h1>My blog post</h1>
     }
   }

   export default Post
   ```
472

473 474
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.

475 476 477 478 479 480
   ```jsx
   server.get('/post/:slug', (req, res) => {
     return app.render(req, res, '/post', { slug: req.params.slug })
   })
   ```

481
4. For client side routing, use `next/link`:
482 483 484
   ```jsx
   <Link href="/post?slug=something" as="/post/something">
   ```
485

486
**Note: use [`<Link prefetch>`](#prefetching-pages) for maximum performance, to link and prefetch in the background at the same time**
G
Guillermo Rauch 已提交
487

G
Guillermo Rauch 已提交
488
Client-side routing behaves exactly like the browser:
G
Guillermo Rauch 已提交
489 490 491

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

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

496 497
##### With URL object

S
Shu Ding 已提交
498
<details>
499 500
  <summary><b>Examples</b></summary>
  <ul>
501
    <li><a href="/examples/with-url-object-routing">With URL Object Routing</a></li>
502
  </ul>
S
Shu Ding 已提交
503 504
</details>

505

506
The component `<Link>` can also receive a URL object and it will automatically format it to create the URL string.
507 508 509 510

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

512 513 514 515 516 517 518 519 520 521 522 523 524
function Home() {
  return (
    <div>
      Click{' '}
      <Link href={{ pathname: '/about', query: { name: 'Zeit' } }}>
        <a>here</a>
      </Link>{' '}
      to read more
    </div>
  )
}

export default Home
525 526 527 528
```

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

529 530
##### Replace instead of push url

D
Dan Zajdband 已提交
531 532 533 534 535
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'
536

537 538 539 540 541 542 543 544 545 546 547 548 549
function Home() {
  return (
    <div>
      Click{' '}
      <Link href="/about" replace>
        <a>here</a>
      </Link>{' '}
      to read more
    </div>
  )
}

export default Home
D
Dan Zajdband 已提交
550 551
```

552
##### Using a component that supports `onClick`
553 554 555 556 557 558

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

560 561 562 563 564 565 566 567 568 569 570 571
function Home() {
  return (
    <div>
      Click{' '}
      <Link href="/about">
        <img src="/static/image.png" alt="image" />
      </Link>
    </div>
  )
}

export default Home
572 573
```

574
##### Forcing the Link to expose `href` to its child
575

576
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.
577

578 579
**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.

580 581 582
```jsx
import Link from 'next/link'
import Unexpected_A from 'third-library'
583

584 585 586
function NavLink({ href, name }) {
  return (
    <Link href={href} passHref>
587
      <Unexpected_A>{name}</Unexpected_A>
588 589 590 591 592
    </Link>
  )
}

export default NavLink
593 594
```

J
Jimmy Moon 已提交
595 596 597 598 599 600 601 602 603
##### 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>
```

604
#### Imperatively
605

S
Shu Ding 已提交
606
<details>
607 608
  <summary><b>Examples</b></summary>
  <ul>
609 610
    <li><a href="/examples/using-router">Basic routing</a></li>
    <li><a href="/examples/with-loading">With a page loading indicator</a></li>
611
  </ul>
S
Shu Ding 已提交
612 613
</details>

614

G
Guillermo Rauch 已提交
615
You can also do client-side page transitions using the `next/router`
616 617 618 619

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

620 621 622 623 624 625 626 627 628
function ReadMore() {
  return (
    <div>
      Click <span onClick={() => Router.push('/about')}>here</span> to read more
    </div>
  )
}

export default ReadMore
629 630
```

631 632 633
#### Intercepting `popstate`

In some cases (for example, if using a [custom router](#custom-server-and-routing)), you may wish
634
to listen to [`popstate`](https://developer.mozilla.org/en-US/docs/Web/Events/popstate) and react before the router acts on it.
635 636 637 638 639 640 641
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!
642
  if (as !== '/' || as !== '/other') {
643 644 645 646 647 648
    // Have SSR render bad routes as a 404.
    window.location.href = as
    return false
  }

  return true
649
})
650 651
```

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

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

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

668
##### With URL object
669

670
You can use a URL object the same way you use it in a `<Link>` component to `push` and `replace` a URL.
671 672 673 674

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

675
const handler = () => {
676 677 678 679
  Router.push({
    pathname: '/about',
    query: { name: 'Zeit' }
  })
680
}
681

682
function ReadMore() {
683
  return (
684 685 686 687 688 689 690
    <div>
      Click <span onClick={handler}>here</span> to read more
    </div>
  )
}

export default ReadMore
691 692
```

693
This uses the same exact parameters as in the `<Link>` component.
694

695 696 697 698 699
##### Router Events

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

700 701 702 703 704 705
- `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
706 707 708

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

709
Here's how to properly listen to the router event `routeChangeStart`:
710 711

```js
712
const handleRouteChange = url => {
713 714
  console.log('App is changing to: ', url)
}
715 716

Router.events.on('routeChangeStart', handleRouteChange)
717 718
```

719
If you no longer want to listen to that event, you can unsubscribe with the `off` method:
720 721

```js
722
Router.events.off('routeChangeStart', handleRouteChange)
723 724
```

725
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`.
726 727

```js
728
Router.events.on('routeChangeError', (err, url) => {
729
  if (err.cancelled) {
G
Guillermo Rauch 已提交
730
    console.log(`Route to ${url} was cancelled!`)
731
  }
732
})
733 734
```

735 736
##### Shallow Routing

S
Shu Ding 已提交
737
<details>
738 739
  <summary><b>Examples</b></summary>
  <ul>
740
    <li><a href="/examples/with-shallow-routing">Shallow Routing</a></li>
741
  </ul>
S
Shu Ding 已提交
742 743
</details>

744

745
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.
746

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

749
```js
750 751 752 753 754 755
// Current URL is "/"
const href = '/?counter=10'
const as = href
Router.push(href, as, { shallow: true })
```

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

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

760
```js
761 762 763 764 765 766
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
  }
767 768 769 770
}
```

> NOTES:
771
>
F
Fabio Espinosa 已提交
772
> 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:
773
>
774
> ```js
J
Jeffrey Young 已提交
775
> Router.push('/?counter=10', '/about?counter=10', { shallow: true })
776
> ```
777
>
B
Ben Hadfield 已提交
778
> 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.
779

A
Arunoda Susiripala 已提交
780 781
#### Using a Higher Order Component

S
Shu Ding 已提交
782
<details>
A
Arunoda Susiripala 已提交
783 784
  <summary><b>Examples</b></summary>
  <ul>
785
    <li><a href="/examples/using-with-router">Using the `withRouter` utility</a></li>
A
Arunoda Susiripala 已提交
786
  </ul>
S
Shu Ding 已提交
787 788
</details>

A
Arunoda Susiripala 已提交
789 790 791 792 793 794

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'

795
function ActiveLink({ children, router, href }) {
A
Arunoda Susiripala 已提交
796 797
  const style = {
    marginRight: 10,
H
Homer Chen 已提交
798
    color: router.pathname === href ? 'red' : 'black'
A
Arunoda Susiripala 已提交
799 800
  }

801
  const handleClick = e => {
A
Arunoda Susiripala 已提交
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817
    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).

818 819
### Prefetching Pages

820
⚠️ This is a production only feature ⚠️
821

S
Shu Ding 已提交
822
<details>
823
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
824
  <ul>
825
    <li><a href="/examples/with-prefetching">Prefetching</a></li>
S
Shu Ding 已提交
826 827 828
  </ul>
</details>

829

830
Next.js has an API which allows you to prefetch pages.
831

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

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

T
Tim Neutkens 已提交
836 837
> `<link rel="preload">` is used for prefetching. Sometimes browsers will show a warning if the resource is not used within 3 seconds, these warnings can be ignored as per https://github.com/zeit/next.js/issues/6517#issuecomment-469063892

G
Guillermo Rauch 已提交
838
#### With `<Link>`
839

840
You can add `prefetch` prop to any `<Link>` and Next.js will prefetch those pages in the background.
841 842

```jsx
843 844
import Link from 'next/link'

G
Gary Meehan 已提交
845
function Header() {
846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
  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
870 871
```

G
Guillermo Rauch 已提交
872
#### Imperatively
873

874
Most prefetching needs are addressed by `<Link />`, but we also expose an imperative API for advanced usage:
875 876

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

G
Gary Meehan 已提交
879
function MyLink({ router }) {
880 881 882 883 884 885 886 887 888 889 890 891
  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 已提交
892
```
893

894 895 896 897
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'
898
import { withRouter } from 'next/router'
899

900
class MyLink extends React.Component {
901
  componentDidMount() {
902 903
    const { router } = this.props
    router.prefetch('/dynamic')
904
  }
905

906
  render() {
907
    const { router } = this.props
908

909
    return (
910
      <div>
911
        <a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}>
912 913
          A route transition will happen after 100ms
        </a>
914
      </div>
915 916 917
    )
  }
}
918 919

export default withRouter(MyLink)
920 921
```

G
Guillermo Rauch 已提交
922 923
### Custom server and routing

S
Shu Ding 已提交
924
<details>
925
  <summary><b>Examples</b></summary>
D
Dan Zajdband 已提交
926
  <ul>
927 928 929 930 931 932
    <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 已提交
933
  </ul>
S
Shu Ding 已提交
934 935
</details>

936

937 938 939 940 941 942 943 944 945 946 947 948 949
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 已提交
950 951 952

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

G
Guillermo Rauch 已提交
953
```js
954
// This file doesn't go through babel or webpack transformation.
955 956
// 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 已提交
957 958 959 960
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

961 962
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
G
Guillermo Rauch 已提交
963 964 965 966
const handle = app.getRequestHandler()

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

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

G
Guillermo Rauch 已提交
986
The `next` API is as follows:
987

G
Guillermo Rauch 已提交
988 989 990
- `next(opts: object)`

Supported options:
991

992 993
- `dev` (`bool`) whether to launch Next.js in dev mode - default `false`
- `dir` (`string`) where the Next project is located - default `'.'`
994
- `quiet` (`bool`) Hide error messages containing server information - default `false`
995
- `conf` (`object`) the same object you would use in `next.config.js` - default `{}`
G
Guillermo Rauch 已提交
996

997 998
Then, change your `start` script to `NODE_ENV=production node server.js`.

999
#### Disabling file-system routing
1000

K
Kanjie Lu 已提交
1001
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`.
1002

1003
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.
1004

1005
To disable this behavior & prevent routing based on files in `/pages`, simply set the following option in your `next.config.js`:
1006 1007 1008 1009 1010 1011 1012 1013

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

1014 1015 1016 1017 1018 1019 1020
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).

1021 1022 1023 1024 1025 1026 1027 1028 1029
#### 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')
1030
const http = require('http')
1031 1032 1033

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
S
S. Suzuki 已提交
1034
const handleNextRequests = app.getRequestHandler()
1035 1036

app.prepare().then(() => {
1037
  const server = new http.Server((req, res) => {
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
    // 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)
  })

1048
  server.listen(port, err => {
1049 1050 1051 1052 1053 1054 1055 1056
    if (err) {
      throw err
    }

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

A
Arunoda Susiripala 已提交
1058 1059
### Dynamic Import

S
Shu Ding 已提交
1060
<details>
A
Arunoda Susiripala 已提交
1061 1062
  <summary><b>Examples</b></summary>
  <ul>
1063
    <li><a href="/examples/with-dynamic-import">With Dynamic Import</a></li>
A
Arunoda Susiripala 已提交
1064
  </ul>
S
Shu Ding 已提交
1065 1066
</details>

A
Arunoda Susiripala 已提交
1067 1068 1069 1070 1071 1072 1073 1074 1075

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.

1076
#### Basic Usage (Also does SSR)
A
Arunoda Susiripala 已提交
1077

1078
```jsx
A
Arunoda Susiripala 已提交
1079
import dynamic from 'next/dynamic'
1080

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

1083 1084 1085 1086 1087 1088 1089 1090
function Home() {
  return (
    <div>
      <Header />
      <DynamicComponent />
      <p>HOME PAGE is here!</p>
    </div>
  )
G
Gary Meehan 已提交
1091
}
1092 1093

export default Home
A
Arunoda Susiripala 已提交
1094 1095
```

1096 1097 1098 1099 1100
#### With named exports

```jsx
// components/hello.js
export function Hello() {
1101
  return <p>Hello!</p>
1102 1103 1104 1105 1106 1107
}
```

```jsx
import dynamic from 'next/dynamic'

1108 1109 1110
const DynamicComponent = dynamic(() =>
  import('../components/hello').then(mod => mod.Hello)
)
1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponent />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
```

#### With Custom Loading Component
A
Arunoda Susiripala 已提交
1126

1127
```jsx
A
Arunoda Susiripala 已提交
1128
import dynamic from 'next/dynamic'
1129

1130 1131 1132 1133 1134 1135
const DynamicComponentWithCustomLoading = dynamic(
  () => import('../components/hello2'),
  {
    loading: () => <p>...</p>
  }
)
A
Arunoda Susiripala 已提交
1136

1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithCustomLoading />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
A
Arunoda Susiripala 已提交
1148 1149
```

1150
#### With No SSR
A
Arunoda Susiripala 已提交
1151

1152
```jsx
A
Arunoda Susiripala 已提交
1153 1154
import dynamic from 'next/dynamic'

1155 1156 1157 1158 1159 1160
const DynamicComponentWithNoSSR = dynamic(
  () => import('../components/hello3'),
  {
    ssr: false
  }
)
1161

1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home
A
Arunoda Susiripala 已提交
1173 1174
```

1175
#### With Multiple Modules At Once
A
Arunoda Susiripala 已提交
1176

1177
```jsx
1178 1179 1180
import dynamic from 'next/dynamic'

const HelloBundle = dynamic({
1181
  modules: () => {
1182
    const components = {
1183 1184
      Hello1: () => import('../components/hello1'),
      Hello2: () => import('../components/hello2')
1185 1186 1187 1188
    }

    return components
  },
1189
  render: (props, { Hello1, Hello2 }) => (
1190
    <div>
1191
      <h1>{props.title}</h1>
1192 1193 1194
      <Hello1 />
      <Hello2 />
    </div>
1195
  )
A
Arunoda Susiripala 已提交
1196 1197
})

1198 1199 1200 1201 1202
function DynamicBundle() {
  return <HelloBundle title="Dynamic Bundle" />
}

export default DynamicBundle
A
Arunoda Susiripala 已提交
1203 1204
```

T
Tim Neutkens 已提交
1205 1206
### Custom `<App>`

S
Shu Ding 已提交
1207
<details>
T
Tim Neutkens 已提交
1208
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1209
  <ul>
1210 1211
    <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 已提交
1212 1213 1214
  </ul>
</details>

T
Tim Neutkens 已提交
1215

C
Christian Nwamba 已提交
1216
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 已提交
1217 1218 1219 1220 1221 1222 1223 1224 1225 1226

- 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'
1227
import App, { Container } from 'next/app'
T
Tim Neutkens 已提交
1228

1229
class MyApp extends App {
1230
  static async getInitialProps({ Component, ctx }) {
T
Tim Neutkens 已提交
1231 1232 1233 1234 1235 1236
    let pageProps = {}

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

1237
    return { pageProps }
T
Tim Neutkens 已提交
1238 1239
  }

1240
  render() {
1241 1242 1243 1244 1245 1246 1247
    const { Component, pageProps } = this.props

    return (
      <Container>
        <Component {...pageProps} />
      </Container>
    )
T
Tim Neutkens 已提交
1248 1249
  }
}
1250 1251

export default MyApp
T
Tim Neutkens 已提交
1252 1253
```

G
Guillermo Rauch 已提交
1254 1255
### Custom `<Document>`

S
Shu Ding 已提交
1256
<details>
1257
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1258
  <ul>
1259 1260
    <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 已提交
1261 1262 1263
  </ul>
</details>

1264

T
Tim Neutkens 已提交
1265 1266
- Is rendered on the server side
- Is used to change the initial server side rendered document markup
1267
- 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 已提交
1268

1269
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 已提交
1270 1271

```jsx
1272 1273 1274
// _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

1275
// ./pages/_document.js
1276
import Document, { Html, Head, Main, NextScript } from 'next/document'
G
Guillermo Rauch 已提交
1277

1278
class MyDocument extends Document {
T
Tim Neutkens 已提交
1279 1280 1281
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
G
Guillermo Rauch 已提交
1282 1283
  }

1284
  render() {
G
Guillermo Rauch 已提交
1285
    return (
1286
      <Html>
1287 1288 1289 1290 1291 1292 1293
        <Head>
          <style>{`body { margin: 0 } /* custom! */`}</style>
        </Head>
        <body className="custom_class">
          <Main />
          <NextScript />
        </body>
1294
      </Html>
G
Guillermo Rauch 已提交
1295 1296 1297
    )
  }
}
1298 1299

export default MyDocument
G
Guillermo Rauch 已提交
1300 1301
```

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

1304
**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.**
1305

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

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

1310
#### Customizing `renderPage`
1311

1312 1313 1314 1315 1316 1317 1318 1319
🚧 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'

1320
class MyDocument extends Document {
1321 1322 1323
  static async getInitialProps(ctx) {
    const originalRenderPage = ctx.renderPage

1324 1325 1326 1327 1328 1329 1330
    ctx.renderPage = () =>
      originalRenderPage({
        // useful for wrapping the whole react tree
        enhanceApp: App => App,
        // useful for wrapping in a per-page basis
        enhanceComponent: Component => Component
      })
1331 1332 1333 1334 1335 1336 1337

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

    return initialProps
  }
}
1338 1339

export default MyDocument
1340
```
1341

G
Guillermo Rauch 已提交
1342
### Custom error handling
1343

F
Fabio Espinosa 已提交
1344
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:
1345

D
Dovydas Navickas 已提交
1346
⚠️ 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 已提交
1347

1348 1349
```jsx
import React from 'react'
1350

1351
class Error extends React.Component {
1352
  static getInitialProps({ res, err }) {
1353
    const statusCode = res ? res.statusCode : err ? err.statusCode : null
1354 1355 1356
    return { statusCode }
  }

1357
  render() {
1358
    return (
1359 1360 1361 1362 1363
      <p>
        {this.props.statusCode
          ? `An error ${this.props.statusCode} occurred on server`
          : 'An error occurred on client'}
      </p>
1364 1365 1366
    )
  }
}
1367 1368

export default Error
1369 1370
```

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

J
Jure Triglav 已提交
1373
If you want to render the built-in error page you can by using `next/error`:
T
Tim Neutkens 已提交
1374 1375 1376 1377

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

1380
class Page extends React.Component {
1381
  static async getInitialProps() {
T
Tim Neutkens 已提交
1382
    const res = await fetch('https://api.github.com/repos/zeit/next.js')
1383
    const errorCode = res.statusCode > 200 ? res.statusCode : false
T
Tim Neutkens 已提交
1384
    const json = await res.json()
1385

1386
    return { errorCode, stars: json.stargazers_count }
T
Tim Neutkens 已提交
1387 1388
  }

1389
  render() {
1390 1391
    if (this.props.errorCode) {
      return <Error statusCode={this.props.errorCode} />
T
Tim Neutkens 已提交
1392 1393
    }

1394
    return <div>Next stars: {this.props.stars}</div>
T
Tim Neutkens 已提交
1395 1396
  }
}
1397 1398

export default Page
T
Tim Neutkens 已提交
1399 1400
```

1401 1402 1403
> If you have created a custom error page you have to import your own `_error` component from `./_error` instead of `next/error`.

The Error module also takes `title` as a property if you want to pass in message text along with a `statusCode`.
T
Tim Neutkens 已提交
1404

G
Guillermo Rauch 已提交
1405
### Custom configuration
G
Guillermo Rauch 已提交
1406

1407
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 已提交
1408 1409 1410

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.

1411
```js
G
Guillermo Rauch 已提交
1412 1413 1414 1415 1416 1417
// next.config.js
module.exports = {
  /* config options here */
}
```

1418 1419 1420
Or use a function:

```js
1421
module.exports = (phase, { defaultConfig }) => {
1422 1423 1424 1425 1426 1427
  return {
    /* config options here */
  }
}
```

1428
`phase` is the current context in which the configuration is loaded. You can see all phases here: [constants](/packages/next-server/lib/constants.js)
1429 1430 1431
Phases can be imported from `next/constants`:

```js
1432 1433 1434
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
module.exports = (phase, { defaultConfig }) => {
  if (phase === PHASE_DEVELOPMENT_SERVER) {
1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445
    return {
      /* development only config options here */
    }
  }

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

1446 1447 1448 1449
#### 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.

1450
```js
1451 1452 1453 1454 1455 1456
// next.config.js
module.exports = {
  distDir: 'build'
}
```

1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467
#### 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
}
```

1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
#### 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
1478
    pagesBufferLength: 2
1479
  }
1480 1481 1482
}
```

1483 1484
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 已提交
1485 1486
#### Configuring extensions looked for when resolving pages in `pages`

1487
Aimed at modules like [`@next/mdx`](https://github.com/zeit/next.js/tree/canary/packages/next-mdx), that add support for pages ending with `.mdx`. `pageExtensions` allows you to configure the extensions looked for in the `pages` directory when resolving pages.
T
Tim Neutkens 已提交
1488 1489 1490 1491

```js
// next.config.js
module.exports = {
1492
  pageExtensions: ['mdx', 'jsx', 'js']
T
Tim Neutkens 已提交
1493 1494 1495
}
```

1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509
#### 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'
  }
}
```

1510 1511 1512 1513 1514 1515
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
1516
    if (process.env.YOUR_BUILD_ID) {
1517 1518 1519 1520 1521 1522 1523 1524
      return process.env.YOUR_BUILD_ID
    }

    return null
  }
}
```

D
DevSide 已提交
1525 1526
#### Configuring next process script

1527
You can pass any node arguments to `next` CLI command.
D
DevSide 已提交
1528 1529

```bash
1530 1531
NODE_OPTIONS="--throw-deprecation" next
NODE_OPTIONS="-r esm" next
C
Connor Davis 已提交
1532
NODE_OPTIONS="--inspect" next
D
DevSide 已提交
1533 1534
```

G
Guillermo Rauch 已提交
1535 1536
### Customizing webpack config

S
Shu Ding 已提交
1537
<details>
1538
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1539
  <ul>
1540
    <li><a href="/examples/with-webpack-bundle-analyzer">Custom webpack bundle analyzer</a></li>
S
Shu Ding 已提交
1541 1542 1543
  </ul>
</details>

1544

1545 1546 1547 1548 1549 1550
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)
1551
- [@next/mdx](https://github.com/zeit/next.js/tree/canary/packages/next-mdx)
1552

M
Mayank Jethva 已提交
1553
> **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
1554 1555 1556 1557

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

```js
1558
const withMDX = require('@next/mdx')
1559 1560
const withSass = require('@zeit/next-sass')

1561
module.exports = withMDX(
1562 1563 1564 1565 1566 1567 1568
  withSass({
    webpack(config, options) {
      // Further custom configuration here
      return config
    }
  })
)
1569 1570
```

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

```js
1574
// next.config.js is not transformed by Babel. So you can only use javascript features supported by your version of Node.js.
1575 1576

module.exports = {
1577 1578
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    // Note: we provide webpack above so you should not `require` it
1579 1580
    // Perform customizations to webpack config
    // Important: return the modified config
1581

J
JJ Kasper 已提交
1582 1583 1584 1585
    // Example using webpack option
    config.plugins.push(
      new webpack.IgnorePlugin(/\/__tests__\//),
    )
1586 1587
    return config
  },
1588
  webpackDevMiddleware: config => {
1589 1590
    // Perform customizations to webpack dev middleware config
    // Important: return the modified config
1591 1592 1593 1594 1595
    return config
  }
}
```

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

1598 1599 1600 1601 1602 1603
- `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.
1604

1605
Example usage of `defaultLoaders.babel`:
1606 1607

```js
1608
// Example next.config.js for adding a loader that depends on babel-loader
1609 1610
// This source was taken from the @next/mdx plugin source:
// https://github.com/zeit/next.js/tree/canary/packages/next-mdx
1611
module.exports = {
T
Truong Hoang Dung 已提交
1612
  webpack: (config, options) => {
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622
    config.module.rules.push({
      test: /\.mdx/,
      use: [
        options.defaultLoaders.babel,
        {
          loader: '@mdx-js/loader',
          options: pluginOptions.options
        }
      ]
    })
1623 1624 1625

    return config
  }
1626
}
1627 1628
```

1629 1630
### Customizing babel config

S
Shu Ding 已提交
1631
<details>
1632
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
1633
  <ul>
1634
    <li><a href="/examples/with-custom-babel-config">Custom babel configuration</a></li>
S
Shu Ding 已提交
1635 1636 1637
  </ul>
</details>

1638

1639 1640
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.

1641
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.
1642 1643 1644 1645

This is designed so that you are not surprised by modifications we could make to the babel configurations.

Here's an example `.babelrc` file:
1646

1647
```json
1648
{
1649 1650
  "presets": ["next/babel"],
  "plugins": []
G
Guillermo Rauch 已提交
1651 1652 1653
}
```

1654 1655 1656 1657 1658 1659 1660 1661 1662
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

1663
These presets / plugins **should not** be added to your custom `.babelrc`. Instead, you can configure them on the `next/babel` preset:
1664 1665 1666 1667

```json
{
  "presets": [
1668 1669 1670 1671 1672 1673 1674 1675 1676
    [
      "next/babel",
      {
        "preset-env": {},
        "transform-runtime": {},
        "styled-jsx": {},
        "class-properties": {}
      }
    ]
1677 1678 1679 1680 1681 1682 1683
  ],
  "plugins": []
}
```

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

1684
### Exposing configuration to the server / client side
1685

1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
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
1712
function Index() {
1713
  return <h1>The value of customKey is: {process.env.customKey}</h1>
1714
}
1715 1716

export default Index
1717
```
1718 1719
> **Warning:** Note that it is not possible to destructure process.env variables due to the webpack `DefinePlugin` replacing process.env.XXXX inline at build time

M
Mayank Jethva 已提交
1720
```js
1721 1722 1723 1724 1725 1726 1727 1728
// Will not work
const { CUSTOM_KEY, CUSTOM_SECRET } = process.env;
AuthMethod({ key: CUSTOM_KEY, secret: CUSTOM_SECRET });

// Will work as replaced inline
AuthMethod({ key: process.env.CUSTOM_KEY, secret: process.env.CUSTOM_SECRET });
```

1729 1730 1731

#### Runtime configuration

1732
> **Warning:** Note that this option is not available when using `target: 'serverless'`
1733

M
Mayank Jethva 已提交
1734 1735
> **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.
1736

G
Gary Meehan 已提交
1737
The `next/config` module gives your app access to the `publicRuntimeConfig` and `serverRuntimeConfig` stored in your `next.config.js`.
1738 1739 1740 1741

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

Anything accessible to both client and server-side code should be under `publicRuntimeConfig`.
1742 1743 1744 1745

```js
// next.config.js
module.exports = {
1746 1747
  serverRuntimeConfig: {
    // Will only be available on the server side
1748 1749
    mySecret: 'secret',
    secondSecret: process.env.SECOND_SECRET // Pass through env variables
1750
  },
1751 1752 1753
  publicRuntimeConfig: {
    // Will be available on both server and client
    staticFolder: '/static'
1754 1755 1756 1757 1758 1759 1760
  }
}
```

```js
// pages/index.js
import getConfig from 'next/config'
1761
// Only holds serverRuntimeConfig and publicRuntimeConfig from next.config.js nothing else.
1762
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
1763 1764 1765

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

1767 1768 1769 1770 1771 1772 1773 1774 1775
function MyImage() {
  return (
    <div>
      <img src={`${publicRuntimeConfig.staticFolder}/logo.png`} alt="logo" />
    </div>
  )
}

export default MyImage
1776 1777
```

1778 1779 1780 1781
### 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.

1782 1783 1784 1785 1786
### 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 已提交
1787
const isProd = process.env.NODE_ENV === 'production'
1788 1789 1790 1791 1792 1793
module.exports = {
  // You may only need to add assetPrefix in the production.
  assetPrefix: isProd ? 'https://cdn.mydomain.com' : ''
}
```

1794
Note: Next.js will automatically use that prefix in the scripts it loads, but this has no effect whatsoever on `/static` or `/public`. 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-build-time).
1795

1796 1797
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.

1798
```js
1799 1800 1801 1802
// next.config.js
module.exports = {
  crossOrigin: 'anonymous'
}
1803
```
1804

G
Guillermo Rauch 已提交
1805
## Production deployment
G
Guillermo Rauch 已提交
1806

1807
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 已提交
1808

G
Guillermo Rauch 已提交
1809
```bash
G
Guillermo Rauch 已提交
1810 1811 1812 1813
next build
next start
```

1814
To deploy Next.js with [ZEIT Now](https://zeit.co/now) see the [ZEIT Guide for Deploying Next.js with Now](https://zeit.co/guides/deploying-nextjs-with-now/).
G
Guillermo Rauch 已提交
1815

A
Arunoda Susiripala 已提交
1816
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.
1817

1818 1819
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!

1820
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 已提交
1821

1822 1823 1824 1825 1826
### Serverless deployment

<details>
  <summary><b>Examples</b></summary>
  <ul>
1827 1828
    <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>
1829 1830 1831 1832
    <li>We encourage contributing more examples to this section</li>
  </ul>
</details>

1833
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.
1834

1835 1836 1837
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`:
1838 1839 1840 1841

```js
// next.config.js
module.exports = {
1842 1843
  target: 'serverless'
}
1844 1845
```

1846
The `serverless` target will output a single lambda per page. This file is completely standalone and doesn't require any dependencies to run:
1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858

- `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)
1859
- `void` refers to the function not having a return value and is equivalent to JavaScript's `undefined`. Calling the function will finish the request.
1860

1861 1862
Using the serverless target, you can deploy Next.js to [ZEIT Now](https://zeit.co/now) with all of the benefits and added ease of control like for example; [custom routes](https://zeit.co/guides/custom-next-js-server-to-routes/) and caching headers. See the [ZEIT Guide for Deploying Next.js with Now](https://zeit.co/guides/deploying-nextjs-with-now/) for more information.

1863 1864
#### One Level Lower

1865
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 compatibility layer.
1866 1867 1868 1869

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

```js
1870 1871 1872 1873
const http = require('http')
const page = require('./.next/serverless/pages/about.js')
const server = new http.Server((req, res) => page.render(req, res))
server.listen(3000, () => console.log('Listening on http://localhost:3000'))
1874 1875 1876 1877
```

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

1878
#### Summary
1879

1880 1881 1882 1883
- 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
1884 1885 1886 1887 1888
- 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

1889 1890
## Browser support

1891
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.
1892 1893 1894

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

1895 1896 1897 1898
## TypeScript

TypeScript is supported out of the box in Next.js. To get started using it create a `tsconfig.json` in your project:

1899
```js
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951
{
  "compilerOptions": {
    "allowJs": true, /* Allow JavaScript files to be type checked. */
    "alwaysStrict": true, /* Parse in strict mode. */
    "esModuleInterop": true, /* matches compilation setting */
    "isolatedModules": true, /* to match webpack loader */
    "jsx": "preserve", /* Preserves jsx outside of Next.js. */
    "lib": ["dom", "es2017"], /* List of library files to be included in the type checking. */
    "module": "esnext", /* Specifies the type of module to type check. */
    "moduleResolution": "node", /* Determine how modules get resolved. */
    "noEmit": true, /* Do not emit outputs. Makes sure tsc only does type checking. */

    /* Strict Type-Checking Options, optional, but recommended. */
    "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
    "noUnusedLocals": true, /* Report errors on unused locals. */
    "noUnusedParameters": true, /* Report errors on unused parameters. */
    "strict": true /* Enable all strict type-checking options. */,
    "target": "esnext" /* The type checking input. */
  }
}
```

After adding the `tsconfig.json` you need to install `@types` to get proper TypeScript typing.

```bash
npm install --save-dev @types/react @types/react-dom @types/node
```

Now can change any file from `.js` to `.ts` / `.tsx` (tsx is for files using JSX). To learn more about TypeScript checkout out its [documentation](https://www.typescriptlang.org/).

### Exported types

Next.js provides `NextPage` type that can be used for pages in the `pages` directory. `NextPage` adds definitions for [`getInitialProps`](#fetching-data-and-component-lifecycle) so that it can be used without any extra typing needed.

```tsx
import { NextPage } from 'next'

interface Props {
  pathname: string
}

const Page: NextPage<Props> = ({ pathname }) => (
  <main>Your request pathname: {pathname}</main>
)

Page.getInitialProps = async ({ pathname }) => {
  return { pathname }
}

export default Page
```

J
JJ Kasper 已提交
1952 1953 1954 1955 1956 1957
## AMP Support

### Enabling AMP Support

To enable AMP support for a page, first enable experimental AMP support in your `next.config.js` and then import `withAmp` from `next/amp` and wrap your page's component in it.

J
JJ Kasper 已提交
1958
### AMP First Page
J
JJ Kasper 已提交
1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
```js
// pages/about.js
import { withAmp } from 'next/amp'

export default withAmp(function AboutPage(props) {
  return (
    <h3>My AMP About Page!</h3>
  )
})
```

J
JJ Kasper 已提交
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999
### Hybrid AMP Page
```js
// pages/hybrid-about.js
import { withAmp, useAmp } from 'next/amp'

export default withAmp(function AboutPage(props) {
  return (
    <div>
      <h3>My AMP Page</h3>
      {useAmp() ? (
        <amp-img
          width='300'
          height='300'
          src='/my-img.jpg'
          alt='a cool image'
          layout='responsive'
        />
      ) : (
        <img
          width='300'
          height='300'
          src='/my-img.jpg'
          alt='a cool image'
        />
      )}
    </div>
  )
}, { hybrid: true })
```

J
JJ Kasper 已提交
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
### AMP Page Modes

AMP pages can specify two modes:

- AMP-only (default)
    - Pages have no Next.js or React client-side runtime
    - Pages are automatically optimized with [AMP Optimizer](https://github.com/ampproject/amp-toolbox/tree/master/packages/optimizer), an optimizer that applies the same transformations as AMP caches (improves performance by up to 42%)
    - Pages have a user-accessible (optimized) version of the page and a search-engine indexable (unoptimized) version of the page
    - Opt-in via `withAmp(Component)`
- Hybrid
    - Pages are able to be rendered as traditional HTML (default) and AMP HTML (by adding `?amp=1` to the URL)
J
JJ Kasper 已提交
2011
    - The AMP version of the page only has valid optimizations applied with AMP Optimizer so that it is indexable by search-engines
J
JJ Kasper 已提交
2012
    - Opt-in via `withAmp(Component, { hybrid: true })`
J
JJ Kasper 已提交
2013
    - Able to differentiate between modes using `useAmp` from `next/amp`
J
JJ Kasper 已提交
2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030

Both of these page modes provide a consistently fast experience for users accessing pages through search engines.

### AMP Behavior with `next export`

When using `next export` to statically pre-render pages Next.js will detect if the page supports AMP and change the exporting behavior based on that.

Hybrid AMP (`pages/about.js`) would output:

- `out/about/index.html` - with client-side React runtime
- `out/about.amp/index.html` - AMP page

AMP-only (`pages/about.js`) would output:

- `out/about/index.html` - Optimized AMP page
- `out/about.amp/index.html` - AMP page

2031
During export Next.js automatically detects if a page is AMP-only and apply dirty/clean optimizations. The dirty version will be output to `page/index.html` and the clean version will be output to `page.amp/index.html`. We also automatically insert the `<link rel="amphtml" href="/page.amp" />` and `<link rel="canonical" href="/" />` tags for you.
J
JJ Kasper 已提交
2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074

### Adding AMP Components

The AMP community provides [many components](https://amp.dev/documentation/components/) to make AMP pages more interactive. You can add these components to your page by using `next/head`:

```js
// pages/hello.js
import Head from 'next/head'
import { withAmp } from 'next/amp'

export default withAmp(function MyAmpPage() {
  return (
    <div>
      <Head>
        <script
          async
          key="amp-timeago"
          custom-element="amp-timeago"
          src="https://cdn.ampproject.org/v0/amp-timeago-0.1.js"
        />
      </Head>

      <p>Some time: {date.toJSON()}</p>
      <amp-timeago
        width="0"
        height="15"
        datetime={date.toJSON()}
        layout="responsive"
      >
        .
      </amp-timeago>
    </div>
  )
})
```

### AMP Validation

AMP pages are automatically validated with [amphtml-validator](https://www.npmjs.com/package/amphtml-validator) during development. Errors and warnings will appear in the terminal where you started Next.js.

Pages are also validated during `next export` and any warnings / errors will be printed to the terminal.
Any AMP errors will cause `next export` to exit with status code `1` because the export is not valid AMP.

A
Arunoda Susiripala 已提交
2075 2076
## Static HTML export

S
Shu Ding 已提交
2077
<details>
2078
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
2079
  <ul>
2080
    <li><a href="/examples/with-static-export">Static export</a></li>
S
Shu Ding 已提交
2081 2082 2083
  </ul>
</details>

2084

2085 2086 2087 2088 2089 2090 2091 2092 2093 2094
`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 已提交
2095 2096
### Usage

2097 2098 2099 2100 2101 2102 2103
Simply develop your app as you normally do with Next.js. Then run:

```
next build
next export
```

2104
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.
2105 2106 2107

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 已提交
2108 2109 2110 2111

```js
// next.config.js
module.exports = {
2112
  exportPathMap: async function(defaultPathMap) {
A
Arunoda Susiripala 已提交
2113
    return {
2114 2115
      '/': { page: '/' },
      '/about': { page: '/about' },
2116
      '/readme.md': { page: '/readme' },
2117 2118 2119
      '/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 已提交
2120
    }
2121
  }
A
Arunoda Susiripala 已提交
2122 2123 2124
}
```

2125 2126
> 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 已提交
2127 2128
Then simply run these commands:

S
Shu Ding 已提交
2129
```bash
A
Arunoda Susiripala 已提交
2130 2131 2132 2133 2134 2135 2136 2137
next build
next export
```

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

```json
{
2138
  "scripts": {
2139 2140
    "build": "next build",
    "export": "npm run build && next export"
2141
  }
A
Arunoda Susiripala 已提交
2142 2143 2144 2145 2146
}
```

And run it at once with:

S
Shu Ding 已提交
2147
```bash
2148
npm run export
A
Arunoda Susiripala 已提交
2149 2150
```

2151
Then you have a static version of your app in the `out` directory.
A
Arunoda Susiripala 已提交
2152 2153 2154

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

2155
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 已提交
2156

2157
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 已提交
2158

S
Shu Ding 已提交
2159
```bash
A
Arunoda Susiripala 已提交
2160 2161 2162
now
```

2163 2164 2165
### 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`.
2166
`exportPathMap` gets a few contextual parameter to aid you with creating/copying files:
2167 2168 2169 2170 2171 2172 2173 2174 2175 2176

- `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')
2177 2178
const { join } = require('path')
const { promisify } = require('util')
2179 2180 2181
const copyFile = promisify(fs.copyFile)

module.exports = {
2182 2183 2184 2185
  exportPathMap: async function(
    defaultPathMap,
    { dev, dir, outDir, distDir, buildId }
  ) {
2186 2187 2188 2189 2190 2191 2192 2193 2194 2195
    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 已提交
2196 2197
### Limitation

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

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

2202
> 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 已提交
2203

2204 2205
## Multi Zones

S
Shu Ding 已提交
2206
<details>
2207
  <summary><b>Examples</b></summary>
S
Shu Ding 已提交
2208
  <ul>
2209
    <li><a href="/examples/with-zones">With Zones</a></li>
S
Shu Ding 已提交
2210 2211 2212
  </ul>
</details>

2213 2214 2215 2216 2217

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:

2218 2219
- https://docs.my-app.com for serving `/docs/**`
- https://ui.my-app.com for serving all other pages
2220 2221 2222 2223 2224 2225 2226 2227 2228

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:

2229 2230
- 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).)
2231 2232 2233 2234 2235 2236 2237 2238 2239 2240

### 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": [
2241 2242 2243 2244 2245 2246
    {
      "pathname": "/docs**",
      "method": ["GET", "POST", "OPTIONS"],
      "dest": "https://docs.my-app.com"
    },
    { "pathname": "/**", "dest": "https://ui.my-app.com" }
2247 2248 2249 2250
  ]
}
```

2251
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.
2252

2253 2254 2255
## Recipes

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

G
Guillermo Rauch 已提交
2260
## FAQ
G
Guillermo Rauch 已提交
2261

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

2266 2267
We’re ecstatic about both the developer experience and end-user performance, so we decided to share it with the community.

G
Guillermo Rauch 已提交
2268
</details>
G
Guillermo Rauch 已提交
2269

S
Shu Ding 已提交
2270

G
Guillermo Rauch 已提交
2271 2272 2273
<details>
  <summary>How big is it?</summary>

2274 2275
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 已提交
2276 2277 2278

</details>

S
Shu Ding 已提交
2279

G
Guillermo Rauch 已提交
2280 2281
<details>
  <summary>Is this like `create-react-app`?</summary>
D
Dan Zajdband 已提交
2282

G
Guillermo Rauch 已提交
2283 2284 2285 2286 2287
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:
2288

G
Guillermo Rauch 已提交
2289 2290
- Server side rendering
- Automatic code splitting
G
Guillermo Rauch 已提交
2291 2292

In addition, Next.js provides two built-in features that are critical for every single website:
2293

2294
- Routing with lazy component loading: `<Link>` (by importing `next/link`)
G
Guillermo Rauch 已提交
2295
- A way for components to alter `<head>`: `<Head>` (by importing `next/head`)
G
Guillermo Rauch 已提交
2296

G
Guillermo Rauch 已提交
2297
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 已提交
2298 2299 2300

</details>

S
Shu Ding 已提交
2301

G
Guillermo Rauch 已提交
2302
<details>
G
Guillermo Rauch 已提交
2303
  <summary>How do I use CSS-in-JS solutions?</summary>
G
Guillermo Rauch 已提交
2304

T
Tim Neutkens 已提交
2305
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.
2306

G
Guillermo Rauch 已提交
2307 2308
</details>

S
Shu Ding 已提交
2309

G
Guillermo Rauch 已提交
2310 2311 2312 2313 2314
<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.

2315
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 已提交
2316 2317 2318

</details>

S
Shu Ding 已提交
2319

G
Guillermo Rauch 已提交
2320 2321 2322 2323 2324 2325
<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 已提交
2326
- Routes are always lazy-loadable
G
Guillermo Rauch 已提交
2327 2328 2329 2330 2331 2332 2333 2334 2335
- 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

</details>

S
Shu Ding 已提交
2336

G
Guillermo Rauch 已提交
2337 2338 2339
<details>
<summary>How do I define a custom fancy route?</summary>

2340
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 已提交
2341

2342
On the client side, we have a parameter call `as` on `<Link>` that _decorates_ the URL differently from the URL it _fetches_.
2343

G
Guillermo Rauch 已提交
2344 2345
</details>

S
Shu Ding 已提交
2346

G
Guillermo Rauch 已提交
2347 2348 2349 2350
<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.
2351

G
Guillermo Rauch 已提交
2352 2353
</details>

S
Shu Ding 已提交
2354

A
Adam Soffer 已提交
2355 2356 2357
<details>
  <summary>Can I use it with GraphQL?</summary>

2358
Yes! Here's an example with [Apollo](/examples/with-apollo).
A
Adam Soffer 已提交
2359 2360 2361

</details>

S
Shu Ding 已提交
2362

2363 2364 2365 2366 2367 2368 2369 2370
<details>
<summary>Can I use it with Redux and thunk?</summary>

Yes! Here's an [example](/examples/with-redux-thunk)

</details>


G
Guillermo Rauch 已提交
2371 2372 2373
<details>
<summary>Can I use it with Redux?</summary>

2374
Yes! Here's an [example](/examples/with-redux)
2375

G
Guillermo Rauch 已提交
2376 2377
</details>

S
Shu Ding 已提交
2378

T
Tim Neutkens 已提交
2379 2380 2381
<details>
<summary>Can I use Next with my favorite Javascript library or toolkit?</summary>

2382
Since our first release we've had **many** example contributions, you can check them out in the [examples](/examples) directory
2383

T
Tim Neutkens 已提交
2384 2385
</details>

S
Shu Ding 已提交
2386

G
Guillermo Rauch 已提交
2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399
<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 已提交
2400

T
Tim Neutkens 已提交
2401 2402
## Contributing

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

G
Guillermo Rauch 已提交
2405 2406
## Authors

2407
- Arunoda Susiripala ([@arunoda](https://twitter.com/arunoda)) – [ZEIT](https://zeit.co)
2408
- Tim Neutkens ([@timneutkens](https://twitter.com/timneutkens)) – [ZEIT](https://zeit.co)
2409 2410 2411
- 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 已提交
2412
- Dan Zajdband ([@impronunciable](https://twitter.com/impronunciable)) – Knight-Mozilla / Coral Project