The value of customKey is: {process.env.customKey}
-}
-
-export default Index
-```
-
-#### 运行时配置
-
-> ⚠️ 请注意,使用此选项时不可用 `target: 'serverless'`
-
-> ⚠️ 通常,您希望使用构建时配置来提供配置。原因是运行时配置增加了一个小的rendering/initialization开销。
-
-`next/config`模块使你应用运行时可以读取些存储在`next.config.js`的配置项。`serverRuntimeConfig`属性只在服务器端可用,`publicRuntimeConfig`属性在服务端和客户端可用。
-
-```js
-// next.config.js
-module.exports = {
- serverRuntimeConfig: {
- // Will only be available on the server side
- mySecret: 'secret',
- secondSecret: process.env.SECOND_SECRET // Pass through env variables
- },
- publicRuntimeConfig: {
- // Will be available on both server and client
- staticFolder: '/static'
- }
-}
-```
-
-```js
-// pages/index.js
-import getConfig from 'next/config'
-// Only holds serverRuntimeConfig and publicRuntimeConfig from next.config.js nothing else.
-const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
-
-console.log(serverRuntimeConfig.mySecret) // Will only be available on the server side
-console.log(publicRuntimeConfig.staticFolder) // Will be available on both server and client
-
-function MyImage() {
- return (
-
diff --git a/bench/readdir/glob.js b/bench/readdir/glob.js
index b871f0779d6951..1c409ad384ba50 100644
--- a/bench/readdir/glob.js
+++ b/bench/readdir/glob.js
@@ -4,17 +4,17 @@ const globMod = require('glob')
const glob = promisify(globMod)
const resolveDataDir = join(__dirname, 'fixtures', '**/*')
-async function test () {
+async function test() {
const time = process.hrtime()
await glob(resolveDataDir)
const hrtime = process.hrtime(time)
- const nanoseconds = (hrtime[0] * 1e9) + hrtime[1]
+ const nanoseconds = hrtime[0] * 1e9 + hrtime[1]
const milliseconds = nanoseconds / 1e6
console.log(milliseconds)
}
-async function run () {
+async function run() {
for (let i = 0; i < 50; i++) {
await test()
}
diff --git a/bench/readdir/recursive-readdir.js b/bench/readdir/recursive-readdir.js
index 43877bb73a0b70..871256707ddb6f 100644
--- a/bench/readdir/recursive-readdir.js
+++ b/bench/readdir/recursive-readdir.js
@@ -2,17 +2,17 @@ const { join } = require('path')
const { recursiveReadDir } = require('next/dist/lib/recursive-readdir')
const resolveDataDir = join(__dirname, 'fixtures')
-async function test () {
+async function test() {
const time = process.hrtime()
await recursiveReadDir(resolveDataDir, /\.js$/)
const hrtime = process.hrtime(time)
- const nanoseconds = (hrtime[0] * 1e9) + hrtime[1]
+ const nanoseconds = hrtime[0] * 1e9 + hrtime[1]
const milliseconds = nanoseconds / 1e6
console.log(milliseconds)
}
-async function run () {
+async function run() {
for (let i = 0; i < 50; i++) {
await test()
}
diff --git a/bench/readme.md b/bench/readme.md
index 0ac01e4b1b4265..71c7070d8f691c 100644
--- a/bench/readme.md
+++ b/bench/readme.md
@@ -17,11 +17,13 @@ npm run start
Then run one of these tests:
- Stateless application which renders `
My component!
`. Runs 3000 http requests.
+
```
npm run bench:stateless
```
- Stateless application which renders `
This is row {i}
` 10.000 times. Runs 500 http requests.
+
```
npm run bench:stateless-big
```
diff --git a/bench/recursive-copy/run.js b/bench/recursive-copy/run.js
new file mode 100644
index 00000000000000..adff8be65aa42c
--- /dev/null
+++ b/bench/recursive-copy/run.js
@@ -0,0 +1,63 @@
+const { join } = require('path')
+const fs = require('fs-extra')
+
+const recursiveCopyNpm = require('recursive-copy')
+
+const {
+ recursiveCopy: recursiveCopyCustom,
+} = require('next/dist/lib/recursive-copy')
+
+const fixturesDir = join(__dirname, 'fixtures')
+const srcDir = join(fixturesDir, 'src')
+const destDir = join(fixturesDir, 'dest')
+
+const createSrcFolder = async () => {
+ await fs.ensureDir(srcDir)
+
+ const files = new Array(100)
+ .fill(undefined)
+ .map((x, i) =>
+ join(srcDir, `folder${i % 5}`, `folder${i + (1 % 5)}`, `file${i}`)
+ )
+
+ await Promise.all(files.map(file => fs.outputFile(file, 'hello')))
+}
+
+async function run(fn) {
+ async function test() {
+ const start = process.hrtime()
+
+ await fn(srcDir, destDir)
+
+ const timer = process.hrtime(start)
+ const ms = (timer[0] * 1e9 + timer[1]) / 1e6
+ return ms
+ }
+
+ const ts = []
+
+ for (let i = 0; i < 10; i++) {
+ const t = await test()
+ await fs.remove(destDir)
+ ts.push(t)
+ }
+
+ const sum = ts.reduce((a, b) => a + b)
+ const nb = ts.length
+ const avg = sum / nb
+ console.log({ sum, nb, avg })
+}
+
+async function main() {
+ await createSrcFolder()
+
+ console.log('test recursive-copy npm module')
+ await run(recursiveCopyNpm)
+
+ console.log('test recursive-copy custom implementation')
+ await run(recursiveCopyCustom)
+
+ await fs.remove(fixturesDir)
+}
+
+main()
diff --git a/bench/recursive-delete/recursive-delete.js b/bench/recursive-delete/recursive-delete.js
index 8b43044e396d41..8989739c9039f1 100644
--- a/bench/recursive-delete/recursive-delete.js
+++ b/bench/recursive-delete/recursive-delete.js
@@ -2,12 +2,12 @@ const { join } = require('path')
const { recursiveDelete } = require('next/dist/lib/recursive-delete')
const resolveDataDir = join(__dirname, `fixtures-${process.argv[2]}`)
-async function test () {
+async function test() {
const time = process.hrtime()
await recursiveDelete(resolveDataDir)
const hrtime = process.hrtime(time)
- const nanoseconds = (hrtime[0] * 1e9) + hrtime[1]
+ const nanoseconds = hrtime[0] * 1e9 + hrtime[1]
const milliseconds = nanoseconds / 1e6
console.log(milliseconds)
}
diff --git a/bench/recursive-delete/rimraf.js b/bench/recursive-delete/rimraf.js
index d3163afc970061..2b5d50457a13c8 100644
--- a/bench/recursive-delete/rimraf.js
+++ b/bench/recursive-delete/rimraf.js
@@ -4,12 +4,12 @@ const rimrafMod = require('rimraf')
const resolveDataDir = join(__dirname, `fixtures-${process.argv[2]}`, '**/*')
const rimraf = promisify(rimrafMod)
-async function test () {
+async function test() {
const time = process.hrtime()
await rimraf(resolveDataDir)
const hrtime = process.hrtime(time)
- const nanoseconds = (hrtime[0] * 1e9) + hrtime[1]
+ const nanoseconds = hrtime[0] * 1e9 + hrtime[1]
const milliseconds = nanoseconds / 1e6
console.log(milliseconds)
}
diff --git a/contributing.md b/contributing.md
index 2d9a0da2ddde64..907253d4ba24c8 100644
--- a/contributing.md
+++ b/contributing.md
@@ -3,52 +3,169 @@
Our Commitment to Open Source can be found [here](https://zeit.co/blog/oss)
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device.
-1. Install yarn: `npm install -g yarn`
-1. Install the dependencies: `yarn`
-1. Run `yarn run dev` to build and watch for code changes
+2. Create a new branch `git checkout -b MY_BRANCH_NAME`
+3. Install yarn: `npm install -g yarn`
+4. Install the dependencies: `yarn`
+5. Run `yarn dev` to build and watch for code changes
+6. In a new terminal, run `yarn types` to compile declaration files from TypeScript
+7. The development branch is `canary` (this is the branch pull requests should be made against). On a release, the relevant parts of the changes in the `canary` branch are rebased into `master`.
+
+> You may need to run `yarn types` again if your types get outdated.
+
+To contribute to [our examples](examples), take a look at the [“Adding examples” section](#adding-examples).
## To run tests
+Make sure you have `chromedriver` installed for your Chrome version. You can install it with
+
+- `brew cask install chromedriver` on Mac OS X
+- `chocolatey install chromedriver` on Windows
+- Or manually downloading it from the [chromedriver repo](https://chromedriver.storage.googleapis.com/index.html) and adding the binary to `/node_modules/.bin`
+
Running all tests:
-```
+```sh
yarn testonly
```
-Running a specific test suite inside of the `test/integration` directory:
+If you would like to run the tests in headless mode (with the browser windows hidden) you can do
+```sh
+yarn testheadless
```
+
+If you would like to use a specific Chrome/Chromium binary to run tests you can specify it with
+
+```sh
+CHROME_BIN='path/to/chrome/bin' yarn testonly
+```
+
+Running a specific test suite inside of the `test/integration` directory:
+
+```sh
yarn testonly --testPathPattern "production"
```
Running just one test in the `production` test suite:
-```
+```sh
yarn testonly --testPathPattern "production" -t "should allow etag header support"
```
-## Running the integration test apps without running tests
+## Running the integration apps
+
+Running examples can be done with:
+```sh
+yarn next ./test/integration/basic
+# OR
+yarn next ./examples/basic-css/
```
-./node_modules/.bin/next ./test/integration/basic
+
+To figure out which pages are available for the given example, you can run:
+
+```sh
+EXAMPLE=./test/integration/basic
+(\
+ cd $EXAMPLE/pages; \
+ find . -type f \
+ | grep -v '\.next' \
+ | sed 's#^\.##' \
+ | sed 's#index\.js##' \
+ | sed 's#\.js$##' \
+ | xargs -I{} echo localhost:3000{} \
+)
```
-## Testing in your own app
+## Running your own app with locally compiled version of Next.js
-Because of the way Node.js resolves modules the easiest way to test your own application is copying it into the `test` directory.
+1. In your app's `package.json`, replace:
-```
-cp -r yourapp /test/integration/yourapp
-```
+ ```json
+ "next": "",
+ ```
+
+ with:
+
+ ```json
+ "next": "file:/packages/next",
+ ```
+
+2. In your app's root directory, make sure to remove `next` from `node_modules` with:
+
+ ```sh
+ rm -rf ./node_modules/next
+ ```
+
+3. In your app's root directory, run:
-Make sure you remove `react` `react-dom` and `next` from `test/integration/yourapp/node_modules` as otherwise they will be overwritten.
+ ```sh
+ yarn
+ ```
+
+ to re-install all of the dependencies.
+
+ Note that Next will be copied from the locally compiled version as opposed to from being downloaded from the NPM registry.
+
+4. Run your application as you normally would.
+
+5. To update your app's dependencies, after you've made changes to your local `next` repository. In your app's root directory, run:
+
+ ```sh
+ yarn install --force
+ ```
+
+## Adding examples
+
+When you add an example to the [examples](examples) directory, don’t forget to add a `README.md` file with the following format:
+
+- Replace `DIRECTORY_NAME` with the directory name you’re adding.
+- Fill in `Example Name` and `Description`.
+- To add additional installation instructions, please add it where appropriate.
+- To add additional notes, add `## Notes` section at the end.
+- Remove the `Deploy your own` section if your example can’t be immediately deployed to ZEIT Now.
+
+````markdown
+# Example Name
+
+Description
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/DIRECTORY_NAME)
+
+## How to use
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
-rm -rf /test/integration/yourapp/{react,react-dom,next,next-server}
+npx create-next-app --example DIRECTORY_NAME DIRECTORY_NAME-app
+# or
+yarn create next-app --example DIRECTORY_NAME DIRECTORY_NAME-app
```
-Then run your app using:
+### Download manually
+
+Download the example:
+```bash
+curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/DIRECTORY_NAME
+cd DIRECTORY_NAME
```
-./node_modules/.bin/next ./test/integration/yourapp
+
+Install it and run:
+
+```bash
+npm install
+npm run dev
+# or
+yarn
+yarn dev
```
+
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
+````
diff --git a/docs/advanced-features/amp-support/adding-amp-components.md b/docs/advanced-features/amp-support/adding-amp-components.md
new file mode 100644
index 00000000000000..63305791d54488
--- /dev/null
+++ b/docs/advanced-features/amp-support/adding-amp-components.md
@@ -0,0 +1,70 @@
+---
+description: Add components from the AMP community to AMP pages, and make your pages more interactive.
+---
+
+# Adding AMP Components
+
+The AMP community provides [many components](https://amp.dev/documentation/components/) to make AMP pages more interactive. Next.js will automatically import all components used on a page and there is no need to manually import AMP component scripts:
+
+```jsx
+export const config = { amp: true }
+
+function MyAmpPage() {
+ const date = new Date()
+
+ return (
+
+
Some time: {date.toJSON()}
+
+ .
+
+
+ )
+}
+
+export default MyAmpPage
+```
+
+The above example uses the [`amp-timeago`](https://amp.dev/documentation/components/amp-timeago/?format=websites) component.
+
+By default, the latest version of a component is always imported. If you want to customize the version, you can use `next/head`, as in the following example:
+
+```jsx
+import Head from 'next/head'
+
+export const config = { amp: true }
+
+function MyAmpPage() {
+ const date = new Date()
+
+ return (
+
+
+
+
+
+
Some time: {date.toJSON()}
+
+ .
+
+
+ )
+}
+
+export default MyAmpPage
+```
diff --git a/docs/advanced-features/amp-support/amp-in-static-html-export.md b/docs/advanced-features/amp-support/amp-in-static-html-export.md
new file mode 100644
index 00000000000000..dfa3afbc41f309
--- /dev/null
+++ b/docs/advanced-features/amp-support/amp-in-static-html-export.md
@@ -0,0 +1,33 @@
+---
+description: Learn how AMP pages are created when used together with `next export`.
+---
+
+# AMP in Static HTML export
+
+When using `next export` to do [Static HTML export](/docs/advanced-features/static-html-export.md) statically prerender pages, Next.js will detect if the page supports AMP and change the exporting behavior based on that.
+
+For example, the hybrid AMP page `pages/about.js` would output:
+
+- `out/about.html` - HTML page with client-side React runtime
+- `out/about.amp.html` - AMP page
+
+And if `pages/about.js` is an AMP-only page, then it would output:
+
+- `out/about.html` - Optimized AMP page
+
+Next.js will automatically insert a link to the AMP version of your page in the HTML version, so you don't have to, like so:
+
+```jsx
+
+```
+
+And the AMP version of your page will include a link to the HTML page:
+
+```jsx
+
+```
+
+When [`exportTrailingSlash`](/docs/api-reference/next.config.js/exportPathMap.md#0cf7d6666b394c5d8d08a16a933e86ea) is enabled the exported pages for `pages/about.js` would be:
+
+- `out/about/index.html` - HTML page
+- `out/about.amp/index.html` - AMP page
diff --git a/docs/advanced-features/amp-support/amp-validation.md b/docs/advanced-features/amp-support/amp-validation.md
new file mode 100644
index 00000000000000..85902433071233
--- /dev/null
+++ b/docs/advanced-features/amp-support/amp-validation.md
@@ -0,0 +1,9 @@
+---
+description: AMP pages are automatically validated by Next.js during development and on build. Learn more about it here.
+---
+
+# 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 [Static HTML export](/docs/advanced-features/static-html-export.md) and any warnings / errors will be printed to the terminal. Any AMP errors will cause the export to exit with status code `1` because the export is not valid AMP.
diff --git a/docs/advanced-features/amp-support/introduction.md b/docs/advanced-features/amp-support/introduction.md
new file mode 100644
index 00000000000000..89ca03b4b3c00a
--- /dev/null
+++ b/docs/advanced-features/amp-support/introduction.md
@@ -0,0 +1,42 @@
+---
+description: With minimal config, and without leaving React, you can start adding AMP and improve the performance and speed of your pages.
+---
+
+# AMP Support
+
+
+ Examples
+
+
+
+With Next.js you can turn any React page into an AMP page, with minimal config, and without leaving React.
+
+You can read more about AMP in the official [amp.dev](https://amp.dev/) site.
+
+## Enabling AMP
+
+To enable AMP support for a page, and to learn more about the different AMP configs, read the [API documentation for `next/amp`](/docs/api-reference/next/amp.md).
+
+## Caveats
+
+- Only CSS-in-JS is supported. [CSS Modules](/docs/basic-features/built-in-css-support.md) aren't supported by AMP pages at the moment. You can [contribute CSS Modules support to Next.js](https://github.com/zeit/next.js/issues/10549).
+
+## Related
+
+For more information on what to do next, we recommend the following sections:
+
+
diff --git a/docs/advanced-features/amp-support/typescript.md b/docs/advanced-features/amp-support/typescript.md
new file mode 100644
index 00000000000000..273c943d94920f
--- /dev/null
+++ b/docs/advanced-features/amp-support/typescript.md
@@ -0,0 +1,9 @@
+---
+description: Using AMP with TypeScript? Extend your typings to allow AMP components.
+---
+
+# TypeScript
+
+AMP currently doesn't have built-in types for TypeScript, but it's in their roadmap ([#13791](https://github.com/ampproject/amphtml/issues/13791)).
+
+As a workaround you can manually create a file called `amp.d.ts` inside your project and add the custom types described [here](https://stackoverflow.com/a/50601125).
diff --git a/docs/advanced-features/automatic-static-optimization.md b/docs/advanced-features/automatic-static-optimization.md
new file mode 100644
index 00000000000000..2d295849102562
--- /dev/null
+++ b/docs/advanced-features/automatic-static-optimization.md
@@ -0,0 +1,38 @@
+---
+description: Next.js automatically optimizes your app to be static HTML whenever possible. Learn how it works here.
+---
+
+# Automatic Static Optimization
+
+Next.js automatically determines that a page is static (can be prerendered) if it has no blocking data requirements. This determination is made by the absence of `getInitialProps` in the page.
+
+This feature allows Next.js to emit hybrid applications that contain **both server-rendered and statically generated pages**.
+
+> Statically generated pages are still reactive: Next.js will hydrate your application client-side to give it full interactivity.
+
+One of the main benefits of this feature is that optimized pages require no server-side computation, and can be instantly streamed to the end-user from multiple CDN locations. The result is an _ultra fast_ loading experience for your users.
+
+## How it works
+
+If `getInitialProps` is present, Next.js will use its default behavior and render the page on-demand, per-request (meaning Server-Side Rendering).
+
+If `getInitialProps` is absent, Next.js will **statically optimize** your page automatically by prerendering the page to static HTML. During prerendering, the router's `query` object will be empty since we do not have `query` information to provide during this phase. Any `query` values will be populated client-side after hydration.
+
+`next build` will emit `.html` files for statically optimized pages. For example, the result for the page `pages/about.js` would be:
+
+```bash
+.next/server/static/${BUILD_ID}/about.html
+```
+
+And if you add `getInitialProps` to the page, it will then be JavaScript, like so:
+
+```bash
+.next/server/static/${BUILD_ID}/about.js
+```
+
+In development you'll know if `pages/about.js` is optimized or not thanks to the included [static optimization indicator](/docs/api-reference/next.config.js/static-optimization-indicator.md).
+
+## Caveats
+
+- If you have a [custom `App`](/docs/advanced-features/custom-app.md) with `getInitialProps` then this optimization will be disabled for all pages.
+- If you have a [custom `Document`](/docs/advanced-features/custom-document.md) with `getInitialProps` be sure you check if `ctx.req` is defined before assuming the page is server-side rendered. `ctx.req` will be `undefined` for pages that are prerendered.
diff --git a/docs/advanced-features/custom-app.md b/docs/advanced-features/custom-app.md
new file mode 100644
index 00000000000000..1eba8e6fec1c71
--- /dev/null
+++ b/docs/advanced-features/custom-app.md
@@ -0,0 +1,65 @@
+---
+description: Control page initialization and add a layout that persists for all pages by overriding the default App component used by Next.js.
+---
+
+# Custom `App`
+
+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:
+
+- Persisting layout between page changes
+- Keeping state when navigating pages
+- Custom error handling using `componentDidCatch`
+- Inject additional data into pages
+- [Add global CSS](/docs/basic-features/built-in-css-support#adding-a-global-stylesheet)
+
+To override the default `App`, create the file `./pages/_app.js` as shown below:
+
+```jsx
+// import App from 'next/app'
+
+function MyApp({ Component, pageProps }) {
+ return
+}
+
+// Only uncomment this method if you have blocking data requirements for
+// every single page in your application. This disables the ability to
+// perform automatic static optimization, causing every page in your app to
+// be server-side rendered.
+//
+// MyApp.getInitialProps = async (appContext) => {
+// // calls page's `getInitialProps` and fills `appProps.pageProps`
+// const appProps = await App.getInitialProps(appContext);
+//
+// return { ...appProps }
+// }
+
+export default MyApp
+```
+
+The `Component` prop is the active `page`, so whenever you navigate between routes, `Component` will change to the new `page`. Therefore, any props you send to `Component` will be received by the `page`.
+
+`pageProps` is an object with the initial props that were preloaded for your page, it's an empty object if the page is not using [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md).
+
+> Adding a custom `getInitialProps` in your `App` will disable [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).
+
+### TypeScript
+
+If you’re using TypeScript, take a look at [our TypeScript documentation](/docs/basic-features/typescript#custom-app).
+
+## Related
+
+For more information on what to do next, we recommend the following sections:
+
+
diff --git a/docs/advanced-features/custom-document.md b/docs/advanced-features/custom-document.md
new file mode 100644
index 00000000000000..8af080e719d695
--- /dev/null
+++ b/docs/advanced-features/custom-document.md
@@ -0,0 +1,86 @@
+---
+description: Extend the default document markup added by Next.js.
+---
+
+# Custom `Document`
+
+A custom `Document` is commonly used to augment your application's `` and `` tags. This is necessary because Next.js pages skip the definition of the surrounding document's markup.
+
+A custom `Document` can also include `getInitialProps` for expressing asynchronous server-rendering data requirements.
+
+To override the default `Document`, create the file `./pages/_document.js` and extend the `Document` class as shown below:
+
+```jsx
+import Document, { Html, Head, Main, NextScript } from 'next/document'
+
+class MyDocument extends Document {
+ static async getInitialProps(ctx) {
+ const initialProps = await Document.getInitialProps(ctx)
+ return { ...initialProps }
+ }
+
+ render() {
+ return (
+
+
+
+
+
+
+
+ )
+ }
+}
+
+export default MyDocument
+```
+
+``, ``, `` and `` are required for the page to be properly rendered.
+
+Custom attributes are allowed as props, like `lang`:
+
+```jsx
+
+```
+
+The `ctx` object is equivalent to the one received in [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md#context-object), with one addition:
+
+- `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)
+
+## Caveats
+
+- `Document` is only rendered in the server, event handlers like `onClick` won't work
+- React components outside of `` will not be initialized 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`](/docs/advanced-features/custom-app.md) component instead
+- `Document`'s `getInitialProps` function is not called during client-side transitions, nor when a page is [statically optimized](/docs/advanced-features/automatic-static-optimization.md)
+- Make sure to check if `ctx.req` / `ctx.res` are defined in `getInitialProps`. Those variables will be `undefined` when a page is being statically exported by [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) or by [`next export`](/docs/advanced-features/static-html-export.md)
+
+## Customizing `renderPage`
+
+> It should be noted that the only reason you should be customizing `renderPage` is for usage with **css-in-js** libraries that need to wrap the application to properly work with server-side rendering.
+
+It takes as argument an options object for further customization:
+
+```jsx
+import Document from 'next/document'
+
+class MyDocument extends Document {
+ static async getInitialProps(ctx) {
+ const originalRenderPage = ctx.renderPage
+
+ ctx.renderPage = () =>
+ originalRenderPage({
+ // useful for wrapping the whole react tree
+ enhanceApp: App => App,
+ // useful for wrapping in a per-page basis
+ enhanceComponent: Component => Component,
+ })
+
+ // Run the parent `getInitialProps`, it now includes the custom `renderPage`
+ const initialProps = await Document.getInitialProps(ctx)
+
+ return initialProps
+ }
+}
+
+export default MyDocument
+```
diff --git a/docs/advanced-features/custom-error-page.md b/docs/advanced-features/custom-error-page.md
new file mode 100644
index 00000000000000..24851e8df4014e
--- /dev/null
+++ b/docs/advanced-features/custom-error-page.md
@@ -0,0 +1,78 @@
+---
+description: Override and extend the built-in Error page to handle custom errors.
+---
+
+## 404 Page
+
+A 404 page may be accessed very often. Server-rendering an error page for every visit increases the load of the Next.js server. This can result in increased costs and slow experiences.
+
+To avoid the above pitfalls, Next.js provides a static 404 page by default without having to add any additional files.
+
+### Customizing The 404 Page
+
+To create a custom 404 page you can create a `pages/404.js` file. This file is statically generated at build time.
+
+```jsx
+// pages/404.js
+export default function Custom404() {
+ return
404 - Page Not Found
+}
+```
+
+## 500 Page
+
+By default Next.js provides a 500 error page that matches the default 404 page’s style. This page is not statically optimized as it allows server-side errors to be reported. This is why 404 and 500 (other errors) are separated.
+
+### Customizing The Error Page
+
+500 errors are handled both client-side and server-side by the `Error` component. If you wish to override it, define the file `pages/_error.js` and add the following code:
+
+```jsx
+function Error({ statusCode }) {
+ return (
+
+ {statusCode
+ ? `An error ${statusCode} occurred on server`
+ : 'An error occurred on client'}
+
+ )
+}
+
+Error.getInitialProps = ({ res, err }) => {
+ const statusCode = res ? res.statusCode : err ? err.statusCode : 404
+ return { statusCode }
+}
+
+export default Error
+```
+
+> `pages/_error.js` is only used in production. In development you’ll get an error with the call stack to know where the error originated from.
+
+### Reusing the built-in error page
+
+If you want to render the built-in error page you can by importing the `Error` component:
+
+```jsx
+import Error from 'next/error'
+import fetch from 'isomorphic-unfetch'
+
+const Page = ({ errorCode, stars }) => {
+ if (errorCode) {
+ return
+ }
+
+ return
Next stars: {stars}
+}
+
+Page.getInitialProps = async () => {
+ const res = await fetch('https://api.github.com/repos/zeit/next.js')
+ const errorCode = res.statusCode > 200 ? res.statusCode : false
+ const json = await res.json()
+
+ return { errorCode, stars: json.stargazers_count }
+}
+
+export default Page
+```
+
+The `Error` component also takes `title` as a property if you want to pass in a text message along with a `statusCode`.
diff --git a/docs/advanced-features/custom-server.md b/docs/advanced-features/custom-server.md
new file mode 100644
index 00000000000000..b7ee881c8e3fa1
--- /dev/null
+++ b/docs/advanced-features/custom-server.md
@@ -0,0 +1,99 @@
+---
+description: Start a Next.js app programmatically using a custom server.
+---
+
+# Custom Server
+
+
+ Examples
+
+
+
+Typically you start your next server with `next start`. It's possible, however, to start a server 100% programmatically in order to use custom route patterns.
+
+> Before deciding to use a custom server please keep in mind that it should only be used when the integrated router of Next.js can't meet your app requirements. A custom server will remove important performance optimizations, like **serverless functions** and **[Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).**
+
+Take a look at the following example of a custom server:
+
+```js
+// server.js
+const { createServer } = require('http')
+const { parse } = require('url')
+const next = require('next')
+
+const dev = process.env.NODE_ENV !== 'production'
+const app = next({ dev })
+const handle = app.getRequestHandler()
+
+app.prepare().then(() => {
+ createServer((req, res) => {
+ // Be sure to pass `true` as the second argument to `url.parse`.
+ // This tells it to parse the query portion of the URL.
+ const parsedUrl = parse(req.url, true)
+ const { pathname, query } = parsedUrl
+
+ if (pathname === '/a') {
+ app.render(req, res, '/b', query)
+ } else if (pathname === '/b') {
+ app.render(req, res, '/a', query)
+ } else {
+ handle(req, res, parsedUrl)
+ }
+ }).listen(3000, err => {
+ if (err) throw err
+ console.log('> Ready on http://localhost:3000')
+ })
+})
+```
+
+> `server.js` doesn't go through babel or webpack. Make sure the syntax and sources this file requires are compatible with the current node version you are running.
+
+Then, to run the custom server you'll need to update the `scripts` in `package.json`, like so:
+
+```json
+"scripts": {
+ "dev": "node server.js",
+ "build": "next build",
+ "start": "NODE_ENV=production node server.js"
+}
+```
+
+---
+
+The custom server uses the following import to connect the server with the Next.js application:
+
+```js
+const next = require('next')
+const app = next({})
+```
+
+The above `next` import is a function that receives an object with the following options:
+
+- `dev`: `Boolean` - Whether or not to launch Next.js in dev mode. Defaults to `false`
+- `dir`: `String` - Location of the Next.js project. Defaults to `'.'`
+- `quiet`: `Boolean` - Hide error messages containing server information. Defaults to `false`
+- `conf`: `object` - The same object you would use in [next.config.js](/docs/api-reference/next.config.js/introduction.md). Defaults to `{}`
+
+The returned `app` can then be used to let Next.js handle requests as required.
+
+## Disabling file-system routing
+
+By default, `Next` will serve each file in the `pages` folder under a pathname matching the filename. If your project uses a custom server, this behavior may result in the same content being served from multiple paths, which can present problems with SEO and UX.
+
+To disable this behavior and prevent routing based on files in `pages`, open `next.config.js` and disable the `useFileSystemPublicRoutes` config:
+
+```js
+module.exports = {
+ useFileSystemPublicRoutes: false,
+}
+```
+
+> Note that `useFileSystemPublicRoutes` simply disables filename routes from SSR; client-side routing may still access those paths. When 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; for that refer to [`Router.beforePopState`](/docs/api-reference/next/router.md#router.beforePopState).
diff --git a/docs/advanced-features/customizing-babel-config.md b/docs/advanced-features/customizing-babel-config.md
new file mode 100644
index 00000000000000..faea0981c88ace
--- /dev/null
+++ b/docs/advanced-features/customizing-babel-config.md
@@ -0,0 +1,60 @@
+---
+description: Extend the babel preset added by Next.js with your own configs.
+---
+
+# Customizing Babel Config
+
+
+ Examples
+
+
+
+Next.js includes the `next/babel` preset to your app, it includes everything needed to compile React applications and server-side code. But if you want to extend the default Babel configs, it's also possible.
+
+To start, you only need to define a `.babelrc` file at the top of your app, if such file is found, we're going to consider it the _source of truth_, therefore it needs to define what Next.js needs as well, which is the `next/babel` preset.
+
+Here's an example `.babelrc` file:
+
+```json
+{
+ "presets": ["next/babel"],
+ "plugins": []
+}
+```
+
+The `next/babel` presets includes:
+
+- preset-env
+- preset-react
+- preset-typescript
+- plugin-proposal-class-properties
+- plugin-proposal-object-rest-spread
+- plugin-transform-runtime
+- styled-jsx
+
+To configure these presets/plugins, **do not** add them to `presets` or `plugins` in your custom `.babelrc`. Instead, configure them on the `next/babel` preset, like so:
+
+```json
+{
+ "presets": [
+ [
+ "next/babel",
+ {
+ "preset-env": {},
+ "transform-runtime": {},
+ "styled-jsx": {},
+ "class-properties": {}
+ }
+ ]
+ ],
+ "plugins": []
+}
+```
+
+To learn more about the available options for each config, visit their documentation site.
+
+> Next.js uses the **current** Node.js version for server-side compilations.
+
+> The `modules` option on `"preset-env"` should be kept to `false`, otherwise webpack code splitting is disabled.
diff --git a/docs/advanced-features/customizing-postcss-config.md b/docs/advanced-features/customizing-postcss-config.md
new file mode 100644
index 00000000000000..0b1cb7bbb2780e
--- /dev/null
+++ b/docs/advanced-features/customizing-postcss-config.md
@@ -0,0 +1,134 @@
+---
+description: Extend the PostCSS config and plugins added by Next.js with your own.
+---
+
+# Customizing PostCSS Config
+
+
+ Examples
+
+
+
+## Default Behavior
+
+Next.js compiles CSS for its [built-in CSS support](/docs/basic-features/built-in-css-support) using PostCSS.
+
+Out of the box, with no configuration, Next.js compiles CSS with the following transformations:
+
+1. [Autoprefixer](https://github.com/postcss/autoprefixer) automatically adds vendor prefixes to CSS rules (back to IE11).
+1. [Cross-browser Flexbox bugs](https://github.com/philipwalton/flexbugs) are corrected to behave like [the spec](https://www.w3.org/TR/css-flexbox-1/).
+1. New CSS features are automatically compiled for Internet Explorer 11 compatibility:
+ - [`all` Property](https://developer.mozilla.org/en-US/docs/Web/CSS/all)
+ - [Break Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/break-after)
+ - [`font-variant` Property](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant)
+ - [Gap Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/gap)
+ - [Grid Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/grid)
+ - [Media Query Ranges](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#Syntax_improvements_in_Level_4)
+
+By default, [Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/var) (CSS variables) are **not compiled** for IE11 support.
+
+CSS variables are not compiled because it is [not possible to safely do so](https://github.com/MadLittleMods/postcss-css-variables#caveats).
+If you must use variables, consider using something like [Sass variables](https://sass-lang.com/documentation/variables) which are compiled away by [Sass](https://sass-lang.com/).
+
+## Customizing Target Browsers
+
+Next.js allows you to configure the target browsers (for [Autoprefixer](https://github.com/postcss/autoprefixer) and compiled css features) through [Browserslist](https://github.com/browserslist/browserslist).
+
+To customize browserslist, create a `browserslist` key in your `package.json` like so:
+
+```json
+{
+ "browserslist": [">0.3%", "not ie 11", "not dead", "not op_mini all"]
+}
+```
+
+You can use the [browserl.ist](https://browserl.ist/?q=%3E0.3%25%2C+not+ie+11%2C+not+dead%2C+not+op_mini+all) tool to visualize what browsers you are targeting.
+
+## CSS Modules
+
+No configuration is needed to support CSS Modules. To enable CSS Modules for a file, rename the file to have the extension `.module.css`.
+
+You can learn more about [Next.js' CSS Module support here](/docs/basic-features/built-in-css-support).
+
+## Customizing Plugins
+
+> **Warning**: When you define a custom PostCSS configuration file, Next.js **completely disables** the [default behavior](#default-behavior).
+> Be sure to manually configure all the features you need compiled, including [Autoprefixer](https://github.com/postcss/autoprefixer).
+
+To customize the PostCSS configuration, create a `postcss.config.json` file in the root of your project.
+
+This is the default configuration used by Next.js:
+
+```json
+{
+ "plugins": [
+ "postcss-flexbugs-fixes",
+ [
+ "postcss-preset-env",
+ {
+ "autoprefixer": {
+ "flexbox": "no-2009"
+ },
+ "stage": 3,
+ "features": {
+ "custom-properties": false
+ }
+ }
+ ]
+ ]
+}
+```
+
+> **Note**: Next.js also allows the file to be named `.postcssrc.json`, or, to be read from the `postcss` key in `package.json`.
+
+It is also possible to configure PostCSS with a `postcss.config.js` file, which is useful when you want to conditionally include plugins based on environment:
+
+```js
+module.exports = {
+ plugins:
+ process.env.NODE_ENV === 'production'
+ ? [
+ 'postcss-flexbugs-fixes',
+ [
+ 'postcss-preset-env',
+ {
+ autoprefixer: {
+ flexbox: 'no-2009',
+ },
+ stage: 3,
+ features: {
+ 'custom-properties': false,
+ },
+ },
+ ],
+ ]
+ : [
+ // No transformations in development
+ ],
+}
+```
+
+> **Note**: Next.js also allows the file to be named `.postcssrc.js`.
+
+Do **not use `require()`** to import the PostCSS Plugins. Plugins must be provided as strings.
+
+> **Note**: If your `postcss.config.js` needs to support other non-Next.js tools in the same project, you must use the interoperable object-based format instead:
+>
+> ```js
+> module.exports = {
+> plugins: {
+> 'postcss-flexbugs-fixes': {},
+> 'postcss-preset-env': {
+> autoprefixer: {
+> flexbox: 'no-2009',
+> },
+> stage: 3,
+> features: {
+> 'custom-properties': false,
+> },
+> },
+> },
+> }
+> ```
diff --git a/docs/advanced-features/dynamic-import.md b/docs/advanced-features/dynamic-import.md
new file mode 100644
index 00000000000000..547137cbb4187c
--- /dev/null
+++ b/docs/advanced-features/dynamic-import.md
@@ -0,0 +1,124 @@
+---
+description: Dynamically import JavaScript modules and React Components and split your code into manageable chunks.
+---
+
+# Dynamic Import
+
+
+ Examples
+
+
+
+Next.js supports ES2020 [dynamic `import()`](https://github.com/tc39/proposal-dynamic-import) for JavaScript. With it you can import JavaScript modules (inc. React Components) dynamically and work with them. They also work with SSR.
+
+You can think of dynamic imports as another way to split your code into manageable chunks.
+
+## Basic usage
+
+In the following example, the module `../components/hello` will be dynamically loaded by the page:
+
+```jsx
+import dynamic from 'next/dynamic'
+
+const DynamicComponent = dynamic(() => import('../components/hello'))
+
+function Home() {
+ return (
+
+
+
+
HOME PAGE is here!
+
+ )
+}
+
+export default Home
+```
+
+`DynamicComponent` will be the default component returned by `../components/hello`. It works like a regular React Component, and you can pass props to it as you normally would.
+
+## With named exports
+
+If the dynamic component is not the default export, you can use a named export too. Consider the module `../components/hello.js` which has a named export `Hello`:
+
+```jsx
+export function Hello() {
+ return
Hello!
+}
+```
+
+To dynamically import the `Hello` component, you can return it from the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) returned by [`import()`](https://github.com/tc39/proposal-dynamic-import#example), like so:
+
+```jsx
+import dynamic from 'next/dynamic'
+
+const DynamicComponent = dynamic(() =>
+ import('../components/hello').then(mod => mod.Hello)
+)
+
+function Home() {
+ return (
+
+
+
+
HOME PAGE is here!
+
+ )
+}
+
+export default Home
+```
+
+## With custom loading component
+
+An optional `loading` component can be added to render a loading state while the dynamic component is being loaded. For example:
+
+```jsx
+import dynamic from 'next/dynamic'
+
+const DynamicComponentWithCustomLoading = dynamic(
+ () => import('../components/hello'),
+ { loading: () =>
...
}
+)
+
+function Home() {
+ return (
+
+
+
+
HOME PAGE is here!
+
+ )
+}
+
+export default Home
+```
+
+## With no SSR
+
+You may not always want to include a module on server-side, For example, when the module includes a library that only works in the browser.
+
+Take a look at the following example:
+
+```jsx
+import dynamic from 'next/dynamic'
+
+const DynamicComponentWithNoSSR = dynamic(
+ () => import('../components/hello3'),
+ { ssr: false }
+)
+
+function Home() {
+ return (
+
+
+
+
HOME PAGE is here!
+
+ )
+}
+
+export default Home
+```
diff --git a/docs/advanced-features/multi-zones.md b/docs/advanced-features/multi-zones.md
new file mode 100644
index 00000000000000..2a9883a2541d52
--- /dev/null
+++ b/docs/advanced-features/multi-zones.md
@@ -0,0 +1,47 @@
+# Multi Zones
+
+
+ Examples
+
+
+
+A zone is a single deployment of a Next.js app. You can have multiple zones and merge them as a single app.
+
+For example, let's say you have the following apps:
+
+- An app for serving `/blog/**`
+- Another app for serving all other pages
+
+With multi zones support, you can merge both these apps into a single one allowing your customers to browse it using a single URL, but you can develop and deploy both apps independently.
+
+## How to define a zone
+
+There are no special zones related APIs. You only need to do following:
+
+- Make sure to keep only the pages you need in your app, meaning that an app can't have pages from another app, if app `A` has `/blog` then app `B` shouldn't have it too.
+- Make sure to add an [assetPrefix](/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md) to avoid conflicts with static files.
+
+## How to merge zones
+
+You can merge zones using any HTTP proxy.
+
+For [ZEIT Now](https://zeit.co/now), you can use a single `now.json` to deploy both apps. It allows you to easily define routing routes for multiple apps like below:
+
+```json
+{
+ "version": 2,
+ "builds": [
+ { "src": "blog/package.json", "use": "@now/next" },
+ { "src": "home/package.json", "use": "@now/next" }
+ ],
+ "routes": [
+ { "src": "/blog/_next(.*)", "dest": "blog/_next$1" },
+ { "src": "/blog(.*)", "dest": "blog/blog$1" },
+ { "src": "(.*)", "dest": "home$1" }
+ ]
+}
+```
+
+You can also configure a proxy server to route using a set of routes like the ones above, e.g deploy the blog app to `https://blog.example.com` and the home app to `https://home.example.com` and then add a proxy server for both apps in `https://example.com`.
diff --git a/docs/advanced-features/preview-mode.md b/docs/advanced-features/preview-mode.md
new file mode 100644
index 00000000000000..2e7fd264cc5030
--- /dev/null
+++ b/docs/advanced-features/preview-mode.md
@@ -0,0 +1,224 @@
+---
+description: Next.js has the preview mode for statically generated pages. You can learn how it works here.
+---
+
+# Preview Mode
+
+> This document is for Next.js versions 9.3 and up. If you’re using older versions of Next.js, refer to our [previous documentation](https://nextjs.org/docs/tag/v9.2.2/basic-features/pages).
+
+In the [Pages documentation](/docs/basic-features/pages.md) and the [Data Fetching documentation](/docs/basic-features/data-fetching.md), we talked about how to pre-render a page at build time (**Static Generation**) using `getStaticProps` and `getStaticPaths`.
+
+Static Generation is useful when your pages fetch data from a headless CMS. However, it’s not ideal when you’re writing a draft on your headless CMS and want to **preview** the draft immediately on your page. You’d want to Next.js to render these pages at **request time** instead of build time and fetch the draft content instead of the published content. You’d want Next.js to bypass Static Generation only for this specific case.
+
+Next.js has the feature called **Preview Mode** which solves this problem. Here’s an instruction on how to use it.
+
+## Step 1. Create and access a preview API route
+
+> Take a look at the [API Routes documentation](/docs/api-routes/introduction.md) first if you’re not familiar with Next.js API Routes.
+
+First, create a **preview API route**. It can have any name - e.g. `pages/api/preview.js` (or `.ts` if using TypeScript).
+
+In this API route, you need to call `setPreviewData` on the response object. The argument for `setPreviewData` should be an object, and this can be used by `getStaticProps` (more on this later). For now, we’ll just use `{}`.
+
+```js
+export default (req, res) => {
+ // ...
+ res.setPreviewData({})
+ // ...
+}
+```
+
+`res.setPreviewData` sets some **cookies** on the browser which turns on the preview mode. Any requests to Next.js containing these cookies will be considered as the **preview mode**, and the behavior for statically generated pages will change (more on this later).
+
+You can test this manually by creating an API route like below and accessing it from your browser manually:
+
+```js
+// A simple example for testing it manually from your browser.
+// If this is located at pages/api/preview.js, then
+// open /api/preview from your browser.
+export default (req, res) => {
+ res.setPreviewData({})
+ res.end('Preview mode enabled')
+}
+```
+
+If you use your browser’s developer tools, you’ll notice that the `__prerender_bypass` and `__next_preview_data` cookies will be set on this request.
+
+### Securely accessing it from your Headless CMS
+
+In practice, you’d want to call this API route _securely_ from your headless CMS. The specific steps will vary depending on which headless CMS you’re using, but here are some common steps you could take.
+
+These steps assume that the headless CMS you’re using supports setting **custom preview URLs**. If it doesn’t, you can still use this method to secure your preview URLs, but you’ll need to construct and access the preview URL manually.
+
+**First**, you should create a **secret token string** using a token generator of your choice. This secret will only be known by your Next.js app and your headless CMS. This secret prevents people who don’t have access to your CMS from accessing preview URLs.
+
+**Second**, if your headless CMS supports setting custom preview URLs, specify the following as the preview URL. (This assumes that your preview API route is located at `pages/api/preview.js`.)
+
+```bash
+https:///api/preview?secret=&slug=
+```
+
+- `` should be your deployment domain.
+- `` should be replaced with the secret token you generated.
+- `` should be the path for the page that you want to preview. If you want to preview `/posts/foo`, then you should use `&slug=/posts/foo`.
+
+Your headless CMS might allow you to include a variable in the preview URL so that `` can be set dynamically based on the CMS’s data like so: `&slug=/posts/{entry.fields.slug}`
+
+**Finally**, in the preview API route:
+
+- Check that the secret matches and that the `slug` parameter exists (if not, the request should fail).
+-
+- Call `res.setPreviewData`.
+- Then redirect the browser to the path specified by `slug`. (The following example uses a [307 redirect](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307)).
+
+```js
+export default async (req, res) => {
+ // Check the secret and next parameters
+ // This secret should only be known to this API route and the CMS
+ if (req.query.secret !== 'MY_SECRET_TOKEN' || !req.query.slug) {
+ return res.status(401).json({ message: 'Invalid token' })
+ }
+
+ // Fetch the headless CMS to check if the provided `slug` exists
+ // getPostBySlug would implement the required fetching logic to the headless CMS
+ const post = await getPostBySlug(req.query.slug)
+
+ // If the slug doesn't exist prevent preview mode from being enabled
+ if (!post) {
+ return res.status(401).json({ message: 'Invalid slug' })
+ }
+
+ // Enable Preview Mode by setting the cookies
+ res.setPreviewData({})
+
+ // Redirect to the path from the fetched post
+ // We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
+ res.writeHead(307, { Location: post.slug })
+ res.end()
+}
+```
+
+If it succeeds, then the browser will be redirected to the path you want to preview with the preview mode cookies being set.
+
+## Step 2. Update `getStaticProps`
+
+The next step is to update `getStaticProps` to support the preview mode.
+
+If you request a page which has `getStaticProps` with the preview mode cookies set (via `res.setPreviewData`), then `getStaticProps` will be called at **request time** (instead of at build time).
+
+Furthermore, it will be called with a `context` object where:
+
+- `context.preview` will be `true`.
+- `context.previewData` will be the same as the argument used for `setPreviewData`.
+
+```js
+export async function getStaticProps(context) {
+ // If you request this page with the preview mode cookies set:
+ //
+ // - context.preview will be true
+ // - context.previewData will be the same as
+ // the argument used for `setPreviewData`.
+}
+```
+
+We used `res.setPreviewData({})` in the preview API route, so `context.previewData` will be `{}`. You can use this to pass session information from the preview API route to `getStaticProps` if necessary.
+
+If you’re also using `getStaticPaths`, then `context.params` will also be available.
+
+### Fetch preview data
+
+You can update `getStaticProps` to fetch different data based on `context.preview` and/or `context.previewData`.
+
+For example, your headless CMS might have a different API endpoint for draft posts. If so, you can use `context.preview` to modify the API endpoint URL like below:
+
+```js
+export async function getStaticProps(context) {
+ // If context.preview is true, append "/preview" to the API endpoint
+ // to request draft data instead of published data. This will vary
+ // based on which headless CMS you're using.
+ const res = await fetch(`https://.../${context.preview ? 'preview' : ''}`)
+ // ...
+}
+```
+
+That’s it! If you access the preview API route (with `secret` and `slug`) from your headless CMS or manually, you should now be able to see the preview content. And if you update your draft without publishing, you should be able to preview the draft.
+
+```bash
+# Set this as the preview URL on your headless CMS or access manually,
+# and you should be able to see the preview.
+https:///api/preview?secret=&slug=
+```
+
+## More Examples
+
+Take a look at the following examples to learn more:
+
+- [DatoCMS Example](https://github.com/zeit/next.js/tree/canary/examples/cms-datocms) ([Demo](https://next-blog-datocms.now.sh/))
+- [TakeShape Example](https://github.com/zeit/next.js/tree/canary/examples/cms-takeshape) ([Demo](https://next-blog-takeshape.now.sh/))
+- [Sanity Example](https://github.com/zeit/next.js/tree/canary/examples/cms-sanity) ([Demo](https://next-blog-sanity.now.sh/))
+
+## More Details
+
+### Clear the preview mode cookies
+
+By default, no expiration date is set for the preview mode cookies, so the preview mode ends when the browser is closed.
+
+To clear the preview cookies manually, you can create an API route which calls `clearPreviewData` and then access this API route.
+
+```js
+export default (req, res) => {
+ // Clears the preview mode cookies.
+ // This function accepts no arguments.
+ res.clearPreviewData()
+ // ...
+}
+```
+
+### Specify the preview mode duration
+
+`setPreviewData` takes an optional second parameter which should be an options object. It accepts the following keys:
+
+- `maxAge`: Specifies the number (in seconds) for the preview session to last for.
+
+```js
+setPreviewData(data, {
+ maxAge: 60 * 60, // The preview mode cookies expire in 1 hour
+})
+```
+
+### `previewData` size limits
+
+You can pass an object to `setPreviewData` and have it be available in `getStaticProps`. However, because the data will be stored in a cookie, there’s a size limitation. Currently, preview data is limited to 2KB.
+
+### Works with `getServerSideProps`
+
+The preview mode works on `getServerSideProps` as well. It will also be available on the `context` object containing `preview` and `previewData`.
+
+### Unique per `next build`
+
+The bypass cookie value and private key for encrypting the `previewData` changes when a `next build` is ran, this ensures that the bypass cookie can’t be guessed.
+
+## Learn more
+
+The following pages might also be useful.
+
+
diff --git a/docs/advanced-features/src-directory.md b/docs/advanced-features/src-directory.md
new file mode 100644
index 00000000000000..00a16283238271
--- /dev/null
+++ b/docs/advanced-features/src-directory.md
@@ -0,0 +1,25 @@
+---
+description: Save pages under the `src` directory as an alternative to the root `pages` directory.
+---
+
+# `src` Directory
+
+Pages can also be added under `src/pages` as an alternative to the root `pages` directory.
+
+The `src` directory is very common in many apps and Next.js supports it by default.
+
+## Caveats
+
+- `src/pages` will be ignored if `pages` is present in the root directory
+- Config files like `next.config.js` and `tsconfig.json` should be inside the root directory, moving them to `src` won't work. Same goes for the [`public` directory](/docs/basic-features/static-file-serving.md)
+
+## Related
+
+For more information on what to do next, we recommend the following sections:
+
+
diff --git a/docs/advanced-features/static-html-export.md b/docs/advanced-features/static-html-export.md
new file mode 100644
index 00000000000000..4b2f09da7c1cf2
--- /dev/null
+++ b/docs/advanced-features/static-html-export.md
@@ -0,0 +1,58 @@
+---
+description: Export your Next.js app to static HTML, and run it standalone without the need of a Node.js server.
+---
+
+# Static HTML Export
+
+
+ Examples
+
+
+
+`next export` allows you to export your app to static HTML, which can be run standalone without the need of a Node.js server.
+
+The exported app supports almost every feature of Next.js, including dynamic routes, prefetching, preloading and dynamic imports.
+
+The way `next export` works is by prerendering all pages to HTML; it does so based on a mapping called [`exportPathMap`](/docs/api-reference/next.config.js/exportPathMap.md) which offers a way to pre-define paths you will render as html.
+
+> If your pages don't have `getInitialProps` you may not need `next export` at all; `next build` is already enough thanks to [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).
+
+## How to use it
+
+Simply develop your app as you normally do with Next.js. Then run:
+
+```bash
+next build && next export
+```
+
+For that you may want to update the scripts in your `package.json` like this:
+
+```json
+"scripts": {
+ "build": "next build && next export"
+}
+```
+
+And run it at once with:
+
+```bash
+npm run build
+```
+
+Then you'll have a static version of your app in the `out` directory.
+
+By default `next export` doesn't require any configuration. It will generate a default `exportPathMap` with routes for the pages inside the `pages` directory.
+
+> To learn more about `exportPathMap` please visit the [documentation for the `exportPathMap` API](/docs/api-reference/next.config.js/exportPathMap.md).
+
+## Deployment
+
+You can read about deploying your Next.js application in the [deployment section](/docs/deployment.md).
+
+## Caveats
+
+- With `next export`, we build an HTML version of your app. At export time we will run the [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md) in your pages. The `req` and `res` fields of the [`context`](/docs/api-reference/data-fetching/getInitialProps.md#context-object) object will be empty objects during export as there is no server running.
+- You won't be able to render HTML dynamically when static exporting, as we pre-build the HTML files. Your application can be a hybrid of [Static Generation](/docs/basic-features/pages.md#static-generation) and [Server-Side Rendering](/docs/basic-features/pages.md#server-side-rendering) when you don't use `next export`. You can learn more about it in the [pages section](/docs/basic-features/pages.md).
+- [API Routes](/docs/api-routes/introduction.md) are not supported by this method because they can't be prerendered to HTML.
diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md
new file mode 100644
index 00000000000000..5b4de22e6301d6
--- /dev/null
+++ b/docs/api-reference/cli.md
@@ -0,0 +1,40 @@
+---
+description: The Next.js CLI allows you to start, build, and export your application. Learn more about it here.
+---
+
+# Next.js CLI
+
+The Next.js CLI allows you to start, build, and export your application.
+
+To get a list of the available CLI commands, run the following command inside your project directory:
+
+```bash
+npx next -h
+```
+
+_([npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) comes with npm 5.2+ and higher)_
+
+The output should look like this:
+
+```bash
+Usage
+ $ next
+
+Available commands
+ build, start, export, dev, telemetry
+
+Options
+ --version, -v Version number
+ --help, -h Displays this message
+
+For more information run a command with the --help flag
+ $ next build --help
+```
+
+You can pass any [node arguments](https://nodejs.org/api/cli.html#cli_node_options_options) to `next` commands:
+
+```bash
+NODE_OPTIONS='--throw-deprecation' next
+NODE_OPTIONS='-r esm' next
+NODE_OPTIONS='--inspect' next
+```
diff --git a/docs/api-reference/data-fetching/getInitialProps.md b/docs/api-reference/data-fetching/getInitialProps.md
new file mode 100644
index 00000000000000..6d161d6732c0c3
--- /dev/null
+++ b/docs/api-reference/data-fetching/getInitialProps.md
@@ -0,0 +1,148 @@
+---
+description: Enable Server-Side Rendering in a page and do initial data population with `getInitialProps`.
+---
+
+# getInitialProps
+
+> **Recommended: [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) or [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering)**
+>
+> If you're using Next.js 9.3 or newer, we recommend that you use `getStaticProps` or `getServerSideProps` instead of `getInitialProps`.
+>
+> These new data fetching methods allow you to have a granular choice between static generation and server-side rendering.
+> Learn more on the documentation for [Pages](/docs/basic-features/pages.md) and [Data fetching](/docs/basic-features/data-fetching.md):
+
+
+ Examples
+
+
+
+`getInitialProps` enables [server-side rendering](/docs/basic-features/pages.md#server-side-rendering) in a page and allows you to do **initial data population**, it means sending the [page](/docs/basic-features/pages.md) with the data already populated from the server. This is especially useful for [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization).
+
+> `getInitialProps` will disable [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).
+
+`getInitialProps` is an [`async`](https://zeit.co/blog/async-and-await) function that can be added to any page as a [`static method`](https://javascript.info/static-properties-methods). Take a look at the following example:
+
+```jsx
+import fetch from 'isomorphic-unfetch'
+
+function Page({ stars }) {
+ return
+ }
+}
+
+export default Page
+```
+
+`getInitialProps` is used to asynchronously fetch some data, which then populates `props`.
+
+Data returned from `getInitialProps` is serialized when server rendering, similar to what [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) does. Make sure the returned object from `getInitialProps` is a plain `Object` and not using `Date`, `Map` or `Set`.
+
+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 [`next/link`](/docs/api-reference/next/link.md) component or by using [`next/router`](/docs/api-reference/next/router.md).
+
+## Context Object
+
+`getInitialProps` receives a single argument called `context`, it's an object with the following properties:
+
+- `pathname` - Current route. That is the path of the page in `/pages`
+- `query` - Query string section of URL parsed as an object
+- `asPath` - `String` of the actual path (including the query) shown in the browser
+- `req` - HTTP request object (server only)
+- `res` - HTTP response object (server only)
+- `err` - Error object if any error is encountered during the rendering
+
+## Caveats
+
+- `getInitialProps` can **not** be used in children components, only in the default export of every page
+- If you are using server-side 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
+
+## TypeScript
+
+If you're using TypeScript, you can use the `NextPage` type for functional components:
+
+```jsx
+import { NextPage } from 'next'
+
+interface Props {
+ userAgent?: string;
+}
+
+const Page: NextPage = ({ userAgent }) => (
+ Your user agent: {userAgent}
+)
+
+Page.getInitialProps = async ({ req }) => {
+ const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
+ return { userAgent }
+}
+
+export default Page
+```
+
+And for `React.Component`, you can use `NextPageContext`:
+
+```jsx
+import React from 'react'
+import { NextPageContext } from 'next'
+
+interface Props {
+ userAgent?: string;
+}
+
+export default class Page extends React.Component {
+ static async getInitialProps({ req }: NextPageContext) {
+ const userAgent = req ? req.headers['user-agent'] : navigator.userAgent
+ return { userAgent }
+ }
+
+ render() {
+ const { userAgent } = this.props
+ return Your user agent: {userAgent}
+ }
+}
+```
+
+## Related
+
+For more information on what to do next, we recommend the following sections:
+
+
diff --git a/docs/api-reference/next.config.js/build-target.md b/docs/api-reference/next.config.js/build-target.md
new file mode 100644
index 00000000000000..616cad6aca6104
--- /dev/null
+++ b/docs/api-reference/next.config.js/build-target.md
@@ -0,0 +1,47 @@
+---
+description: Learn more about the build targets used by Next.js, which decide the way your application is built and run.
+---
+
+# Build Target
+
+Next.js supports various build targets, each changing the way your application is built and run. We'll explain each of the targets below.
+
+## `server` target
+
+> This is the default target, however, we highly recommend the [`serverless` target](#serverless-target). The `serverless` target enforces [additional constraints](https://rauchg.com/2020/2019-in-review#serverless-upgrades-itself) to keep you in the [Pit of Success](https://blog.codinghorror.com/falling-into-the-pit-of-success/).
+
+This target is compatible with both `next start` and [custom server](/docs/advanced-features/custom-server.md) setups (it's mandatory for a custom server).
+
+Your application will be built and deployed as a monolith. This is the default target and no action is required on your part to opt-in.
+
+## `serverless` target
+
+> Deployments to [ZEIT Now](https://zeit.co) will automatically enable this target. You do not need to opt-into it yourself, but you can.
+
+This target will output independent pages that don't require a monolithic server.
+
+It's only compatible with `next start` or Serverless deployment platforms (like [ZEIT Now](https://zeit.co)) — you cannot use the custom server API.
+
+To opt-into this target, set the following configuration in your `next.config.js`:
+
+```js
+module.exports = {
+ target: 'serverless',
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md b/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md
new file mode 100644
index 00000000000000..7b6435c1eba303
--- /dev/null
+++ b/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md
@@ -0,0 +1,36 @@
+---
+description: A custom asset prefix allows you serve static assets from a CDN. Learn more about it here.
+---
+
+# CDN Support with Asset Prefix
+
+To set up a [CDN](https://en.wikipedia.org/wiki/Content_delivery_network), you can set up an asset prefix and configure your CDN's origin to resolve to the domain that Next.js is hosted on.
+
+Open `next.config.js` and add the `assetPrefix` config:
+
+```js
+const isProd = process.env.NODE_ENV === 'production'
+
+module.exports = {
+ // Use the CDN in production and localhost for development.
+ assetPrefix: isProd ? 'https://cdn.mydomain.com' : '',
+}
+```
+
+Next.js will automatically use your prefix in the scripts it loads, but this has no effect whatsoever on the [public](/docs/basic-features/static-file-serving.md) folder; if you want to serve those assets over a 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/canary/examples/with-universal-configuration-build-time).
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/compression.md b/docs/api-reference/next.config.js/compression.md
new file mode 100644
index 00000000000000..c20ebe798e1c7d
--- /dev/null
+++ b/docs/api-reference/next.config.js/compression.md
@@ -0,0 +1,24 @@
+---
+description: Next.js provides gzip compression to compress rendered content and static files, it only works with the server target. Learn more about it here.
+---
+
+# Compression
+
+Next.js provides [**gzip**](https://tools.ietf.org/html/rfc6713#section-3) compression to compress rendered content and static files. Compression only works with the [`server` target](/docs/api-reference/next.config.js/build-target.md#server-target). In general you will want to enable compression on a HTTP proxy like [nginx](https://www.nginx.com/), to offload load from the `Node.js` process.
+
+To disable **compression**, open `next.config.js` and disable the `compress` config:
+
+```js
+module.exports = {
+ compress: false,
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/configuring-onDemandEntries.md b/docs/api-reference/next.config.js/configuring-onDemandEntries.md
new file mode 100644
index 00000000000000..2e9133a9d2d0b9
--- /dev/null
+++ b/docs/api-reference/next.config.js/configuring-onDemandEntries.md
@@ -0,0 +1,29 @@
+---
+description: Configure how Next.js will dispose and keep in memory pages created in development.
+---
+
+# Configuring onDemandEntries
+
+Next.js exposes some options that give you some control over how the server will dispose or keep in memory built pages in development.
+
+To change the defaults, open `next.config.js` and add the `onDemandEntries` config:
+
+```js
+module.exports = {
+ onDemandEntries: {
+ // period (in ms) where the server will keep pages in the buffer
+ maxInactiveAge: 25 * 1000,
+ // number of pages that should be kept simultaneously without being disposed
+ pagesBufferLength: 2,
+ },
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/configuring-the-build-id.md b/docs/api-reference/next.config.js/configuring-the-build-id.md
new file mode 100644
index 00000000000000..1d22438a7c2068
--- /dev/null
+++ b/docs/api-reference/next.config.js/configuring-the-build-id.md
@@ -0,0 +1,27 @@
+---
+description: Configure the build id, which is used to identify the current build in which your application is being served.
+---
+
+# Configuring the Build ID
+
+Next.js uses a constant id 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 your own build id.
+
+Open `next.config.js` and add the `generateBuildId` function:
+
+```js
+module.exports = {
+ generateBuildId: async () => {
+ // You can, for example, get the latest git commit hash here
+ return 'my-build-id'
+ },
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/custom-page-extensions.md b/docs/api-reference/next.config.js/custom-page-extensions.md
new file mode 100644
index 00000000000000..54fc78f6f9ba39
--- /dev/null
+++ b/docs/api-reference/next.config.js/custom-page-extensions.md
@@ -0,0 +1,24 @@
+---
+description: Extend the default page extensions used by Next.js when resolving pages in the pages directory.
+---
+
+# Custom Page Extensions
+
+Aimed at modules like [@next/mdx](https://github.com/zeit/next.js/tree/canary/packages/next-mdx), which adds support for pages ending with `.mdx`. You can configure the extensions looked for in the `pages` directory when resolving pages.
+
+Open `next.config.js` and add the `pageExtensions` config:
+
+```js
+module.exports = {
+ pageExtensions: ['mdx', 'jsx', 'js', 'ts', 'tsx'],
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/custom-webpack-config.md b/docs/api-reference/next.config.js/custom-webpack-config.md
new file mode 100644
index 00000000000000..5e0f74a5656323
--- /dev/null
+++ b/docs/api-reference/next.config.js/custom-webpack-config.md
@@ -0,0 +1,76 @@
+---
+description: Extend the default webpack config added by Next.js.
+---
+
+# Custom Webpack Config
+
+Some commonly asked for features are available as plugins:
+
+- [@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-stylus](https://github.com/zeit/next-plugins/tree/master/packages/next-stylus)
+- [@zeit/next-preact](https://github.com/zeit/next-plugins/tree/master/packages/next-preact)
+- [@next/mdx](https://github.com/zeit/next.js/tree/canary/packages/next-mdx)
+- [@next/bundle-analyzer](https://github.com/zeit/next.js/tree/canary/packages/next-bundle-analyzer)
+
+In order to extend our usage of `webpack`, you can define a function that extends its config inside `next.config.js`, like so:
+
+```js
+module.exports = {
+ webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
+ // Note: we provide webpack above so you should not `require` it
+ // Perform customizations to webpack config
+ // Important: return the modified config
+ config.plugins.push(new webpack.IgnorePlugin(/\/__tests__\//))
+ return config
+ },
+ webpackDevMiddleware: config => {
+ // Perform customizations to webpack dev middleware config
+ // Important: return the modified config
+ return config
+ },
+}
+```
+
+> 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.
+
+The second argument to the `webpack` function is an object with the following properties:
+
+- `buildId`: `String` - The build id, used as a unique identifier between builds
+- `dev`: `Boolean` - Indicates if the compilation will be done in development
+- `isServer`: `Boolean` - It's `true` for server-side compilation, and `false` for client-side compilation
+- `defaultLoaders`: `Object` - Default loaders used internally by Next.js:
+ - `babel`: `Object` - Default `babel-loader` configuration
+
+Example usage of `defaultLoaders.babel`:
+
+```js
+// Example config for adding a loader that depends on babel-loader
+// This source was taken from the @next/mdx plugin source:
+// https://github.com/zeit/next.js/tree/canary/packages/next-mdx
+module.exports = {
+ webpack: (config, options) => {
+ config.module.rules.push({
+ test: /\.mdx/,
+ use: [
+ options.defaultLoaders.babel,
+ {
+ loader: '@mdx-js/loader',
+ options: pluginOptions.options,
+ },
+ ],
+ })
+
+ return config
+ },
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/disabling-etag-generation.md b/docs/api-reference/next.config.js/disabling-etag-generation.md
new file mode 100644
index 00000000000000..71a2f82cf5fff8
--- /dev/null
+++ b/docs/api-reference/next.config.js/disabling-etag-generation.md
@@ -0,0 +1,24 @@
+---
+description: Next.js will generate etags for every page by default. Learn more about how to disable etag generation here.
+---
+
+# Disabling ETag Generation
+
+Next.js will generate [etags](https://en.wikipedia.org/wiki/HTTP_ETag) for every page by default. You may want to disable etag generation for HTML pages depending on your cache strategy.
+
+Open `next.config.js` and disable the `generateEtags` option:
+
+```js
+module.exports = {
+ generateEtags: false,
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/disabling-x-powered-by.md b/docs/api-reference/next.config.js/disabling-x-powered-by.md
new file mode 100644
index 00000000000000..1595d8e3001164
--- /dev/null
+++ b/docs/api-reference/next.config.js/disabling-x-powered-by.md
@@ -0,0 +1,22 @@
+---
+description: Next.js will add `x-powered-by` to the request headers by default. Learn to opt-out of it here.
+---
+
+# Disabling x-powered-by
+
+By default Next.js will add `x-powered-by` to the request headers. To opt-out of it, open `next.config.js` and disable the `poweredByHeader` config:
+
+```js
+module.exports = {
+ poweredByHeader: false,
+}
+```
+
+## Related
+
+
+
+
+To add environment variables to the JavaScript bundle, open `next.config.js` and add the `env` config:
+
+```js
+module.exports = {
+ env: {
+ customKey: 'my-value',
+ },
+}
+```
+
+Now you can access `process.env.customKey` in your code. For example:
+
+```jsx
+function Page() {
+ return
The value of customKey is: {process.env.customKey}
+}
+
+export default Page
+```
+
+Next.js will replace `process.env.customKey` with `'my-value'` at build time. Trying to destructure `process.env` variables won't work due to the nature of webpack [DefinePlugin](https://webpack.js.org/plugins/define-plugin/).
+
+For example, the following line:
+
+```jsx
+return
The value of customKey is: {process.env.customKey}
diff --git a/docs/api-reference/next.config.js/exportPathMap.md b/docs/api-reference/next.config.js/exportPathMap.md
new file mode 100644
index 00000000000000..449f00e038aaed
--- /dev/null
+++ b/docs/api-reference/next.config.js/exportPathMap.md
@@ -0,0 +1,84 @@
+---
+description: Customize the pages that will be exported as HTML files when using `next export`.
+---
+
+# exportPathMap
+
+> This feature is exclusive of `next export`. Please refer to [Static HTML export](/docs/advanced-features/static-html-export.md) if you want to learn more about it.
+
+
+ Examples
+
+
+
+Let's start with an example, to create a custom `exportPathMap` for an app with the following pages:
+
+- `pages/index.js`
+- `pages/about.js`
+- `pages/post.js`
+
+Open `next.config.js` and add the following `exportPathMap` config:
+
+```js
+module.exports = {
+ exportPathMap: async function(
+ defaultPathMap,
+ { dev, dir, outDir, distDir, buildId }
+ ) {
+ return {
+ '/': { page: '/' },
+ '/about': { page: '/about' },
+ '/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' } },
+ }
+ },
+}
+```
+
+The pages will then be exported as HTML files, for example, `/about` will become `/about.html`.
+
+`exportPathMap` is an `async` function that receives 2 arguments: the first one is `defaultPathMap`, which is the default map used by Next.js. The second argument is an object with:
+
+- `dev` - `true` when `exportPathMap` is being called in development. `false` when running `next export`. In development `exportPathMap` is used to define routes.
+- `dir` - Absolute path to the project directory
+- `outDir` - Absolute path to the `out/` directory (configurable with `-o`). When `dev` is `true` the value of `outDir` will be `null`.
+- `distDir` - Absolute path to the `.next/` directory (configurable with the [`distDir`](/docs/api-reference/next.config.js/setting-a-custom-build-directory.md) config)
+- `buildId` - The generated build id
+
+The returned object is a map of pages where the `key` is the `pathname` and the `value` is an object that accepts the following fields:
+
+- `page`: `String` - the page inside the `pages` directory to render
+- `query`: `Object` - the `query` object passed to `getInitialProps` when prerendering. Defaults to `{}`
+
+> The exported `pathname` can also be a filename (for example, `/readme.md`), but you may need to set the `Content-Type` header to `text/html` when serving its content if it is different than `.html`.
+
+## Adding a trailing slash
+
+It is possible to configure Next.js to export pages as `index.html` files and require trailing slashes, `/about` becomes `/about/index.html` and is routable via `/about/`. This was the default behavior prior to Next.js 9.
+
+To switch back and add a trailing slash, open `next.config.js` and enable the `exportTrailingSlash` config:
+
+```js
+module.exports = {
+ exportTrailingSlash: true,
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/ignoring-typescript-errors.md b/docs/api-reference/next.config.js/ignoring-typescript-errors.md
new file mode 100644
index 00000000000000..f9f5b6ba9e4f4c
--- /dev/null
+++ b/docs/api-reference/next.config.js/ignoring-typescript-errors.md
@@ -0,0 +1,58 @@
+---
+description: Next.js reports TypeScript errors by default. Learn to opt-out of this behavior here.
+---
+
+# Ignoring TypeScript Errors
+
+Next.js reports TypeScript errors by default. If you don't want to leverage this behavior and prefer something else instead, like your editor's integration, you may want to disable it.
+
+Open `next.config.js` and enable the `ignoreDevErrors` option in the `typescript` config:
+
+```js
+module.exports = {
+ typescript: {
+ ignoreDevErrors: true,
+ },
+}
+```
+
+Next.js will still fail your **production build** (`next build`) when TypeScript errors are present in your project.
+
+---
+
+If you'd like Next.js to dangerously produce production code even when your application has errors, you can also disable error reports for builds.
+
+> Be sure you are running type checks as part of your build or deploy process, otherwise this can be very dangerous.
+
+Open `next.config.js` and enable the `ignoreBuildErrors` option in the `typescript` config:
+
+```js
+module.exports = {
+ typescript: {
+ // !! WARN !!
+ // Dangerously allow production builds to successfully complete even if
+ // your project has type errors.
+ //
+ // This option is rarely needed, and should be reserved for advanced
+ // setups. You may be looking for `ignoreDevErrors` instead.
+ // !! WARN !!
+ ignoreBuildErrors: true,
+ },
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/introduction.md b/docs/api-reference/next.config.js/introduction.md
new file mode 100644
index 00000000000000..e9fd3f681694fb
--- /dev/null
+++ b/docs/api-reference/next.config.js/introduction.md
@@ -0,0 +1,51 @@
+---
+description: learn more about the configuration file used by Next.js to handle your application.
+---
+
+# next.config.js
+
+For custom advanced behavior of Next.js, you can create a `next.config.js` in the root of your project directory (next to `package.json`).
+
+`next.config.js` is a regular Node.js module, not a JSON file. It gets used by the Next.js server and build phases, and it's not included in the browser build.
+
+Take a look at the following `next.config.js` example:
+
+```js
+module.exports = {
+ /* config options here */
+}
+```
+
+You can also use a function:
+
+```js
+module.exports = (phase, { defaultConfig }) => {
+ return {
+ /* config options here */
+ }
+}
+```
+
+`phase` is the current context in which the configuration is loaded. You can see the available phases [here](https://github.com/zeit/next.js/blob/canary/packages/next/next-server/lib/constants.ts#L1-L4). Phases can be imported from `next/constants`:
+
+```js
+const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
+
+module.exports = (phase, { defaultConfig }) => {
+ if (phase === PHASE_DEVELOPMENT_SERVER) {
+ return {
+ /* development only config options here */
+ }
+ }
+
+ return {
+ /* config options for all phases except development here */
+ }
+}
+```
+
+The commented lines are the place where you can put the configs allowed by `next.config.js`, which are defined [here](https://github.com/zeit/next.js/blob/canary/packages/next/next-server/server/config.ts#L12-L63).
+
+However, none of the configs are required, and it's not necessary to understand what each config does, instead, search for the features you need to enable or modify in this section and they will show you what to do.
+
+> Avoid using new JavaScript features not available in your target Node.js version. `next.config.js` will not be parsed by Webpack, Babel or TypeScript.
diff --git a/docs/api-reference/next.config.js/runtime-configuration.md b/docs/api-reference/next.config.js/runtime-configuration.md
new file mode 100644
index 00000000000000..4a4a2a5ace6e1e
--- /dev/null
+++ b/docs/api-reference/next.config.js/runtime-configuration.md
@@ -0,0 +1,70 @@
+---
+description: Add client and server runtime configuration to your Next.js app.
+---
+
+# Runtime Configuration
+
+> Generally you'll want to use [build-time environment variables](/docs/api-reference/next.config.js/environment-variables.md) to provide your configuration. The reason for this is that runtime configuration adds rendering / initialization overhead and is incompatible with [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).
+
+> Runtime configuration is not available when using the [`serverless` target](/docs/api-reference/next.config.js/build-target.md#serverless-target).
+
+To add runtime configuration to your app open `next.config.js` and add the `publicRuntimeConfig` and `serverRuntimeConfig` configs:
+
+```js
+module.exports = {
+ serverRuntimeConfig: {
+ // Will only be available on the server side
+ mySecret: 'secret',
+ secondSecret: process.env.SECOND_SECRET, // Pass through env variables
+ },
+ publicRuntimeConfig: {
+ // Will be available on both server and client
+ staticFolder: '/static',
+ },
+}
+```
+
+Place any server-only runtime config under `serverRuntimeConfig`.
+
+Anything accessible to both client and server-side code should be under `publicRuntimeConfig`.
+
+> A page that relies on `publicRuntimeConfig` **must** use `getInitialProps` to opt-out of [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md). Runtime configuration won't be available to any page (or component in a page) without `getInitialProps`.
+
+To get access to the runtime configs in your app use `next/config`, like so:
+
+```jsx
+import getConfig from 'next/config'
+
+// Only holds serverRuntimeConfig and publicRuntimeConfig
+const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
+// Will only be available on the server-side
+console.log(serverRuntimeConfig.mySecret)
+// Will be available on both server-side and client-side
+console.log(publicRuntimeConfig.staticFolder)
+
+function MyImage() {
+ return (
+
diff --git a/docs/api-reference/next.config.js/setting-a-custom-build-directory.md b/docs/api-reference/next.config.js/setting-a-custom-build-directory.md
new file mode 100644
index 00000000000000..47e269bfa9e6da
--- /dev/null
+++ b/docs/api-reference/next.config.js/setting-a-custom-build-directory.md
@@ -0,0 +1,28 @@
+---
+description: Set a custom build directory to use instead of the default .next directory.
+---
+
+# Setting a custom build directory
+
+You can specify a name to use for a custom build directory to use instead of `.next`.
+
+Open `next.config.js` and add the `distDir` config:
+
+```js
+module.exports = {
+ distDir: 'build',
+}
+```
+
+Now if you run `next build` Next.js will use `build` instead of the default `.next` folder.
+
+> `distDir` **should not** leave your project directory. For example, `../build` is an **invalid** directory.
+
+## Related
+
+
diff --git a/docs/api-reference/next.config.js/static-optimization-indicator.md b/docs/api-reference/next.config.js/static-optimization-indicator.md
new file mode 100644
index 00000000000000..7ef296f9c36f98
--- /dev/null
+++ b/docs/api-reference/next.config.js/static-optimization-indicator.md
@@ -0,0 +1,35 @@
+---
+description: Optimized pages include an indicator to let you know if it's being statically optimized. You can opt-out of it here.
+---
+
+# Static Optimization Indicator
+
+When a page qualifies for [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) we show an indicator to let you know.
+
+This is helpful since automatic static optimization can be very beneficial and knowing immediately in development if the page qualifies can be useful.
+
+In some cases this indicator might not be useful, like when working on electron applications. To remove it open `next.config.js` and disable the `autoPrerender` config in `devIndicators`:
+
+```js
+module.exports = {
+ devIndicators: {
+ autoPrerender: false,
+ },
+}
+```
+
+## Related
+
+
diff --git a/docs/api-reference/next/amp.md b/docs/api-reference/next/amp.md
new file mode 100644
index 00000000000000..a5fd080b2fd5d9
--- /dev/null
+++ b/docs/api-reference/next/amp.md
@@ -0,0 +1,87 @@
+---
+description: Enable AMP in a page, and control the way Next.js adds AMP to the page with the AMP config.
+---
+
+# next/amp
+
+
+ Examples
+
+
+
+> AMP support is one of our advanced features, you can read more about it [here](/docs/advanced-features/amp-support/introduction.md).
+
+To enable AMP, add the following config to your page:
+
+```jsx
+export const config = { amp: true }
+```
+
+The `amp` config accepts the following values:
+
+- `true` - The page will be AMP-only
+- `'hybrid'` - The page will two versions, one with AMP and another one with HTML
+
+To learn more about the `amp` config, read the sections below.
+
+## AMP First Page
+
+Take a look at the following example:
+
+```jsx
+export const config = { amp: true }
+
+function About(props) {
+ return
My AMP About Page!
+}
+
+export default About
+```
+
+The page above is an AMP-only page, which means:
+
+- The page has no Next.js or React client-side runtime
+- The page is 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%)
+- The page has an user-accessible (optimized) version of the page and a search-engine indexable (unoptimized) version of the page
+
+## Hybrid AMP Page
+
+Take a look at the following example:
+
+```jsx
+import { useAmp } from 'next/amp'
+
+export const config = { amp: 'hybrid' }
+
+function About(props) {
+ const isAmp = useAmp()
+
+ return (
+
+
My AMP About Page!
+ {isAmp ? (
+
+ ) : (
+
+ )}
+
+ )
+}
+
+export default About
+```
+
+The page above is a hybrid AMP page, which means:
+
+- The page is rendered as traditional HTML (default) and AMP HTML (by adding `?amp=1` to the URL)
+- The AMP version of the page only has valid optimizations applied with AMP Optimizer so that it is indexable by search-engines
+
+The page uses `useAmp` to differentiate between modes, it's a [React Hook](https://reactjs.org/docs/hooks-intro.html) that returns `true` if the page is using AMP, and `false` otherwise.
diff --git a/docs/api-reference/next/head.md b/docs/api-reference/next/head.md
new file mode 100644
index 00000000000000..802e7563b995d0
--- /dev/null
+++ b/docs/api-reference/next/head.md
@@ -0,0 +1,70 @@
+---
+description: Add custom elements to the `head` of your page with the built-in Head component.
+---
+
+# next/head
+
+
+ Examples
+
+
+
+We expose a built-in component for appending elements to the `head` of the page:
+
+```jsx
+import Head from 'next/head'
+
+function IndexPage() {
+ return (
+
+
+ My page title
+
+
+
Hello world!
+
+ )
+}
+
+export default IndexPage
+```
+
+To avoid duplicate tags in your `head` you can use the `key` property, which will make sure the tag is only rendered once, as in the following example:
+
+```jsx
+import Head from 'next/head'
+
+function IndexPage() {
+ return (
+
+
+ My page title
+
+
+
+
+
+
Hello world!
+
+ )
+}
+
+export default IndexPage
+```
+
+In this case only the second `` is rendered.
+
+> 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.
+
+> `title` and `meta` elements need to be contained as **direct** children of the `Head` element, or wrapped into maximum one level of ``, otherwise the meta tags won't be correctly picked up on client-side navigations.
diff --git a/docs/api-reference/next/link.md b/docs/api-reference/next/link.md
new file mode 100644
index 00000000000000..832963e96137ea
--- /dev/null
+++ b/docs/api-reference/next/link.md
@@ -0,0 +1,184 @@
+---
+description: Enable client-side transitions between routes with the built-in Link component.
+---
+
+# next/link
+
+
+ Examples
+
+
+
+> Before moving forward, we recommend you to read [Routing Introduction](/docs/routing/introduction.md) first.
+
+Client-side transitions between routes can be enabled via the `Link` component exported by `next/link`.
+
+An example of linking to `/` and `/about`:
+
+```jsx
+import Link from 'next/link'
+
+function Home() {
+ return (
+
+ )
+}
+
+export default Home
+```
+
+The above example will be a link to `/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).
+
+## Replace the URL instead of push
+
+The default behavior of the `Link` component is to `push` a new URL into the `history` stack. You can use the `replace` prop to prevent adding a new entry, as in the following example:
+
+```jsx
+
+ About us
+
+```
+
+## Using a component that supports `onClick`
+
+`Link` supports any component that supports the `onClick` event, in the case you don't provide an `` tag, consider the following example:
+
+```jsx
+
+
+
+```
+
+The child of `Link` is `` instead of ``. `Link` will send the `onClick` property to `` but won't pass the `href` property.
+
+## Disable scrolling to the top of the page
+
+The default behavior 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 `` tag. To prevent scrolling to the top / hash `scroll={false}` can be added to `Link`:
+
+```jsx
+
+ Disables scrolling to the top
+
+```
diff --git a/docs/api-reference/next/router.md b/docs/api-reference/next/router.md
new file mode 100644
index 00000000000000..39cd2e66d0f543
--- /dev/null
+++ b/docs/api-reference/next/router.md
@@ -0,0 +1,255 @@
+---
+description: Learn more about the API of the Next.js Router, and access the router instance in your page with the useRouter hook.
+---
+
+# next/router
+
+> Before moving forward, we recommend you to read [Routing Introduction](/docs/routing/introduction.md) first.
+
+## useRouter
+
+If you want to access the [`router` object](#router-object) inside any function component in your app, you can use the `useRouter` hook, take a look at the following example:
+
+```jsx
+import { useRouter } from 'next/router'
+
+function ActiveLink({ children, href }) {
+ const router = useRouter()
+ const style = {
+ marginRight: 10,
+ color: router.pathname === href ? 'red' : 'black',
+ }
+
+ const handleClick = e => {
+ e.preventDefault()
+ router.push(href)
+ }
+
+ return (
+
+ {children}
+
+ )
+}
+
+export default ActiveLink
+```
+
+> `useRouter` is a [React Hook](https://reactjs.org/docs/hooks-intro.html), meaning it cannot be used with classes. You can either use [withRouter](#withRouter) or wrap your class in a function component.
+
+### router object
+
+The following is the definition of the `router` object returned by both [`useRouter`](#useRouter) and [`withRouter`](#withRouter):
+
+- `pathname`: `String` - Current route. That is the path of the page in `/pages`
+- `query`: `Object` - The query string parsed to an object. Defaults to `{}`
+- `asPath`: `String` - Actual path (including the query) shown in the browser
+
+Additionally, the [`Router API`](#router-api) is also included inside the object.
+
+> The `query` object will be empty during prerendering if the page is [statically optimized](/docs/advanced-features/automatic-static-optimization.md).
+
+## withRouter
+
+If [`useRouter`](#useRouter) is not the best fit for you, `withRouter` can also add the same [`router` object](#router-object) to any component, here's how to use it:
+
+```jsx
+import { withRouter } from 'next/router'
+
+function Page({ router }) {
+ return
{router.pathname}
+}
+
+export default withRouter(Page)
+```
+
+## Router API
+
+The API of `Router`, exported by `next/router`, is defined below.
+
+### Router.push
+
+
+ Examples
+
+
+
+Handles client-side transitions, this method is useful for cases where [`next/link`](/docs/api-reference/next/link.md) is not enough.
+
+```jsx
+import Router from 'next/router'
+
+Router.push(url, as, options)
+```
+
+- `url` - The URL to navigate to. This is usually the name of a `page`
+- `as` - Optional decorator for the URL that will be shown in the browser. Defaults to `url`
+- `options` - Optional object with the following configuration options:
+ - [`shallow`](/docs/routing/shallow-routing.md): Update the path of the current page without rerunning `getInitialProps`. Defaults to `false`
+
+> You don't need to use `Router` for external URLs, [window.location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location) is better suited for those cases.
+
+#### Usage
+
+Navigating to `pages/about.js`, which is a predefined route:
+
+```jsx
+import Router from 'next/router'
+
+function Page() {
+ return Router.push('/about')}>Click me
+}
+```
+
+Navigating `pages/post/[pid].js`, which is a dynamic route:
+
+```jsx
+import Router from 'next/router'
+
+function Page() {
+ return (
+ Router.push('/post/[pid]', '/post/abc')}>
+ Click me
+
+ )
+}
+```
+
+#### With URL object
+
+You can use an URL object in the same way you can use it for [`next/link`](/docs/api-reference/next/link.md#with-url-object). Works for both the `url` and `as` parameters:
+
+```jsx
+import Router from 'next/router'
+
+const handler = () => {
+ Router.push({
+ pathname: '/about',
+ query: { name: 'Zeit' },
+ })
+}
+
+function ReadMore() {
+ return (
+
+ Click here to read more
+
+ )
+}
+
+export default ReadMore
+```
+
+### Router.replace
+
+Similar to the `replace` prop in [`next/link`](/docs/api-reference/next/link.md), `Router.replace` will prevent adding a new URL entry into the `history` stack, take a look at the following example:
+
+```jsx
+import Router from 'next/router'
+
+Router.replace('/home')
+```
+
+The API for `Router.replace` is exactly the same as that used for [`Router.push`](#router.push).
+
+### Router.beforePopState
+
+In some cases (for example, if using a [Custom Server](/docs/advanced-features/custom-server.md)), you may wish to listen to [popstate](https://developer.mozilla.org/en-US/docs/Web/Events/popstate) and do something before the router acts on it.
+
+You could use this to manipulate the request, or force a SSR refresh, as in the following example:
+
+```jsx
+import Router from 'next/router'
+
+Router.beforePopState(({ url, as, options }) => {
+ // I only want to allow these two routes!
+ if (as !== '/' && as !== '/other') {
+ // Have SSR render bad routes as a 404.
+ window.location.href = as
+ return false
+ }
+
+ return true
+})
+```
+
+`Router.beforePopState(cb: () => boolean)`
+
+- `cb` - The function to execute on incoming `popstate` events. The function receives the state of the event as an object with the following props:
+ - `url`: `String` - the route for the new state. This is usually the name of a `page`
+ - `as`: `String` - the url that will be shown in the browser
+ - `options`: `Object` - Additional options sent by [Router.push](#router.push)
+
+If the function you pass into `beforePopState` returns `false`, `Router` will not handle `popstate` and you'll be responsible for handling it, in that case. See [Disabling file-system routing](/docs/advanced-features/custom-server.md#disabling-file-system-routing).
+
+### Router.events
+
+
+ Examples
+
+
+
+You can listen to different events happening inside the Router. Here's a list of supported events:
+
+- `routeChangeStart(url)` - Fires when a route starts to change
+- `routeChangeComplete(url)` - Fires when a route changed completely
+- `routeChangeError(err, url)` - Fires when there's an error when changing routes, or a route load is cancelled
+ - `err.cancelled` - Indicates if the navigation was cancelled
+- `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
+
+> 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`.
+
+For example, to listen to the router event `routeChangeStart`, do the following:
+
+```jsx
+import Router from 'next/router'
+
+const handleRouteChange = url => {
+ console.log('App is changing to: ', url)
+}
+
+Router.events.on('routeChangeStart', handleRouteChange)
+```
+
+If you no longer want to listen to the event, unsubscribe with the `off` method:
+
+```jsx
+import Router from 'next/router'
+
+Router.events.off('routeChangeStart', handleRouteChange)
+```
+
+If a route load is cancelled (for example, by clicking two links rapidly in succession), `routeChangeError` will fire. And the passed `err` will contain a `cancelled` property set to `true`, as in the following example:
+
+```jsx
+import Router from 'next/router'
+
+Router.events.on('routeChangeError', (err, url) => {
+ if (err.cancelled) {
+ console.log(`Route to ${url} was cancelled!`)
+ }
+})
+```
+
+Router events should be registered when a component mounts ([useEffect](https://reactjs.org/docs/hooks-effect.html) or [componentDidMount](https://reactjs.org/docs/react-component.html#componentdidmount) / [componentWillUnmount](https://reactjs.org/docs/react-component.html#componentwillunmount)) or imperatively when an event happens, as in the following example:
+
+```jsx
+import Router from 'next/router'
+
+useEffect(() => {
+ const handleRouteChange = url => {
+ console.log('App is changing to: ', url)
+ }
+
+ Router.events.on('routeChangeStart', handleRouteChange)
+ return () => {
+ Router.events.off('routeChangeStart', handleRouteChange)
+ }
+}, [])
+```
diff --git a/docs/api-routes/api-middlewares.md b/docs/api-routes/api-middlewares.md
new file mode 100644
index 00000000000000..a73199a181fa0c
--- /dev/null
+++ b/docs/api-routes/api-middlewares.md
@@ -0,0 +1,98 @@
+---
+description: API Routes provide built-in middlewares that parse the incoming request. Learn more about them here.
+---
+
+# API Middlewares
+
+API routes provide built in middlewares which parse the incoming request (`req`). Those middlewares are:
+
+- `req.cookies` - An object containing the cookies sent by the request. Defaults to `{}`
+- `req.query` - An object containing the [query string](https://en.wikipedia.org/wiki/Query_string). Defaults to `{}`
+- `req.body` - An object containing the body parsed by `content-type`, or `null` if no body was sent
+
+## Custom config
+
+Every API route can export a `config` object to change the default configs, which are the following:
+
+```js
+export const config = {
+ api: {
+ bodyParser: {
+ sizeLimit: '1mb',
+ },
+ },
+}
+```
+
+The `api` object includes all configs available for API routes.
+
+`bodyParser` Enables body parsing, you can disable it if you want to consume it as a `Stream`:
+
+```js
+export const config = {
+ api: {
+ bodyParser: false,
+ },
+}
+```
+
+`bodyParser.sizeLimit` is the maximum size allowed for the parsed body, in any format supported by [bytes](https://github.com/visionmedia/bytes.js), like so:
+
+```js
+export const config = {
+ api: {
+ bodyParser: {
+ sizeLimit: '500kb',
+ },
+ },
+}
+```
+
+## Connect/Express middleware support
+
+You can also use [Connect](https://github.com/senchalabs/connect) compatible middleware.
+
+For example, [configuring CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) for your API endpoint can be done leveraging the [cors](https://www.npmjs.com/package/cors) package.
+
+First, install `cors`:
+
+```bash
+npm i cors
+# or
+yarn add cors
+```
+
+Now, let's add `cors` to the API route:
+
+```js
+import Cors from 'cors'
+
+// Initializing the cors middleware
+const cors = Cors({
+ methods: ['GET', 'HEAD'],
+})
+
+// Helper method to wait for a middleware to execute before continuing
+// And to throw an error when an error happens in a middleware
+function runMiddleware(req, res, fn) {
+ return new Promise((resolve, reject) => {
+ fn(req, res, result => {
+ if (result instanceof Error) {
+ return reject(result)
+ }
+
+ return resolve(result)
+ })
+ })
+}
+
+async function handler(req, res) {
+ // Run the middleware
+ await runMiddleware(req, res, cors)
+
+ // Rest of the API logic
+ res.json({ message: 'Hello Everyone!' })
+}
+
+export default handler
+```
diff --git a/docs/api-routes/dynamic-api-routes.md b/docs/api-routes/dynamic-api-routes.md
new file mode 100644
index 00000000000000..fe700be588a872
--- /dev/null
+++ b/docs/api-routes/dynamic-api-routes.md
@@ -0,0 +1,62 @@
+---
+description: You can add the dynamic routes used for pages to API Routes too. Learn how it works here.
+---
+
+# Dynamic API Routes
+
+API routes support [dynamic routes](/docs/routing/dynamic-routes.md), and follow the same file naming rules used for `pages`.
+
+For example, the API route `pages/api/post/[pid].js` has the following code:
+
+```js
+export default (req, res) => {
+ const {
+ query: { pid },
+ } = req
+
+ res.end(`Post: ${pid}`)
+}
+```
+
+Now, a request to `/api/post/abc` will respond with the text: `Post: abc`.
+
+### Catch all API routes
+
+API Routes can be extended to catch all paths by adding three dots (`...`) inside the brackets. For example:
+
+- `pages/api/post/[...slug].js` matches `/api/post/a`, but also `/api/post/a/b`, `/api/post/a/b/c` and so on.
+
+> **Note**: You can use names other than `slug`, such as: `[...param]`
+
+Matched parameters will be sent as a query parameter (`slug` in the example) to the page, and it will always be an array, so, the path `/api/post/a` will have the following `query` object:
+
+```json
+{ "slug": ["a"] }
+```
+
+And in the case of `/api/post/a/b`, and any other matching path, new parameters will be added to the array, like so:
+
+```json
+{ "slug": ["a", "b"] }
+```
+
+An API route for `pages/api/post/[...slug].js` could look like this:
+
+```js
+export default (req, res) => {
+ const {
+ query: { slug },
+ } = req
+
+ res.end(`Post: ${slug.join(', ')}`)
+}
+```
+
+Now, a request to `/api/post/a/b/c` will respond with the text: `Post: a, b, c`.
+
+## Caveats
+
+- Predefined API routes take precedence over dynamic API routes, and dynamic API routes over catch all API routes. Take a look at the following examples:
+ - `pages/api/post/create.js` - Will match `/api/post/create`
+ - `pages/api/post/[pid].js` - Will match `/api/post/1`, `/api/post/abc`, etc. But not `/api/post/create`
+ - `pages/api/post/[...slug].js` - Will match `/api/post/1/2`, `/api/post/a/b/c`, etc. But not `/api/post/create`, `/api/post/abc`
diff --git a/docs/api-routes/introduction.md b/docs/api-routes/introduction.md
new file mode 100644
index 00000000000000..7e828e06a048be
--- /dev/null
+++ b/docs/api-routes/introduction.md
@@ -0,0 +1,78 @@
+---
+description: Next.js supports API Routes, which allow you to build your API without leaving your Next.js app. Learn how it works here.
+---
+
+# API Routes
+
+
+ Examples
+
+
+
+API routes provide a straightforward solution to build your **API** with Next.js.
+
+Any file inside the folder `pages/api` is mapped to `/api/*` and will be treated as an API endpoint instead of a `page`.
+
+For example, the following API route `pages/api/user.js` handles a simple `json` response:
+
+```js
+export default (req, res) => {
+ res.statusCode = 200
+ res.setHeader('Content-Type', 'application/json')
+ res.end(JSON.stringify({ name: 'John Doe' }))
+}
+```
+
+For an API route to work, you need to export as default a function (a.k.a **request handler**), which then receives the following parameters:
+
+- `req`: An instance of [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage), plus some pre-built middlewares you can see [here](/docs/api-routes/api-middlewares.md)
+- `res`: An instance of [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse), plus some helper functions you can see [here](/docs/api-routes/response-helpers.md)
+
+To handle different HTTP methods in an API route, you can use `req.method` in your request handler, like so:
+
+```js
+export default (req, res) => {
+ if (req.method === 'POST') {
+ // Process a POST request
+ } else {
+ // Handle any other HTTP method
+ }
+}
+```
+
+To fetch API endpoints, take a look into any of the examples at the start of this section.
+
+> API Routes [do not specify CORS headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), meaning they are **same-origin only** by default. You can customize such behavior by wrapping the request handler with the [cors middleware](/docs/api-routes/api-middlewares.md#connectexpress-middleware-support).
+
+> API Routes do not increase your client-side bundle size. They are server-side only bundles.
+
+## Related
+
+For more information on what to do next, we recommend the following sections:
+
+
diff --git a/docs/api-routes/response-helpers.md b/docs/api-routes/response-helpers.md
new file mode 100644
index 00000000000000..9039bd0a60e696
--- /dev/null
+++ b/docs/api-routes/response-helpers.md
@@ -0,0 +1,19 @@
+---
+description: API Routes include a set of Express.js-like methods for the response to help you creating new API endpoints. Learn how it works here.
+---
+
+# Response Helpers
+
+The response (`res`) includes a set of Express.js-like methods to improve the developer experience and increase the speed of creating new API endpoints, take a look at the following example:
+
+```js
+export default (req, res) => {
+ res.status(200).json({ name: 'Next.js' })
+}
+```
+
+The included helpers are:
+
+- `res.status(code)` - A function to set the status code. `code` must be a valid [HTTP status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
+- `res.json(json)` - Sends a JSON response. `json` must be a valid JSON object
+- `res.send(body)` - Sends the HTTP response. `body` can be a `string`, an `object` or a `Buffer`
diff --git a/docs/basic-features/built-in-css-support.md b/docs/basic-features/built-in-css-support.md
new file mode 100644
index 00000000000000..0e17247a7d81a2
--- /dev/null
+++ b/docs/basic-features/built-in-css-support.md
@@ -0,0 +1,190 @@
+---
+description: Next.js supports including CSS files as Global CSS or CSS Modules, using `styled-jsx` for CSS-in-JS, or any other CSS-in-JS solution! Learn more here.
+---
+
+# Built-In CSS Support
+
+Next.js allows you to import CSS files from a JavaScript file.
+This is possible because Next.js extends the concept of [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) beyond JavaScript.
+
+## Adding a Global Stylesheet
+
+To add a stylesheet to your application, import the CSS file within `pages/_app.js`.
+
+For example, consider the following stylesheet named `styles.css`:
+
+```css
+body {
+ font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
+ 'Arial', sans-serif;
+ padding: 20px 20px 60px;
+ max-width: 680px;
+ margin: 0 auto;
+}
+```
+
+Create a [`pages/_app.js` file](/docs/advanced-features/custom-app) if not already present.
+Then, [`import`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) the `styles.css` file.
+
+```jsx
+import '../styles.css'
+
+// This default export is required in a new `pages/_app.js` file.
+export default function MyApp({ Component, pageProps }) {
+ return
+}
+```
+
+These styles (`styles.css`) will apply to all pages and components in your application.
+Due to the global nature of stylesheets, and to avoid conflicts, you may **only import them inside [`pages/_app.js`](/docs/advanced-features/custom-app)**.
+
+In development, expressing stylesheets this way allows your styles to be hot reloaded as you edit them—meaning you can keep application state.
+
+In production, all CSS files will be automatically concatenated into a single minified `.css` file.
+
+## Adding Component-Level CSS
+
+Next.js supports [CSS Modules](https://github.com/css-modules/css-modules) using the `[name].module.css` file naming convention.
+
+CSS Modules locally scope CSS by automatically creating a unique class name.
+This allows you to use the same CSS class name in different files without worrying about collisions.
+
+This behavior makes CSS Modules the ideal way to include component-level CSS.
+CSS Module files **can be imported anywhere in your application**.
+
+For example, consider a reusable `Button` component in the `components/` folder:
+
+First, create `components/Button.module.css` with the following content:
+
+```css
+/*
+You do not need to worry about .error {} colliding with any other `.css` or
+`.module.css` files!
+*/
+.error {
+ color: white;
+ background-color: red;
+}
+```
+
+Then, create `components/Button.js`, importing and using the above CSS file:
+
+```jsx
+import styles from './Button.module.css'
+
+export function Button() {
+ return (
+
+ )
+}
+```
+
+CSS Modules are an _optional feature_ and are **only enabled for files with the `.module.css` extension**.
+Regular `` stylesheets and global CSS files are still supported.
+
+In production, all CSS Module files will be automatically concatenated into **many minified and code-split** `.css` files.
+These `.css` files represent hot execution paths in your application, ensuring the minimal amount of CSS is loaded for your application to paint.
+
+## CSS-in-JS
+
+
+ Examples
+
+
+
+It's possible to use any existing CSS-in-JS solution.
+The simplest one is inline styles:
+
+```jsx
+function HiThere() {
+ return
hi there
+}
+
+export default HiThere
+```
+
+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).
+
+See the above examples for other popular CSS-in-JS solutions (like Styled Components).
+
+A component using `styled-jsx` looks like this:
+
+```jsx
+function HelloWorld() {
+ return (
+
+ Hello world
+
scoped!
+
+
+
+ )
+}
+
+export default HelloWorld
+```
+
+Please see the [styled-jsx documentation](https://github.com/zeit/styled-jsx) for more examples.
+
+## Sass Support
+
+Next.js allows you to import Sass using both the `.scss` and `.sass` extensions.
+You can use component-level Sass via CSS Modules and the `.module.scss` or `.module.sass` extension.
+
+Before you can use Next.js' built-in Sass support, be sure to install [`sass`](https://github.com/sass/sass):
+
+```bash
+npm install sass
+```
+
+Sass support has the same benefits and restrictions as the built-in CSS support detailed above.
+
+## Less and Stylus Support
+
+To support importing `.less` or `.styl` files you can use the following plugins:
+
+- [@zeit/next-less](https://github.com/zeit/next-plugins/tree/master/packages/next-less)
+- [@zeit/next-stylus](https://github.com/zeit/next-plugins/tree/master/packages/next-stylus)
+
+## Related
+
+For more information on what to do next, we recommend the following sections:
+
+
diff --git a/docs/basic-features/data-fetching.md b/docs/basic-features/data-fetching.md
new file mode 100644
index 00000000000000..ac7e6f2ed47936
--- /dev/null
+++ b/docs/basic-features/data-fetching.md
@@ -0,0 +1,518 @@
+---
+description: 'Next.js has 2 pre-rendering modes: Static Generation and Server-side rendering. Learn how they work here.'
+---
+
+# Data fetching
+
+> This document is for Next.js versions 9.3 and up. If you’re using older versions of Next.js, refer to our [previous documentation](https://nextjs.org/docs/tag/v9.2.2/basic-features/data-fetching).
+
+In the [Pages documentation](/docs/basic-features/pages.md), we’ve explained that Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. In this page, we’ll talk in depths about data fetching strategies for each case. We recommend you to [read through the Pages documentation](/docs/basic-features/pages.md) first if you haven’t done so.
+
+We’ll talk about the three special Next.js functions you can use to fetch data for pre-rendering:
+
+- `getStaticProps` (Static Generation): Fetch data at **build time**.
+- `getStaticPaths` (Static Generation): Specify [dynamic routes](/docs/routing/dynamic-routes.md) to pre-render based on data.
+- `getServerSideProps` (Server-side Rendering): Fetch data on **each request**.
+
+In addition, we’ll talk briefly about how to do fetch data on the client side.
+
+## `getStaticProps` (Static Generation)
+
+If you export an `async` function called `getStaticProps` from a page, Next.js will pre-render this page at build time using the props returned by `getStaticProps`.
+
+```jsx
+export async function getStaticProps(context) {
+ return {
+ props: {}, // will be passed to the page component as props
+ }
+}
+```
+
+The `context` parameter is an object containing the following keys:
+
+- `params` contains the route parameters for pages using dynamic routes. For example, if the page name is `[id].js` , then `params` will look like `{ id: ... }`. To learn more, take a look at the [Dynamic Routing documentation](/docs/routing/dynamic-routes.md). You should use this together with `getStaticPaths`, which we’ll explain later.
+- `preview` is `true` if the page is in the preview mode and `false` otherwise. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md).
+- `previewData` contains the preview data set by `setPreviewData`. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md).
+
+### Simple Example
+
+Here’s an example which uses `getStaticProps` to fetch a list of blog posts from a CMS (content management system). This example is also in the [Pages documentation](/docs/basic-features/pages.md).
+
+```jsx
+// You can use any data fetching library
+import fetch from 'node-fetch'
+
+// posts will be populated at build time by getStaticProps()
+function Blog({ posts }) {
+ return (
+
+ {posts.map(post => (
+
{post.title}
+ ))}
+
+ )
+}
+
+// This function gets called at build time on server-side.
+// It won't be called on client-side, so you can even do
+// direct database queries. See the "Technical details" section.
+export async function getStaticProps() {
+ // Call an external API endpoint to get posts.
+ const res = await fetch('https://.../posts')
+ const posts = await res.json()
+
+ // By returning { props: posts }, the Blog component
+ // will receive `posts` as a prop at build time
+ return {
+ props: {
+ posts,
+ },
+ }
+}
+
+export default Blog
+```
+
+### When should I use `getStaticProps`?
+
+You should use `getStaticProps` if:
+
+- The data required to render the page is available at build time ahead of a user’s request.
+- The data comes from headless CMS.
+- The data can be publicly cached (not user-specific).
+- The page must be pre-rendered (for SEO) and be very fast — `getStaticProps` generates HTML and JSON files, both of which can be cached by a CDN for performance.
+
+### TypeScript: Use `GetStaticProps`
+
+For TypeScript, you can use the `GetStaticProps` type from `next`:
+
+```ts
+import { GetStaticProps } from 'next'
+
+export const getStaticProps: GetStaticProps = async context => {
+ // ...
+}
+```
+
+### Reading files: Use `process.cwd()`
+
+Files can be read directly from the filesystem in `getStaticProps`.
+
+In order to do so you have to get the full path to a file.
+
+Since Next.js compiles your code into a separate directory you can't use `__dirname` as the path it will return will be different from the pages directory.
+
+Instead you can use `process.cwd()` which gives you the directory where Next.js is being executed.
+
+```jsx
+import fs from 'fs'
+import path from 'path'
+
+// posts will be populated at build time by getStaticProps()
+function Blog({ posts }) {
+ return (
+
+ {posts.map(post => (
+
+
{post.filename}
+
{post.content}
+
+ ))}
+
+ )
+}
+
+// This function gets called at build time on server-side.
+// It won't be called on client-side, so you can even do
+// direct database queries. See the "Technical details" section.
+export async function getStaticProps() {
+ const postsDirectory = path.join(process.cwd(), 'posts')
+ const filenames = fs.readdirSync(postsDirectory)
+
+ const posts = filenames.map(filename => {
+ const filePath = path.join(postsDirectory, filename)
+ const fileContents = fs.readFileSync(filePath, 'utf8')
+
+ // Generally you would parse/transform the contents
+ // For example you can transform markdown to HTML here
+
+ return {
+ filename,
+ content: fileContents,
+ }
+ })
+ // By returning { props: posts }, the Blog component
+ // will receive `posts` as a prop at build time
+ return {
+ props: {
+ posts,
+ },
+ }
+}
+
+export default Blog
+```
+
+### Technical details
+
+#### Only runs at build time
+
+Because `getStaticProps` runs at build time, it does **not** receive data that’s only available during request time, such as query parameters or HTTP headers as it generates static HTML.
+
+#### Write server-side code directly
+
+Note that `getStaticProps` runs only on the server-side. It will never be run on the client-side. It won’t even be included in the JS bundle for the browser. That means you can write code such as direct database queries without them being sent to browsers. You should not fetch an **API route** from `getStaticProps` — instead, you can write the server-side code directly in `getStaticProps`.
+
+#### Statically Generates both HTML and JSON
+
+When a page with `getStaticProps` is pre-rendered at build time, in addition to the page HTML file, Next.js generates a JSON file holding the result of running `getStaticProps`.
+
+This JSON file will be used in client-side routing through `next/link` ([documentation](/docs/api-reference/next/link.md)) or `next/router` ([documentation](/docs/api-reference/next/router.md)). When you navigate to a page that’s pre-rendered using `getStaticProps`, Next.js fetches this JSON file (pre-computed at build time) and uses it as the props for the page component. This means that client-side page transitions will **not** call `getStaticProps` as only the exported JSON is used.
+
+#### Only allowed in a page
+
+`getStaticProps` can only be exported from a **page**. You can’t export it from non-page files.
+
+One of the reasons for this restriction is that React needs to have all the required data before the page is rendered.
+
+Also, you must use `export async function getStaticProps() {}` — it will **not** work if you add `getStaticProps` as a property of the page component.
+
+#### Runs on every request in development
+
+In development (`next dev`), `getStaticProps` will be called on every request.
+
+#### Preview Mode
+
+In some cases, you might want to temporarily bypass Static Generation and render the page at **request time** instead of build time. For example, you might be using a headless CMS and want to preview drafts before they're published.
+
+This use case is supported by Next.js by the feature called **Preview Mode**. Learn more on the [Preview Mode documentation](/docs/advanced-features/preview-mode.md).
+
+## `getStaticPaths` (Static Generation)
+
+If a page has dynamic routes ([documentation](/docs/routing/dynamic-routes.md)) and uses `getStaticProps` it needs to define a list of paths that have to be rendered to HTML at build time.
+
+If you export an `async` function called `getStaticPaths` from a page that uses dynamic routes, Next.js will statically pre-render all the paths specified by `getStaticPaths`.
+
+```jsx
+export async function getStaticPaths() {
+ return {
+ paths: [
+ { params: { ... } } // See the "paths" section below
+ ],
+ fallback: true or false // See the "fallback" section below
+ };
+}
+```
+
+#### The `paths` key (required)
+
+The `paths` key determines which paths will be pre-rendered. For example, suppose that you have a page that uses dynamic routes named `pages/posts/[id].js`. If you export `getStaticPaths` from this page and return the following for `paths`:
+
+```js
+return {
+ paths: [
+ { params: { id: '1' } },
+ { params: { id: '2' } }
+ ],
+ fallback: ...
+}
+```
+
+Then Next.js will statically generate `posts/1` and `posts/2` at build time using the page component in `pages/posts/[id].js`.
+
+Note that the value for each `params` must match the parameters used in the page name:
+
+- If the page name is `pages/posts/[postId]/[commentId]`, then `params` should contain `postId` and `commentId`.
+- If the page name uses catch-all routes, for example `pages/[...slug]`, then `params` should contain `slug` which is an array. For example, if this array is `['foo', 'bar']`, then Next.js will statically generate the page at `/foo/bar`.
+
+#### The `fallback` key (required)
+
+The object returned by `getStaticPaths` must contain a boolean `fallback` key.
+
+#### `fallback: false`
+
+If `fallback` is `false`, then any paths not returned by `getStaticPaths` will result in a **404 page**. You can do this if you have a small number of paths to pre-render - so they are all statically generated during build time. It’s also useful when the new pages are not added often. If you add more items to the data source and need to render the new pages, you’d need to run the build again.
+
+Here’s an example which pre-renders one blog post per page called `pages/posts/[id].js`. The list of blog posts will be fetched from a CMS and returned by `getStaticPaths` . Then, for each page, it fetches the post data from a CMS using `getStaticProps`. This example is also in the [Pages documentation](/docs/basic-features/pages.md).
+
+```jsx
+// pages/posts/[id].js
+import fetch from 'node-fetch'
+
+function Post({ post }) {
+ // Render post...
+}
+
+// This function gets called at build time
+export async function getStaticPaths() {
+ // Call an external API endpoint to get posts
+ const res = await fetch('https://.../posts')
+ const posts = await res.json()
+
+ // Get the paths we want to pre-render based on posts
+ const paths = posts.map(post => ({
+ params: { id: post.id },
+ }))
+
+ // We'll pre-render only these paths at build time.
+ // { fallback: false } means other routes should 404.
+ return { paths, fallback: false }
+}
+
+// This also gets called at build time
+export async function getStaticProps({ params }) {
+ // params contains the post `id`.
+ // If the route is like /posts/1, then params.id is 1
+ const res = await fetch(`https://.../posts/${params.id}`)
+ const post = await res.json()
+
+ // Pass post data to the page via props
+ return { props: { post } }
+}
+
+export default Post
+```
+
+#### `fallback: true`
+
+If `fallback` is `true`, then the behavior of `getStaticProps` changes:
+
+- The paths returned from `getStaticPaths` will be rendered to HTML at build time.
+- The paths that have not been generated at build time will **not** result in a 404 page. Instead, Next.js will serve a “fallback” version of the page on the first request to such a path (see [“Fallback pages”](#fallback-pages) below for details).
+- In the background, Next.js will statically generate the requested path HTML and JSON. This includes running `getStaticProps`.
+- When that’s done, the browser receives the JSON for the generated path. This will be used to automatically render the page with the required props. From the user’s perspective, the page will be swapped from the fallback page to the full page.
+- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, just like other pages pre-rendered at build time.
+
+#### Fallback pages
+
+In the “fallback” version of a page:
+
+- The page’s props will be empty.
+- Using the [router](/docs/api-reference/next/router.md), you can detect if the fallback is being rendered, `router.isFallback` will be `true`.
+
+Here’s an example that uses `isFallback`:
+
+```jsx
+// pages/posts/[id].js
+import { useRouter } from 'next/router'
+import fetch from 'node-fetch'
+
+function Post({ post }) {
+ const router = useRouter()
+
+ // If the page is not yet generated, this will be displayed
+ // initially until getStaticProps() finishes running
+ if (router.isFallback) {
+ return
Loading...
+ }
+
+ // Render post...
+}
+
+// This function gets called at build time
+export async function getStaticPaths() {
+ return {
+ // Only `/posts/1` and `/posts/2` are generated at build time
+ paths: [{ params: { id: 1 } }, { params: { id: 2 } }],
+ // Enable statically generating additional pages
+ // For example: `/posts/3`
+ fallback: true,
+ }
+}
+
+// This also gets called at build time
+export async function getStaticProps({ params }) {
+ // params contains the post `id`.
+ // If the route is like /posts/1, then params.id is 1
+ const res = await fetch(`https://.../posts/${params.id}`)
+ const post = await res.json()
+
+ // Pass post data to the page via props
+ return { props: { post } }
+}
+
+export default Post
+```
+
+#### When is `fallback: true` useful?
+
+`fallback: true` is useful if your app has a very large number of static pages that depend on data (think: a very large e-commerce site). You want to pre-render all product pages, but then your builds would take forever.
+
+Instead, you may statically generate a small subset of pages and use `fallback: true` for the rest. When someone requests a page that’s not generated yet, the user will see the page with a loading indicator. Shortly after, `getStaticProps` finishes and the page will be rendered with the requested data. From now on, everyone who requests the same page will get the statically pre-rendered page.
+
+This ensures that users always have a fast experience while preserving fast builds and the benefits of Static Generation.
+
+### When should I use `getStaticPaths`?
+
+You should use `getStaticPaths` if you’re statically pre-rendering pages that use dynamic routes.
+
+### TypeScript: Use `GetStaticPaths`
+
+For TypeScript, you can use the `GetStaticPaths` type from `next`:
+
+```ts
+import { GetStaticPaths } from 'next'
+
+export const getStaticPaths: GetStaticPaths = async () => {
+ // ...
+}
+```
+
+### Technical details
+
+#### Use together with `getStaticProps`
+
+When you use `getStaticProps` on a page with dynamic route parameters, you must use `getStaticPaths`.
+
+You cannot use `getStaticPaths` with `getServerSideProps`.
+
+#### Only runs at build time on server-side
+
+`getStaticPaths` only runs at build time on server-side.
+
+#### Only allowed in a page
+
+`getStaticPaths` can only be exported from a **page**. You can’t export it from non-page files.
+
+Also, you must use `export async function getStaticPaths() {}` — it will **not** work if you add `getStaticPaths` as a property of the page component.
+
+#### Runs on every request in development
+
+In development (`next dev`), `getStaticPaths` will be called on every request.
+
+## `getServerSideProps` (Server-side Rendering)
+
+If you export an `async` function called `getServerSideProps` from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`.
+
+```js
+export async function getServerSideProps(context) {
+ return {
+ props: {}, // will be passed to the page component as props
+ }
+}
+```
+
+The `context` parameter is an object containing the following keys:
+
+- `params`: If this page uses a dynamic route, `params` contains the route parameters. If the page name is `[id].js` , then `params` will look like `{ id: ... }`. To learn more, take a look at the [Dynamic Routing documentation](/docs/routing/dynamic-routes.md).
+- `req`: [The HTTP IncomingMessage object](https://nodejs.org/api/http.html#http_class_http_incomingmessage).
+- `res`: [The HTTP response object](https://nodejs.org/api/http.html#http_class_http_serverresponse).
+- `query`: The query string.
+- `preview`: `preview` is `true` if the page is in the preview mode and `false` otherwise. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md).
+- `previewData`: The preview data set by `setPreviewData`. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md).
+
+### Simple example
+
+Here’s an example which uses `getServerSideProps` to fetch data at request time and pre-renders it. This example is also in the [Pages documentation](/docs/basic-features/pages.md).
+
+```jsx
+function Page({ data }) {
+ // Render data...
+}
+
+// This gets called on every request
+export async function getServerSideProps() {
+ // Fetch data from external API
+ const res = await fetch(`https://.../data`)
+ const data = await res.json()
+
+ // Pass data to the page via props
+ return { props: { data } }
+}
+
+export default Page
+```
+
+### When should I use `getServerSideProps`?
+
+You should use `getServerSideProps` only if you need to pre-render a page whose data must be fetched at request time. Time to first byte (TTFB) will be slower than `getStaticProps` because the server must compute the result on every request, and the result cannot be cached by a CDN without extra configuration.
+
+If you don’t need to pre-render the data, then you should consider fetching data on the client side. [Click here to learn more](#fetching-data-on-the-client-side).
+
+### TypeScript: Use `GetServerSideProps`
+
+For TypeScript, you can use the `GetServerSideProps` type from `next`:
+
+```ts
+import { GetServerSideProps } from 'next'
+
+export const getServerSideProps: GetServerSideProps = async context => {
+ // ...
+}
+```
+
+### Technical details
+
+#### Only runs on server-side
+
+`getServerSideProps` only runs on server-side and never runs on the browser. If a page uses `getServerSideProps` , then:
+
+- When you request this page directly, `getServerSideProps` runs at the request time, and this page will be pre-rendered with the returned props.
+- When you request this page on client-side page transitions through `next/link` ([documentation](/docs/api-reference/next/link.md)) or `next/router` ([documentation](/docs/api-reference/next/router.md)), Next.js sends an API request to the server, which runs `getServerSideProps`. It’ll return JSON that contains the result of running `getServerSideProps`, and the JSON will be used to render the page. All this work will be handled automatically by Next.js, so you don’t need to do anything extra as long as you have `getServerSideProps` defined.
+
+#### Only allowed in a page
+
+`getServerSideProps` can only be exported from a **page**. You can’t export it from non-page files.
+
+Also, you must use `export async function getServerSideProps() {}` — it will **not** work if you add `getServerSideProps` as a property of the page component.
+
+## Fetching data on the client side
+
+If your page contains frequently updating data, and you don’t need to pre-render the data, you can fetch the data on the client side. An example of this is user-specific data. Here’s how it works:
+
+- First, immediately show the page without data. Parts of the page can be pre-rendered using Static Generation. You can show loading states for missing data.
+- Then, fetch the data on the client side and display it when ready.
+
+This approach works well for user dashboard pages, for example. Because a dashboard is a private, user-specific page, SEO is not relevant and the page doesn’t need to be pre-rendered. The data is frequently updated, which requires request-time data fetching.
+
+### SWR
+
+The team behind Next.js has created a React hook for data fetching called [**SWR**](https://swr.now.sh/). We highly recommend it If you’re fetching data on the client side. It handles caching, revalidation, focus tracking, refetching on interval, and more. And the usage is very simple:
+
+```jsx
+import useSWR from 'swr'
+
+function Profile() {
+ const { data, error } = useSWR('/api/user', fetch)
+
+ if (error) return
failed to load
+ if (!data) return
loading...
+ return
hello {data.name}!
+}
+```
+
+[Check out the SWR documentation to learn more](https://swr.now.sh/).
+
+## More Examples
+
+Take a look at the following examples to learn more:
+
+- [Blog Starter using markdown files](https://github.com/zeit/next.js/tree/canary/examples/blog-starter) ([Demo](https://next-blog-starter.now.sh/))
+- [DatoCMS Example](https://github.com/zeit/next.js/tree/canary/examples/cms-datocms) ([Demo](https://next-blog-datocms.now.sh/))
+- [TakeShape Example](https://github.com/zeit/next.js/tree/canary/examples/cms-takeshape) ([Demo](https://next-blog-takeshape.now.sh/))
+- [Sanity Example](https://github.com/zeit/next.js/tree/canary/examples/cms-sanity) ([Demo](https://next-blog-sanity.now.sh/))
+
+## Learn more
+
+We recommend you to read the following sections next:
+
+
diff --git a/docs/basic-features/pages.md b/docs/basic-features/pages.md
new file mode 100644
index 00000000000000..b4d908cac197c4
--- /dev/null
+++ b/docs/basic-features/pages.md
@@ -0,0 +1,284 @@
+---
+description: Next.js pages are React Components exported in a file in the pages directory. Learn how they work here.
+---
+
+# Pages
+
+> This document is for Next.js versions 9.3 and up. If you're using older versions of Next.js, refer to our [previous documentation](https://nextjs.org/docs/tag/v9.2.2/basic-features/pages).
+
+In Next.js, a **page** is a [React Component](https://reactjs.org/docs/components-and-props.html) exported from a `.js`, `.ts`, or `.tsx` file in the `pages` directory. Each page is associated with a route based on its file name.
+
+**Example**: If you create `pages/about.js` that exports a React component like below, it will be accessible at `/about`.
+
+```jsx
+function About() {
+ return
About
+}
+
+export default About
+```
+
+### Pages with Dynamic Routes
+
+Next.js supports pages with dynamic routes. For example, if you create a file called `pages/posts/[id].js`, then it will be accessible at `posts/1`, `posts/2`, etc.
+
+> To learn more about dynamic routing, check the [Dynamic Routing documentation](/docs/routing/dynamic-routes.md).
+
+## Pre-rendering
+
+By default, Next.js **pre-renders** every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO.
+
+Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called _hydration_.)
+
+### Two forms of Pre-rendering
+
+Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page.
+
+- [**Static Generation (Recommended)**](#static-generation-recommended): The HTML is generated at **build time** and will be reused on each request.
+- [**Server-side Rendering**](#server-side-rendering): The HTML is generated on **each request**.
+
+Importantly, Next.js lets you **choose** which pre-rendering form you'd like to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others.
+
+We **recommend** using **Static Generation** over Server-side Rendering for performance reasons. Statically generated pages can be cached by CDN to boost performance. However, in some cases, Server-side Rendering might be the only option.
+
+Finally, you can always use **Client-side Rendering** along with Static Generation or Server-side Rendering. That means some parts of a page can be rendered entirely by client side JavaScript. To learn more, take a look at the [Data Fetching](/docs/basic-features/data-fetching.md#fetching-data-on-the-client-side) documentation.
+
+## Static Generation (Recommended)
+
+If a page uses **Static Generation**, the page HTML is generated at **build time**. That means in production, the page HTML is generated when you run `next build` . This HTML will then be reused on each request. It can be cached by a CDN.
+
+In Next.js, you can statically generate pages **with or without data**. Let's take a look at each case.
+
+### Static Generation without data
+
+By default, Next.js pre-renders pages using Static Generation without fetching data. Here's an example:
+
+```jsx
+function About() {
+ return
About
+}
+
+export default About
+```
+
+Note that this page does not need to fetch any external data to be pre-rendered. In cases like this, Next.js simply generates a single HTML file per page during build time.
+
+### Static Generation with data
+
+Some pages require fetching external data for pre-rendering. There are two scenarios, and one or both might apply. In each case, you can use a special function Next.js provides:
+
+1. Your page **content** depends on external data: Use `getStaticProps`.
+2. Your page **paths** depend on external data: Use `getStaticPaths` (usually in addition to `getStaticProps`).
+
+#### Scenario 1: Your page **content** depends on external data
+
+**Example**: Your blog page might need to fetch the list of blog posts from a CMS (content management system).
+
+```jsx
+// TODO: Need to fetch `posts` (by calling some API endpoint)
+// before this page can be pre-rendered.
+function Blog({ posts }) {
+ return (
+
+ {posts.map(post => (
+
{post.title}
+ ))}
+
+ )
+}
+
+export default Blog
+```
+
+To fetch this data on pre-render, Next.js allows you to `export` an `async` function called `getStaticProps` from the same file. This function gets called at build time and lets you pass fetched data to the page's `props` on pre-render.
+
+```jsx
+// You can use any data fetching library
+import fetch from 'node-fetch'
+
+function Blog({ posts }) {
+ // Render posts...
+}
+
+// This function gets called at build time
+export async function getStaticProps() {
+ // Call an external API endpoint to get posts
+ const res = await fetch('https://.../posts')
+ const posts = await res.json()
+
+ // By returning { props: posts }, the Blog component
+ // will receive `posts` as a prop at build time
+ return {
+ props: {
+ posts,
+ },
+ }
+}
+
+export default Blog
+```
+
+To learn more about how `getStaticProps` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation).
+
+#### Scenario 2: Your page paths depend on external data
+
+Next.js allows you to create pages with **dynamic routes**. For example, you can create a file called `pages/posts/[id].js` to show a single blog post based on `id`. This will allow you to show a blog post with `id: 1` when you access `posts/1`.
+
+> To learn more about dynamic routing, check the [Dynamic Routing documentation](/docs/routing/dynamic-routes.md).
+
+However, which `id` you want to pre-render at build time might depend on external data.
+
+**Example**: suppose that you've only added one blog post (with `id: 1`) to the database. In this case, you'd only want to pre-render `posts/1` at build time.
+
+Later, you might add the second post with `id: 2`. Then you'd want to pre-render `posts/2` as well.
+
+So your page **paths** that are pre-rendered depend on external data**.** To handle this, Next.js lets you `export` an `async` function called `getStaticPaths` from a dynamic page (`pages/posts/[id].js` in this case). This function gets called at build time and lets you specify which paths you want to pre-render.
+
+```jsx
+import fetch from 'node-fetch'
+
+// This function gets called at build time
+export async function getStaticPaths() {
+ // Call an external API endpoint to get posts
+ const res = await fetch('https://.../posts')
+ const posts = await res.json()
+
+ // Get the paths we want to pre-render based on posts
+ const paths = posts.map(post => `/posts/${post.id}`)
+
+ // We'll pre-render only these paths at build time.
+ // { fallback: false } means other routes should 404.
+ return { paths, fallback: false }
+}
+```
+
+Also in `pages/posts/[id].js`, you need to export `getStaticProps` so that you can fetch the data about the post with this `id` and use it to pre-render the page:
+
+```jsx
+import fetch from 'node-fetch'
+
+function Post({ post }) {
+ // Render post...
+}
+
+export async function getStaticPaths() {
+ // ...
+}
+
+// This also gets called at build time
+export async function getStaticProps({ params }) {
+ // params contains the post `id`.
+ // If the route is like /posts/1, then params.id is 1
+ const res = await fetch(`https://.../posts/${params.id}`)
+ const post = await res.json()
+
+ // Pass post data to the page via props
+ return { props: { post } }
+}
+
+export default Post
+```
+
+To learn more about how `getStaticPaths` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation).
+
+### When should I use Static Generation?
+
+We recommend using **Static Generation** (with and without data) whenever possible because your page can be built once and served by CDN, which makes it much faster than having a server render the page on every request.
+
+You can use Static Generation for many types of pages, including:
+
+- Marketing pages
+- Blog posts
+- E-commerce product listings
+- Help and documentation
+
+You should ask yourself: "Can I pre-render this page **ahead** of a user's request?" If the answer is yes, then you should choose Static Generation.
+
+On the other hand, Static Generation is **not** a good idea if you cannot pre-render a page ahead of a user's request. Maybe your page shows frequently updated data, and the page content changes on every request.
+
+In cases like this, you can do one of the following:
+
+- Use Static Generation with **Client-side Rendering:** You can skip pre-rendering some parts of a page and then use client-side JavaScript to populate them. To learn more about this approach, check out the [Data Fetching documentation](/docs/basic-features/data-fetching.md#fetching-data-on-the-client-side).
+- Use **Server-Side Rendering:** Next.js pre-renders a page on each request. It will be slower because the page cannot be cached by a CDN, but the pre-rendered page will always be up-to-date. We'll talk about this approach below.
+
+## Server-side Rendering
+
+> Also referred to as "SSR" or "Dynamic Rendering".
+
+If a page uses **Server-side Rendering**, the page HTML is generated on **each request**.
+
+To use Server-side Rendering for a page, you need to `export` an `async` function called `getServerSideProps`. This function will be called by the server on every request.
+
+For example, suppose that your page needs to pre-render frequently updated data (fetched from an external API). You can write `getServerSideProps` which fetches this data and passes it to `Page` like below:
+
+```jsx
+import fetch from 'node-fetch'
+
+function Page({ data }) {
+ // Render data...
+}
+
+// This gets called on every request
+export async function getServerSideProps() {
+ // Fetch data from external API
+ const res = await fetch(`https://.../data`)
+ const data = await res.json()
+
+ // Pass data to the page via props
+ return { props: { data } }
+}
+
+export default Page
+```
+
+As you can see, `getServerSideProps` is similar to `getStaticProps`, but the difference is that `getServerSideProps` is run on every request instead of on build time.
+
+To learn more about how `getServerSideProps` works, check out our [Data Fetching documentation](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering)
+
+## Summary
+
+We've discussed two forms of pre-rendering for Next.js.
+
+- **Static Generation (Recommended):** The HTML is generated at **build time** and will be reused on each request. To make a page use Static Generation, just export the page component, or export `getStaticProps` (and `getStaticPaths` if necessary). It's great for pages that can be pre-rendered ahead of a user's request. You can also use it with Client-side Rendering to bring in additional data.
+- **Server-side Rendering:** The HTML is generated on **each request**. To make a page use Server-side Rendering, export `getServerSideProps`. Because Server-side Rendering results in slower performance than Static Generation, use this only if absolutely necessary.
+
+## More Examples
+
+Take a look at the following examples to learn more:
+
+- [Blog Starter using markdown files](https://github.com/zeit/next.js/tree/canary/examples/blog-starter) ([Demo](https://next-blog-starter.now.sh/))
+- [DatoCMS Example](https://github.com/zeit/next.js/tree/canary/examples/cms-datocms) ([Demo](https://next-blog-datocms.now.sh/))
+- [TakeShape Example](https://github.com/zeit/next.js/tree/canary/examples/cms-takeshape) ([Demo](https://next-blog-takeshape.now.sh/))
+- [Sanity Example](https://github.com/zeit/next.js/tree/canary/examples/cms-sanity) ([Demo](https://next-blog-sanity.now.sh/))
+
+## Learn more
+
+We recommend you to read the following sections next:
+
+
diff --git a/docs/basic-features/static-file-serving.md b/docs/basic-features/static-file-serving.md
new file mode 100644
index 00000000000000..ffc0525641e82c
--- /dev/null
+++ b/docs/basic-features/static-file-serving.md
@@ -0,0 +1,25 @@
+---
+description: Next.js allows you to serve static files, like images, in the public directory. You can learn how it works here.
+---
+
+# Static File Serving
+
+Next.js can serve static files, like images, under a folder called `public` in the root directory. Files inside `public` can then be referenced by your code starting from the base URL (`/`).
+
+For example, if you add an image to `public/my-image.png`, the following code will access the image:
+
+```jsx
+function MyImage() {
+ return
+}
+
+export default MyImage
+```
+
+This folder is also useful for `robots.txt`, Google Site Verification, and any other static files (including `.html`)!
+
+> **Note**: Don't name the `public` directory anything else. The name cannot be changed and is the only directory used to serve static assets.
+
+> **Note**: Be sure to not have a static file with the same name as a file in the `pages/` directory, as this will result in an error.
+>
+> Read more:
diff --git a/docs/basic-features/typescript.md b/docs/basic-features/typescript.md
new file mode 100644
index 00000000000000..17269a8f816a55
--- /dev/null
+++ b/docs/basic-features/typescript.md
@@ -0,0 +1,110 @@
+---
+description: Next.js supports TypeScript by default and has built-in types for pages and the API. You can get started with TypeScript in Next.js here.
+---
+
+# TypeScript
+
+
+ Examples
+
+
+
+Next.js provides an integrated [TypeScript](https://www.typescriptlang.org/) experience out of the box, similar to an IDE.
+
+To get started, create an empty `tsconfig.json` file in the root of your project:
+
+```bash
+touch tsconfig.json
+```
+
+Next.js will automatically configure this file with default values. Providing your own `tsconfig.json` with custom [compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html) is also supported.
+
+> Next.js uses Babel to handle TypeScript, which has some [caveats](https://babeljs.io/docs/en/babel-plugin-transform-typescript#caveats), and some [compiler options are handled differently](https://babeljs.io/docs/en/babel-plugin-transform-typescript#typescript-compiler-options).
+
+Then, run `next` (normally `npm run dev`) and Next.js will guide you through the installation of the required packages to finish the setup:
+
+```bash
+npm run dev
+
+# You'll see instructions like these:
+#
+# Please install typescript, @types/react, and @types/node by running:
+#
+# yarn add --dev typescript @types/react @types/node
+#
+# ...
+```
+
+You're now ready to start converting files from `.js` to `.tsx` and leveraging the benefits of TypeScript!.
+
+> A file named `next-env.d.ts` will be created in the root of your project. This file ensures Next.js types are picked up by the TypeScript compiler. **You cannot remove it**, however, you can edit it (but you don't need to).
+
+> Next.js `strict` mode is disabled by default. When you feel comfortable with TypeScript, it's recommended to turn it on in your `tsconfig.json`.
+
+By default, Next.js reports TypeScript errors during development for pages you are actively working on. TypeScript errors for inactive pages **do not** block the development process.
+
+If you want to silence the error reports, refer to the documentation for [Ignoring TypeScript errors](/docs/api-reference/next.config.js/ignoring-typescript-errors.md).
+
+## Static Generation and Server-side Rendering
+
+For `getStaticProps`, `getStaticPaths`, and `getServerSideProps`, you can use the `GetStaticProps`, `GetStaticPaths`, and `GetServerSideProps` types respectively:
+
+```ts
+import { GetStaticProps, GetStaticPaths, GetServerSideProps } from 'next'
+
+export const getStaticProps: GetStaticProps = async context => {
+ // ...
+}
+
+export const getStaticPaths: GetStaticPaths = async () => {
+ // ...
+}
+
+export const getServerSideProps: GetServerSideProps = async context => {
+ // ...
+}
+```
+
+> If you're using `getInitialProps`, you can [follow the directions on this page](/docs/api-reference/data-fetching/getInitialProps.md#typescript).
+
+## API Routes
+
+The following is an example of how to use the built-in types for API routes:
+
+```ts
+import { NextApiRequest, NextApiResponse } from 'next'
+
+export default (req: NextApiRequest, res: NextApiResponse) => {
+ res.status(200).json({ name: 'John Doe' })
+}
+```
+
+You can also type the response data:
+
+```ts
+import { NextApiRequest, NextApiResponse } from 'next'
+
+type Data = {
+ name: string
+}
+
+export default (req: NextApiRequest, res: NextApiResponse) => {
+ res.status(200).json({ name: 'John Doe' })
+}
+```
+
+## Custom `App`
+
+If you have a [custom `App` ](/docs/advanced-features/custom-app), you can use the built-in type `AppProps`, like so:
+
+```ts
+import { AppProps } from 'next/app'
+
+function MyApp({ Component, pageProps }: AppProps) {
+ return
+}
+
+export default MyApp
+```
diff --git a/docs/concepts/_data-fetching.md b/docs/concepts/_data-fetching.md
new file mode 100644
index 00000000000000..b5496b255f37de
--- /dev/null
+++ b/docs/concepts/_data-fetching.md
@@ -0,0 +1,75 @@
+# Data Fetching
+
+As outlined in the `pages` documentation Next.js has 2 render modes:
+
+- Static Generation
+- Server-Side Rendering
+
+Next.js provides methods to do data fetching for both modes. These methods are agnostic to your data solution.
+Meaning you can use any data solution, from fetching rest APIs to GraphQL.
+
+Both of modes have different trade-offs and use different methods of data fetching.
+
+## Static Generation
+
+[Read more about how Static Generation works]().
+
+By default Next.js renders pages to static HTML at build time.
+
+However sometimes you might want to fetch some data from an external source while preserving the static generation behavior.
+
+Next.js provides the `getStaticProps` method to do exactly that, fetch data and render to static HTML.
+
+```jsx
+import fetch from 'isomorphic-unfetch'
+
+// Called at build time and renders the page to static HTML.
+export async function getStaticProps() {
+ const res = await fetch('https://api.github.com/repos/zeit/next.js')
+ const json = await res.json()
+
+ return {
+ props: {
+ stars: json.stargazers_count,
+ },
+ }
+}
+
+function HomePage({ stars }) {
+ return
Next stars: {stars}
+}
+
+export default HomePage
+```
+
+## Server-Side Rendering
+
+[Read more about how Server-Side Rendering works]().
+
+To opt-in to Server-Side Rendering, making every request render HTML on-demand you use the `getServerSideProps` method.
+
+It allows you to fetch data before rendering starts when a request comes in.
+
+Taking the same example as Static Generation, but opted into rendering the page when a request comes in.
+
+```jsx
+import fetch from 'isomorphic-unfetch'
+
+// Called when a request comes in.
+export async function getServerSideProps() {
+ const res = await fetch('https://api.github.com/repos/zeit/next.js')
+ const json = await res.json()
+
+ return {
+ props: {
+ stars: json.stargazers_count,
+ },
+ }
+}
+
+function HomePage({ stars }) {
+ return
Next stars: {stars}
+}
+
+export default HomePage
+```
diff --git a/docs/concepts/_server-side-and-client-side.md b/docs/concepts/_server-side-and-client-side.md
new file mode 100644
index 00000000000000..571af2659ace80
--- /dev/null
+++ b/docs/concepts/_server-side-and-client-side.md
@@ -0,0 +1,133 @@
+# Server-Side and Client-Side
+
+When working with Next.js, we tend to write isomorphic code that can be rendered in both Node.js and the browser, to give you a better idea, take a look at the following example:
+
+```jsx
+function Page() {
+ return
Hello World
+}
+
+export default Page
+```
+
+The above example is pretty basic, but it properly demonstrates what an isomorphic `page` looks like. The page can be prerendered with Node.js to static HTML, and it can also be rendered by the browser.
+
+Now, what if the page tries to use a browser-only API?. Like so:
+
+```jsx
+function Page() {
+ return
Hello World. Your user agent is: {navigator.userAgent}
+}
+
+export default Page
+```
+
+[`navigator`](https://developer.mozilla.org/en-US/docs/Web/API/Window/navigator) is only available in the `window` object, therefore Node.js doesn't have access to it, so your page would end up in a server-side error.
+
+To work with code that only works in one side, read the sections below.
+
+> [Dynamic imports](/docs/advanced-features/dynamic-import.md) can also help you handle code that only loads when required.
+
+## Client-side only code
+
+If you need access to APIs that only exist in the browser, like `window`, then `useEffect` is the recommended solution. Take a look at the following example:
+
+```jsx
+import { useState, useEffect } from 'react'
+
+function Page() {
+ const [userAgent, setUserAgent] = useState()
+
+ useEffect(() => {
+ setUserAgent(navigator.userAgent)
+ }, [])
+
+ return
Hello World. Your user agent is: {userAgent}
+}
+
+export default Page
+```
+
+Everything inside the function passed to `useEffect` will always run after the initial render, meaning it only runs in the browser.
+
+You can achieve the same using [class components](https://reactjs.org/docs/react-component.html), as in the following example:
+
+```jsx
+import React from 'react'
+
+class Page extends React.Component {
+ componentDidMount() {
+ this.setState({ userAgent: navigator.userAgent })
+ }
+ render() {
+ return
Hello World. Your user agent is: {this.state.userAgent}
+ }
+}
+
+export default Page
+```
+
+`componentDidMount` will only execute in the browser, just like `useEffect`.
+
+> In both cases, `userAgent` will be `undefined` in the first render, and once `useEffect` or `componentDidMount` are executed, it will change to the value of `navigator.userAgent`.
+
+## Server-side only code
+
+Following the `userAgent` example from above, we can make it always available to the page by adding [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md), like so:
+
+```jsx
+import { useState, useEffect } from 'react'
+
+function Page({ userAgent }) {
+ return
Hello World. Your user agent is: {userAgent}
+}
+
+Page.getInitialProps = ({ req }) => {
+ if (typeof window === 'undefined') {
+ return { userAgent: req.headers['user-agent'] }
+ } else {
+ return { userAgent: navigator.userAgent }
+ }
+}
+
+export default Page
+```
+
+The above example uses `req` to get the user agent in the server, and `navigator` if `getInitialProps` is executed in the browser.
+
+> `typeof window` not only allows the page to differentiate between sides, but it also enables webpack's dead code elimination. We replace `typeof window` with a constant using webpack [DefinePlugin](https://webpack.js.org/plugins/define-plugin/).
+
+Only the required code that passes the condition (`typeof window === 'undefined'`) will be included in the build. So the server-side build for the page's `getInitialProps` would look like:
+
+```jsx
+Page.getInitialProps = ({ req }) => {
+ return { userAgent: req.headers['user-agent'] }
+}
+```
+
+And the client-side build:
+
+```jsx
+Page.getInitialProps = ({ req }) => {
+ return { userAgent: navigator.userAgent }
+}
+```
+
+Thanks to dead code elimination, you could also import modules only for the required side, as in the following example:
+
+```jsx
+Page.getInitialProps = async ({ req }) => {
+ if (typeof window === 'undefined') {
+ const cookie = await import('cookie')
+ const cookies = cookie.parse(req.headers.cookie)
+
+ return { userAgent: req.headers['user-agent'], theme: cookies.theme }
+ } else {
+ const cookies = await import('js-cookie')
+
+ return { userAgent: navigator.userAgent, theme: cookies.get('theme') }
+ }
+}
+```
+
+And same as before, each build will only include the code that passes the condition.
diff --git a/docs/deployment.md b/docs/deployment.md
new file mode 100644
index 00000000000000..3ddbb1de16bbf5
--- /dev/null
+++ b/docs/deployment.md
@@ -0,0 +1,77 @@
+---
+description: Deploy your Next.js app to production with ZEIT Now and other hosting options.
+---
+
+# Deployment
+
+## ZEIT Now (Recommended)
+
+The easiest way to deploy Next.js to production is to use the **[ZEIT Now platform](https://zeit.co)** from the creators of Next.js. [ZEIT Now](https://zeit.co) is an all-in-one platform with Global CDN supporting static & JAMstack deployment and Serverless Functions.
+
+### Getting started
+
+If you haven’t already done so, push your Next.js app to a Git provider of your choice: [GitHub](http://github.com/), [GitLab](https://gitlab.com/), or [BitBucket](https://bitbucket.org/). Your repository can be private or public.
+
+Then, follow these steps:
+
+1. [Sign up to ZEIT Now](https://zeit.co/signup) (no credit card is required).
+2. After signing up, you’ll arrive on the [“Import Project”](https://zeit.co/import) page. Under “From Git Repository”, choose the Git provider you use and set up an integration. (Instructions: [GitHub](https://zeit.co/docs/v2/git-integrations/zeit-now-for-github) / [GitLab](https://zeit.co/docs/v2/git-integrations/zeit-now-for-gitlab) / [BitBucket](https://zeit.co/docs/v2/git-integrations/zeit-now-for-bitbucket)).
+3. Once that’s set up, click “Import Project From …” and import your Next.js app. It auto-detects that your app is using Next.js and sets up the build configuration for you. No need to change anything — everything just works!
+4. After importing, it’ll deploy your Next.js app and provide you with a deployment URL. Click “Visit” to see your app in production.
+
+Congratulations! You’ve just deployed your Next.js app! If you have questions, take a look at the [ZEIT Now documentation](https://zeit.co/docs).
+
+> If you’re using a [custom server](/docs/advanced-features/custom-server.md), we strongly recommend migrating away from it (for example, by using [dynamic routing](/docs/routing/dynamic-routes.md)). If you cannot migrate, consider [other hosting options](#other-hosting-options).
+
+### DPS: Develop, Preview, Ship
+
+Let’s talk about the workflow we recommend using. [ZEIT Now](https://zeit.co) supports what we call the **DPS** workflow: **D**evelop, **P**review, and **S**hip:
+
+- **Develop:** Write code in Next.js. Keep the development server running and take advantage of its hot code reloading feature.
+- **Preview:** Every time you push changes to a branch on GitHub / GitLab / BitBucket, ZEIT Now automatically creates a new deployment with a unique URL. You can view them on GitHub when you open a pull request, or under “Preview Deployments” on your project page on ZEIT Now. [Learn more about it here](https://zeit.co/features/deployment-previews).
+- **Ship:** When you’re ready to ship, merge the pull request to your default branch (e.g. `master`). ZEIT Now will automatically create a production deployment.
+
+By using the DPS workflow, in addition to doing _code reviews_, you can do _deployment previews_. Each deployment creates a unique URL that can be shared or used for integration tests.
+
+### Optimized for Next.js
+
+[ZEIT Now](https://zeit.co) is made by the creators of Next.js and has first-class support for Next.js.
+
+For example, the [hybrid pages](/docs/basic-features/pages.md) approach is fully supported out of the box.
+
+- Every page can either use [Static Generation](/docs/basic-features/pages.md#static-generation) or [Server-Side Rendering](/docs/basic-features/pages.md#server-side-rendering).
+- Pages that use [Static Generation](/docs/basic-features/pages.md#static-generation) and assets (JS, CSS, images, fonts, etc) will automatically be served from the [ZEIT Now Smart CDN](https://zeit.co/smart-cdn), which is blazingly fast.
+- Pages that use [Server-Side Rendering](/docs/basic-features/pages.md#server-side-rendering) and [API routes](/docs/api-routes/introduction.md) will automatically become isolated Serverless Functions. This allows page rendering and API requests to scale infinitely.
+
+### Custom Domains, Environment Variables, Automatic HTTPS, and more
+
+- **Custom Domains:** Once deployed on [ZEIT Now](https://zeit.co), you can assign a custom domain to your Next.js app. Take a look at [our documentation here](https://zeit.co/docs/v2/custom-domains).
+- **Environment Variables:** You can also set environment variables on ZEIT Now. Take a look at [our documentation here](https://zeit.co/docs/v2/build-step#using-environment-variables-and-secrets). You can then [use those environment variables](/docs/api-reference/next.config.js/environment-variables.md) in your Next.js app.
+- **Automatic HTTPS:** HTTPS is enabled by default (including custom domains) and doesn't require extra configuration. We auto-renew SSL certificates.
+- **More:** [Read our documentation](https://zeit.co/docs) to learn more about the ZEIT Now platform.
+
+## Other hosting options
+
+### Node.js Server
+
+Next.js can be deployed to any hosting provider that supports Node.js. This is the approach you should take if you’re using a [custom server](/docs/advanced-features/custom-server.md).
+
+Make sure your `package.json` has the `"build"` and `"start"` scripts:
+
+```json
+{
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ }
+}
+```
+
+`next build` builds the production application in the `.next` folder. After building, `next start` starts a Node.js server that supports [hybrid pages](/docs/basic-features/pages.md), serving both statically generated and server-side rendered pages.
+
+### Static HTML Export
+
+If you’d like to do a static HTML export of your Next.js app, follow the directions on [our documentation](/docs/advanced-features/static-html-export.md). By default, `next export` will generate an `out` directory, which can be served by any static hosting service or CDN.
+
+> We strongly recommend using [ZEIT Now](https://zeit.co/) even if your Next.js app is fully static. [ZEIT Now](https://zeit.co/) is optimized to make static Next.js apps blazingly fast. `next export` works with Zero Config deployments on ZEIT Now.
diff --git a/docs/faq.md b/docs/faq.md
new file mode 100644
index 00000000000000..ae06df7865abbe
--- /dev/null
+++ b/docs/faq.md
@@ -0,0 +1,81 @@
+---
+description: Get to know more about Next.js with the frequently asked questions.
+---
+
+# Frequently Asked Questions
+
+
+ What browsers are supported?
+
Next.js supports IE11 and all modern browsers out of the box using @babel/preset-env. 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 require features not supported by your target browsers you will need to implement polyfills. If you need to implement polyfills, the polyfills example demonstrates the recommended approach.
+
+
+
+ Is this production ready?
+
Next.js has been powering https://zeit.co since its inception.
+
+
We’re ecstatic about both the developer experience and end-user performance, so we decided to share it with the community.
+
+
+
+ How big is it?
+
The client side bundle size should be measured in a per-app basis. A small Next main bundle is around 65kb gzipped.
+
+
+
+ How can I change the internal webpack configs?
+
Next.js tries its best to remove the overhead of webpack configurations, but for advanced cases where more control is needed, refer to the custom webpack config documentation.
+
+
+
+ What syntactic features are compiled? How do I change them?
+
We track V8. Since V8 has wide support for ES6 and async and await, we compile those. Since V8 doesn’t support class decorators, we don’t compile those.
The ease-of-use of PHP is a great inspiration. We feel Next.js is a suitable replacement for many scenarios where you would otherwise use PHP to output HTML.
+
+
Unlike PHP, we benefit from the ES6 module system and every page 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 (now deprecated), a similar approach to Next.js by the creator of React Jordan Walke.
+
diff --git a/docs/getting-started.md b/docs/getting-started.md
new file mode 100644
index 00000000000000..e4d8cba5c3a78b
--- /dev/null
+++ b/docs/getting-started.md
@@ -0,0 +1,99 @@
+---
+description: Get started with Next.js in the official documentation, and learn more about all our features!
+---
+
+# Getting Started
+
+Welcome to the Next.js documentation!
+
+If you're new to Next.js we recommend that you start with the [learn course](https://nextjs.org/learn/basics/getting-started).
+
+The interactive course with quizzes will guide you through everything you need to know to use Next.js.
+
+If you have questions about anything related to Next.js, you're always welcome to ask our community on [GitHub Discussions](https://github.com/zeit/next.js/discussions).
+
+#### System Requirements
+
+- [Node.js 10](https://nodejs.org/) or later
+- MacOS, Windows (including WSL), and Linux are supported
+
+## Setup
+
+We recommend creating a new Next.js app using `create-next-app`, which sets up everything automatically for you. To create a project, run:
+
+```bash
+npm init next-app
+# or
+yarn create next-app
+```
+
+After the installation is complete, follow the instructions to start the development server. Try editing `pages/index.js` and see the result on your browser.
+
+## Manual Setup
+
+Install `next`, `react` and `react-dom` in your project:
+
+```bash
+npm install next react react-dom
+```
+
+Open `package.json` and add the following `scripts`:
+
+```json
+"scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+}
+```
+
+These scripts refer to the different stages of developing an application:
+
+- `dev` - Runs `next` which starts Next.js in development mode
+- `build` - Runs `next build` which builds the application for production usage
+- `start` - Runs `next start` which starts a Next.js production server
+
+Next.js is built around the concept of pages. A page is a [React Component](https://reactjs.org/docs/components-and-props.html) exported from a `.js`, `.jsx`, `.ts`, or `.tsx` file in the `pages` directory.
+
+Pages are associated with a route based on their file name. For example `pages/about.js` is mapped to `/about`. You can even add dynamic route parameters with the filename.
+
+Create a `pages` directory inside your project.
+
+Populate `./pages/index.js` with the following contents:
+
+```jsx
+function HomePage() {
+ return
Welcome to Next.js!
+}
+
+export default HomePage
+```
+
+To start developing your application run `npm run dev`. This starts the development server on `http://localhost:3000`.
+
+Visit `http://localhost:3000` to view your application.
+
+So far, we get:
+
+- Automatic compilation and bundling (with webpack and babel)
+- Hot code reloading
+- Static generation and server-side rendering of [`./pages/`](/docs/basic-features/pages.md)
+- [Static file serving](/docs/basic-features/static-file-serving.md). `./public/` is mapped to `/`
+
+## Related
+
+For more information on what to do next, we recommend the following sections:
+
+
+
+
+Defining routes by using predefined paths is not always enough for complex applications. In Next.js you can add brackets to a page (`[param]`) to create a dynamic route (a.k.a. url slugs, pretty urls, and others).
+
+Consider the following page `pages/post/[pid].js`:
+
+```jsx
+import { useRouter } from 'next/router'
+
+const Post = () => {
+ const router = useRouter()
+ const { pid } = router.query
+
+ return
Post: {pid}
+}
+
+export default Post
+```
+
+Any route like `/post/1`, `/post/abc`, etc. will be matched by `pages/post/[pid].js`. The matched path parameter will be sent as a query parameter to the page, and it will be merged with the other query parameters.
+
+For example, the route `/post/abc` will have the following `query` object:
+
+```json
+{ "pid": "abc" }
+```
+
+Similarly, the route `/post/abc?foo=bar` will have the following `query` object:
+
+```json
+{ "foo": "bar", "pid": "abc" }
+```
+
+However, route parameters will override query parameters with the same name. For example, the route `/post/abc?pid=123` will have the following `query` object:
+
+```json
+{ "pid": "abc" }
+```
+
+Multiple dynamic route segments work the same way. The page `pages/post/[pid]/[comment].js` will match the route `/post/abc/a-comment` and its `query` object will be:
+
+```json
+{ "pid": "abc", "comment": "a-comment" }
+```
+
+Client-side navigations to a dynamic route can be handled with [`next/link`](/docs/api-reference/next/link.md#dynamic-routes).
+
+### Catch all routes
+
+
+ Examples
+
+
+
+Dynamic routes can be extended to catch all paths by adding three dots (`...`) inside the brackets. For example:
+
+- `pages/post/[...slug].js` matches `/post/a`, but also `/post/a/b`, `/post/a/b/c` and so on.
+
+> **Note**: You can use names other than `slug`, such as: `[...param]`
+
+Matched parameters will be sent as a query parameter (`slug` in the example) to the page, and it will always be an array, so, the path `/post/a` will have the following `query` object:
+
+```json
+{ "slug": ["a"] }
+```
+
+And in the case of `/post/a/b`, and any other matching path, new parameters will be added to the array, like so:
+
+```json
+{ "slug": ["a", "b"] }
+```
+
+> A good example of catch all routes is the Next.js docs, a single page called [pages/docs/[...slug].js](https://github.com/zeit/next-site/blob/master/pages/docs/%5B...slug%5D.js) takes care of all the docs you're currently looking at.
+
+## Caveats
+
+- Predefined routes take precedence over dynamic routes, and dynamic routes over catch all routes. Take a look at the following examples:
+ - `pages/post/create.js` - Will match `/post/create`
+ - `pages/post/[pid].js` - Will match `/post/1`, `/post/abc`, etc. But not `/post/create`
+ - `pages/post/[...slug].js` - Will match `/post/1/2`, `/post/a/b/c`, etc. But not `/post/create`, `/post/abc`
+- Pages that are statically optimized by [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) will be hydrated without their route parameters provided, i.e `query` will be an empty object (`{}`).
+
+ After hydration, Next.js will trigger an update to your application to provide the route parameters in the `query` object.
diff --git a/docs/routing/imperatively.md b/docs/routing/imperatively.md
new file mode 100644
index 00000000000000..f555132a0c5bd7
--- /dev/null
+++ b/docs/routing/imperatively.md
@@ -0,0 +1,30 @@
+---
+description: Client-side navigations are also possible using the Router API instead of the Link component. Learn more here.
+---
+
+# Imperatively
+
+
+ Examples
+
+
+
+[`next/link`](/docs/api-reference/next/link.md) should be able to cover most of your routing needs, but you can also do client-side navigations without it, take a look at the [Router API documentation](/docs/api-reference/next/router.md#router-api).
+
+The following example shows the basic usage of the Router API:
+
+```jsx
+import Router from 'next/router'
+
+function ReadMore() {
+ return (
+
+ Click Router.push('/about')}>here to read more
+
+ )
+}
+
+export default ReadMore
+```
diff --git a/docs/routing/introduction.md b/docs/routing/introduction.md
new file mode 100644
index 00000000000000..4191ff1d4ece9c
--- /dev/null
+++ b/docs/routing/introduction.md
@@ -0,0 +1,116 @@
+---
+description: Next.js has a built-in, opinionated, and file-system based Router. You can learn how it works here.
+---
+
+# Routing
+
+Next.js has a file-system based router built on the [concept of pages](/docs/basic-features/pages.md).
+
+When a file is added to the `pages` directory it's automatically available as a route.
+
+The files inside the `pages` directory can be used to define most common patterns.
+
+#### Index routes
+
+The router will automatically route files named `index` to the root of the directory.
+
+- `pages/index.js` → `/`
+- `pages/blog/index.js` → `/blog`
+
+#### Nested routes
+
+The router supports nested files. If you create a nested folder structure files will be automatically routed in the same way still.
+
+- `pages/blog/first-post.js` → `/blog/first-post`
+- `pages/dashboard/settings/username.js` → `/dashboard/settings/username`
+
+#### Dynamic route segments
+
+To match a dynamic segment you can use the bracket syntax. This allows you to match named parameters.
+
+- `pages/blog/[slug].js` → `/blog/:slug` (`/blog/hello-world`)
+- `pages/[username]/settings.js` → `/:username/settings` (`/foo/settings`)
+- `pages/post/[...all].js` → `/post/*` (`/post/2020/id/title`)
+
+## Linking between pages
+
+The Next.js router allows you to do client-side route transitions between pages, similarly to a single-page application.
+
+A special React component called `Link` is provided to do this client-side route transition.
+
+```jsx
+import Link from 'next/link'
+
+function Home() {
+ return (
+
+ )
+}
+
+export default Home
+```
+
+When linking to a route with [dynamic path segments](/docs/routing/dynamic-routes.md) you have to provide `href` and `as` to make sure the router knows which JavaScript file to load.
+
+- `href` - The name of the page in the `pages` directory. For example `/blog/[slug]`.
+- `as` - The url that will be shown in the browser. For example `/blog/hello-world`.
+
+```jsx
+import Link from 'next/link'
+
+function Home() {
+ return (
+
+
+
+To access the [`router` object](/docs/api-reference/next/router.md#router-object) in a React component you can use [`useRouter`](/docs/api-reference/next/router.md#useRouter) or [`withRouter`](/docs/api-reference/next/router.md#withRouter).
+
+In general we recommend using [`useRouter`](/docs/api-reference/next/router.md#useRouter).
+
+## Learn more
+
+The router is divided in multiple parts:
+
+
diff --git a/docs/routing/shallow-routing.md b/docs/routing/shallow-routing.md
new file mode 100644
index 00000000000000..96fdb6dc4405a1
--- /dev/null
+++ b/docs/routing/shallow-routing.md
@@ -0,0 +1,71 @@
+---
+description: You can use shallow routing to change the URL without triggering a new page change. Learn more here.
+---
+
+# Shallow Routing
+
+
+ Examples
+
+
+
+Shallow routing allows you to change the URL without running [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md).
+
+You'll receive the updated `pathname` and the `query` via the [`router` object](/docs/api-reference/next/router.md#router-object) (added by [`useRouter`](/docs/api-reference/next/router.md#useRouter) or [`withRouter`](/docs/api-reference/next/router.md#withRouter)), without losing state.
+
+To enable shallow routing, set the `shallow` option to `true`. Consider the following example:
+
+```jsx
+import { useEffect } from 'react'
+import { useRouter } from 'next/router'
+
+// Current URL is '/'
+function Page() {
+ const router = useRouter()
+
+ useEffect(() => {
+ // Always do navigations after the first render
+ router.push('/?counter=10', null, { shallow: true })
+ }, [])
+
+ useEffect(() => {
+ // The counter changed!
+ }, [router.query.counter])
+}
+
+export default Page
+```
+
+If you don't need to add the router object to the page, you can also use the [Router API](/docs/api-reference/next/router.md#router-api) directly, like so:
+
+```jsx
+import Router from 'next/router'
+// Inside your page
+Router.push('/?counter=10', null, { shallow: true })
+```
+
+The URL will get updated to `/?counter=10`. and the page won't get replaced, only the state of the route is changed.
+
+You can also watch for URL changes via [`componentDidUpdate`](https://reactjs.org/docs/react-component.html#componentdidupdate) as shown below:
+
+```jsx
+componentDidUpdate(prevProps) {
+ const { pathname, query } = this.props.router
+ // verify props have changed to avoid an infinite loop
+ if (query.counter !== prevProps.router.query.counter) {
+ // fetch data based on the new query
+ }
+}
+```
+
+## Caveats
+
+Shallow routing **only** works for same page URL changes. For example, let's assume we have another page called `pages/about.js`, and you run this:
+
+```jsx
+Router.push('/?counter=10', '/about?counter=10', { shallow: true })
+```
+
+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.
diff --git a/docs/upgrading.md b/docs/upgrading.md
new file mode 100644
index 00000000000000..d5be42132d862d
--- /dev/null
+++ b/docs/upgrading.md
@@ -0,0 +1,219 @@
+---
+description: Learn how to upgrade Next.js.
+---
+
+# Upgrade Guide
+
+## Upgrading from version 8 to 9.0.x
+
+### Preamble
+
+#### Production Deployment on ZEIT Now v2
+
+If you previously configured `routes` in your `now.json` file for dynamic routes, these rules can be removed when leveraging Next.js 9's new [Dynamic Routing feature](https://nextjs.org/docs/routing/dynamic-routes).
+
+Next.js 9's dynamic routes are **automatically configured on [Now](https://zeit.co/now)** and do not require any `now.json` customization.
+
+You can read more about [Dynamic Routing here](https://nextjs.org/docs/routing/dynamic-routes).
+
+#### Check your Custom (`pages/_app.js`)
+
+If you previously copied the [Custom ``](https://nextjs.org/docs#custom-app) example, you may be able to remove your `getInitialProps`.
+
+Removing `getInitialProps` from `pages/_app.js` (when possible) is important to leverage new Next.js features!
+
+The following `getInitialProps` does nothing and may be removed:
+
+```js
+class MyApp extends App {
+ // Remove me, I do nothing!
+ static async getInitialProps({ Component, ctx }) {
+ let pageProps = {}
+
+ if (Component.getInitialProps) {
+ pageProps = await Component.getInitialProps(ctx)
+ }
+
+ return { pageProps }
+ }
+
+ render() {
+ // ... etc
+ }
+}
+```
+
+### Breaking Changes
+
+#### `@zeit/next-typescript` is no longer necessary
+
+Next.js will now ignore usage `@zeit/next-typescript` and warn you to remove it. Please remove this plugin from your `next.config.js`.
+
+Remove references to `@zeit/next-typescript/babel` from your custom `.babelrc` (if present).
+
+Usage of [`fork-ts-checker-webpack-plugin`](https://github.com/Realytics/fork-ts-checker-webpack-plugin/issues) should also be removed from your `next.config.js`.
+
+TypeScript Definitions are published with the `next` package, so you need to uninstall `@types/next` as they would conflict.
+
+The following types are different:
+
+> This list was created by the community to help you upgrade, if you find other differences please send a pull-request to this list to help other users.
+
+From:
+
+```tsx
+import { NextContext } from 'next'
+import { NextAppContext, DefaultAppIProps } from 'next/app'
+import { NextDocumentContext, DefaultDocumentIProps } from 'next/document'
+```
+
+to
+
+```tsx
+import { NextPageContext } from 'next'
+import { AppContext, AppInitialProps } from 'next/app'
+import { DocumentContext, DocumentInitialProps } from 'next/document'
+```
+
+#### The `config` key is now a special export on a page
+
+You may no longer export a custom variable named `config` from a page (i.e. `export { config }` / `export const config ...`).
+This exported variable is now used to specify page-level Next.js configuration like Opt-in AMP and API Route features.
+
+You must rename a non-Next.js-purposed `config` export to something different.
+
+#### `next/dynamic` no longer renders "loading..." by default while loading
+
+Dynamic components will not render anything by default while loading. You can still customize this behavior by setting the `loading` property:
+
+```jsx
+import dynamic from 'next/dynamic'
+
+const DynamicComponentWithCustomLoading = dynamic(
+ () => import('../components/hello2'),
+ {
+ loading: () =>
Loading
,
+ }
+)
+```
+
+#### `withAmp` has been removed in favor of an exported configuration object
+
+Next.js now has the concept of page-level configuration, so the `withAmp` higher-order component has been removed for consistency.
+
+This change can be **automatically migrated by running the following commands in the root of your Next.js project:**
+
+```bash
+curl -L https://github.com/zeit/next-codemod/archive/master.tar.gz | tar -xz --strip=2 next-codemod-master/transforms/withamp-to-config.js npx jscodeshift -t ./withamp-to-config.js pages/**/*.js
+```
+
+To perform this migration by hand, or view what the codemod will produce, see below:
+
+**Before**
+
+```jsx
+import { withAmp } from 'next/amp'
+
+function Home() {
+ return
+}
+
+export const config = {
+ amp: true,
+ // or
+ amp: 'hybrid',
+}
+```
+
+#### `next export` no longer exports pages as `index.html`
+
+Previously, exporting `pages/about.js` would result in `out/about/index.html`. This behavior has been changed to result in `out/about.html`.
+
+You can revert to the previous behavior by creating a `next.config.js` with the following content:
+
+```js
+// next.config.js
+module.exports = {
+ exportTrailingSlash: true,
+}
+```
+
+#### `./pages/api/` is treated differently
+
+Pages in `./pages/api/` are now considered [API Routes](https://nextjs.org/blog/next-9#api-routes).
+Pages in this directory will no longer contain a client-side bundle.
+
+## Deprecated Features
+
+#### `next/dynamic` has deprecated loading multiple modules at once
+
+The ability to load multiple modules at once has been deprecated in `next/dynamic` to be closer to React's implementation (`React.lazy` and `Suspense`).
+
+Updating code that relies on this behavior is relatively straightforward! We've provided an example of a before/after to help you migrate your application:
+
+**Before**
+
+```jsx
+import dynamic from 'next/dynamic'
+
+const HelloBundle = dynamic({
+ modules: () => {
+ const components = {
+ Hello1: () => import('../components/hello1').then(m => m.default),
+ Hello2: () => import('../components/hello2').then(m => m.default),
+ }
+
+ return components
+ },
+ render: (props, { Hello1, Hello2 }) => (
+
+ )
+}
+
+function DynamicBundle() {
+ return
+}
+
+export default DynamicBundle
+```
diff --git a/errors/404-get-initial-props.md b/errors/404-get-initial-props.md
new file mode 100644
index 00000000000000..af7fde5a3b48b2
--- /dev/null
+++ b/errors/404-get-initial-props.md
@@ -0,0 +1,15 @@
+# 404.js Cannot Have getInitialProps
+
+#### Why This Error Occurred
+
+In your `404.js` page you added `getInitialProps` or `getServerSideProps` which is not allowed as this prevents the page from being static and `404.js` is meant to provide more flexibility for a static 404 page. Having a static 404 page is the most ideal as this page can be served very often and if not static puts extra strain on your server and more invocations for serverless functions which increase the cost of hosting your site unnecessarily.
+
+#### Possible Ways to Fix It
+
+Remove `getInitialProps` from `404.js` and make sure no HOC's used in `404.js` attach `getInitialProps`.
+
+If you want to fetch data for your `404.js` page move it to a client side fetch inside of `componentDidMount` or `useEffect(() => {}, [])`.
+
+### Useful Links
+
+- [Automatic Static Optimization](https://nextjs.org/docs/advanced-features/automatic-static-optimization)
diff --git a/errors/api-routes-static-export.md b/errors/api-routes-static-export.md
new file mode 100644
index 00000000000000..d82365e0d324a2
--- /dev/null
+++ b/errors/api-routes-static-export.md
@@ -0,0 +1,15 @@
+# API routes in Static export
+
+#### Why This Warning Occurred
+
+An `exportPathMap` path was matched to an API route. Statically exporting a Next.js application via `next export` disables API routes.
+
+This command is meant for static-only hosts, and is not necessary to make your application static. Pages in your application without server-side data dependencies will be automatically statically exported by `next build`, including pages powered by `getStaticProps`
+
+#### Possible Ways to Fix It
+
+Use `next build` with platforms that don't require `next export` like https://zeit.co or remove any paths using API routes from your `exportPathMap` in `next.config.js`.
+
+### Useful Links
+
+- [Static HTML export](https://nextjs.org/docs#static-html-export)
diff --git a/errors/app-container-deprecated.md b/errors/app-container-deprecated.md
new file mode 100644
index 00000000000000..1126290e39e4ea
--- /dev/null
+++ b/errors/app-container-deprecated.md
@@ -0,0 +1,46 @@
+# App Container Deprecated
+
+#### Why This Error Occurred
+
+In versions prior to v9.0.4 the `` component was used in `./pages/_app.js` to handle scrolling to hashes.
+This handling has been moved up the tree so the `` component is no longer needed in your custom ``!
+
+#### Possible Ways to Fix It
+
+Remove the `` component from your Custom `` (`./pages/_app.js`).
+
+**Before**
+
+```jsx
+import React from 'react'
+import App, { Container } from 'next/app'
+
+class MyApp extends App {
+ render() {
+ const { Component, pageProps } = this.props
+ return (
+
+
+
+ )
+ }
+}
+
+export default MyApp
+```
+
+**After**
+
+```jsx
+import React from 'react'
+import App from 'next/app'
+
+class MyApp extends App {
+ render() {
+ const { Component, pageProps } = this.props
+ return
+ }
+}
+
+export default MyApp
+```
diff --git a/errors/build-dir-not-writeable.md b/errors/build-dir-not-writeable.md
index 0f654b50b60fd4..33bf5345f6a1b7 100644
--- a/errors/build-dir-not-writeable.md
+++ b/errors/build-dir-not-writeable.md
@@ -2,7 +2,7 @@
#### Why This Error Occurred
-The filesystem does not allow writing to the specified directory. A common cause for this error is starting a [custom server](https://github.com/zeit/next.js#custom-server-and-routing) in development mode on a production server, for example, [now.sh](https://zeit.co) which [doesn't allow you to write to the filesystem after your app is built](https://zeit.co/docs/deployment-types/node#file-system-specifications).
+The filesystem does not allow writing to the specified directory. A common cause for this error is starting a [custom server](https://nextjs.org/docs#custom-server-and-routing) in development mode on a production server, for example, [now.sh](https://zeit.co) which [doesn't allow you to write to the filesystem after your app is built](https://zeit.co/docs/deployment-types/node#file-system-specifications).
#### Possible Ways to Fix It
@@ -27,4 +27,4 @@ const app = next({ dev })
### Useful Links
-- [Custom Server documentation + examples](https://github.com/zeit/next.js#custom-server-and-routing)
+- [Custom Server documentation + examples](https://nextjs.org/docs#custom-server-and-routing)
diff --git a/errors/built-in-css-disabled.md b/errors/built-in-css-disabled.md
new file mode 100644
index 00000000000000..4f6311769a31be
--- /dev/null
+++ b/errors/built-in-css-disabled.md
@@ -0,0 +1,18 @@
+# Built-in CSS Support Disabled
+
+#### Why This Error Occurred
+
+Custom CSS configuration was added in `next.config.js` which disables the built-in CSS/SCSS support to prevent conflicting configuration.
+
+A legacy plugin such as `@zeit/next-css` being added in `next.config.js` can cause this message.
+
+#### Possible Ways to Fix It
+
+If you would like to leverage the built-in CSS/SCSS support you can remove any custom CSS configuration or any plugins like `@zeit/next-css` or `@zeit/next-sass` in your `next.config.js`.
+
+If you would prefer not to leverage the built-in support you can ignore this message.
+
+### Useful Links
+
+- [Built-in CSS Support docs](https://nextjs.org/docs/basic-features/built-in-css-support)
+- [Custom webpack config docs](https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config)
diff --git a/errors/can-not-output-to-public.md b/errors/can-not-output-to-public.md
new file mode 100644
index 00000000000000..5a266aeb8fc4cb
--- /dev/null
+++ b/errors/can-not-output-to-public.md
@@ -0,0 +1,15 @@
+# Cannot output to /public
+
+#### Why This Error Occurred
+
+Either you set `distDir` to `public` in your `next.config.js` or during `next export` you tried to export to the `public` directory.
+
+This is not allowed due to `public` being a special folder in Next.js used to serve static assets.
+
+#### Possible Ways to Fix It
+
+Use a different `distDir` or export to a different folder.
+
+### Useful Links
+
+- [Static file serving docs](https://nextjs.org/docs#static-file-serving-eg-images)
diff --git a/errors/cant-override-next-props.md b/errors/cant-override-next-props.md
index d47b6b4d9ffe10..35bfc02c82f096 100644
--- a/errors/cant-override-next-props.md
+++ b/errors/cant-override-next-props.md
@@ -6,7 +6,7 @@ In your `pages/_app.js` you returned an object from `getInitialProps` that conta
#### Possible Ways to Fix It
-Look in your _app.js component's `getInitialProps` function and make sure neither of these property names are present in the object returned.
+Look in your \_app.js component's `getInitialProps` function and make sure neither of these property names are present in the object returned.
### Useful Links
diff --git a/errors/config-resolve-alias.md b/errors/config-resolve-alias.md
index 3669e124de18f2..feacf2e3a62eba 100644
--- a/errors/config-resolve-alias.md
+++ b/errors/config-resolve-alias.md
@@ -1,4 +1,4 @@
-# Invalid webpack resolve alias
+# Invalid webpack resolve alias
#### Why This Error Occurred
diff --git a/errors/conflicting-amp-tag.md b/errors/conflicting-amp-tag.md
index 6e5d87445288cd..522aeb6fed30c3 100644
--- a/errors/conflicting-amp-tag.md
+++ b/errors/conflicting-amp-tag.md
@@ -2,7 +2,7 @@
#### Why This Error Occurred
-In AMP mode Next.js adds certain necessary tags automatically to comply with the AMP standard. You added a tag using `next/head` that conflicts with one of these automatically added tags.
+In AMP mode Next.js adds certain necessary tags automatically to comply with the AMP standard. You added a tag using `next/head` that conflicts with one of these automatically added tags.
#### Possible Ways to Fix It
diff --git a/errors/conflicting-public-file-page.md b/errors/conflicting-public-file-page.md
new file mode 100644
index 00000000000000..3000fdd75fab77
--- /dev/null
+++ b/errors/conflicting-public-file-page.md
@@ -0,0 +1,31 @@
+# Conflicting Public File and Page File
+
+#### Why This Error Occurred
+
+One of your public files has the exact same path as a page file which is not supported. Since only one resource can reside at the URL both public files and page files must be unique.
+
+#### Possible Ways to Fix It
+
+Rename either the public file or page file that is causing the conflict.
+
+Example conflict between public file and page file
+
+```
+public/
+ hello
+pages/
+ hello.js
+```
+
+Non-conflicting public file and page file
+
+```
+public/
+ hello.txt
+pages/
+ hello.js
+```
+
+### Useful Links
+
+- [Static file serving docs](https://nextjs.org/docs#static-file-serving-eg-images)
diff --git a/errors/css-global.md b/errors/css-global.md
new file mode 100644
index 00000000000000..22c4e87c5e78b0
--- /dev/null
+++ b/errors/css-global.md
@@ -0,0 +1,22 @@
+# Global CSS Must Be in Your Custom \
+
+#### Why This Error Occurred
+
+An attempt to import Global CSS from a file other than [`pages/_app.js`](https://nextjs.org/docs/advanced-features/custom-app) was made.
+
+Global CSS cannot be used in files other than your [Custom ``](https://nextjs.org/docs/advanced-features/custom-app) due to its side-effects and ordering problems.
+
+#### Possible Ways to Fix It
+
+Relocate all Global CSS imports to your [`pages/_app.js` file](https://nextjs.org/docs/advanced-features/custom-app).
+
+#### Example
+
+```jsx
+// pages/_app.js
+import '../styles.css'
+
+export default function MyApp({ Component, pageProps }) {
+ return
+}
+```
diff --git a/errors/css-modules-npm.md b/errors/css-modules-npm.md
new file mode 100644
index 00000000000000..c7d86dcd95120c
--- /dev/null
+++ b/errors/css-modules-npm.md
@@ -0,0 +1,24 @@
+# CSS Modules Imported by a Dependency
+
+#### Why This Error Occurred
+
+One of your dependencies (`node_modules`) imports a CSS Modules file.
+
+This normally happens when a package's source files are accidentally consumed,
+instead of the built package.
+
+#### Possible Ways to Fix It
+
+Reach out to the maintainer and ask for them to publish a compiled version of
+their dependency.
+
+Compiled dependencies do not have references to CSS Module files, or any other
+files that require bundler-specific integrations.
+
+The dependency should also provide instructions about what CSS needs to be
+imported by you, in your application.
+
+---
+
+If this is **first party code**, try
+[including said monorepo package in the compilation pipeline](https://github.com/zeit/next.js/tree/canary/examples/with-yarn-workspaces).
diff --git a/errors/css-npm.md b/errors/css-npm.md
new file mode 100644
index 00000000000000..3e4e81f834a793
--- /dev/null
+++ b/errors/css-npm.md
@@ -0,0 +1,27 @@
+# CSS Imported by a Dependency
+
+#### Why This Error Occurred
+
+One of your dependencies (`node_modules`) imports a CSS file.
+
+This normally happens when a package's source files are accidentally consumed,
+instead of the built package.
+
+#### Possible Ways to Fix It
+
+Reach out to the maintainer and ask for them to publish a compiled version of
+their dependency.
+
+Compiled dependencies do not have references to CSS files, or any other files
+that require bundler-specific integrations.
+
+The dependency should also provide instructions about what CSS needs to be
+imported by you, in your application.
+
+Importing CSS files within `node_modules` cannot be supported because we cannot
+know the correct behavior:
+
+- Should the file be consumed as Global CSS or CSS Modules?
+- If Global, in what order does the file need to be injected?
+- If Modules, what are the emitted class names? As-is, camel-case, snake case?
+- Etc...
diff --git a/errors/doc-crossorigin-deprecated.md b/errors/doc-crossorigin-deprecated.md
index 6a4c8913ebf115..48b99e30013d42 100644
--- a/errors/doc-crossorigin-deprecated.md
+++ b/errors/doc-crossorigin-deprecated.md
@@ -11,7 +11,7 @@ Add the config option:
```js
// next.config.js
module.exports = {
- crossOrigin: 'anonymous'
+ crossOrigin: 'anonymous',
}
```
diff --git a/errors/empty-configuration.md b/errors/empty-configuration.md
new file mode 100644
index 00000000000000..316f928d6d1de3
--- /dev/null
+++ b/errors/empty-configuration.md
@@ -0,0 +1,19 @@
+# Detected next.config.js, no exported configuration found
+
+#### Why This Warning Occurred
+
+There is no object exported from next.config.js or the object is empty.
+
+#### Possible Ways to Fix It
+
+Check if you correctly export configuration in `next.config.js` file:
+
+```
+module.exports = {
+ /* config options here */
+}
+```
+
+### Useful Links
+
+- [Introduction to next.config.js](https://nextjs.org/docs/api-reference/next.config.js/introduction)
diff --git a/errors/empty-object-getInitialProps.md b/errors/empty-object-getInitialProps.md
new file mode 100644
index 00000000000000..9bba215d0a6e66
--- /dev/null
+++ b/errors/empty-object-getInitialProps.md
@@ -0,0 +1,13 @@
+# Empty Object Returned From `getInitialProps`
+
+#### Why This Error Occurred
+
+In one of your page components you added a `getInitialProps` that returned an empty object. This de-optimizes automatic static optimization. If you **meant** to do this and understand the **consequences** you can ignore this message as it is only shown in development.
+
+#### Possible Ways to Fix It
+
+Look for any page's using `getInitialProps` that return an empty object `{}`. You might also need to update higher order components (HOCs) to only add `getInitialProps` if they are present on the passed component.
+
+### Useful Links
+
+- [Automatic Static Optimization Documentation](https://nextjs.org/docs/advanced-features/automatic-static-optimization)
diff --git a/errors/export-path-mismatch.md b/errors/export-path-mismatch.md
new file mode 100644
index 00000000000000..ecf3a75faf116b
--- /dev/null
+++ b/errors/export-path-mismatch.md
@@ -0,0 +1,26 @@
+# The provided export path doesn't match the page.
+
+#### Why This Error Occurred
+
+An `exportPathMap` path was improperly matched to a dynamically routed page.
+This would result in the page missing its URL parameters.
+
+#### Possible Ways to Fix It
+
+Change your `exportPathMap` function in `next.config.js` to have a path that matches the dynamically routed page.
+
+```js
+module.exports = {
+ exportPathMap: function() {
+ return {
+ '/': { page: '/' },
+ // '/blog/nextjs': { page: '/blog/[post]/comment/[id]' }, // wrong
+ '/blog/nextjs/comment/1': { page: '/blog/[post]/comment/[id]' }, // correct
+ }
+ },
+}
+```
+
+### Useful Links
+
+- [exportPathMap](https://nextjs.org/docs#usage) documentation
diff --git a/errors/get-initial-props-as-an-instance-method.md b/errors/get-initial-props-as-an-instance-method.md
index d9c58e617f1825..fb67e95bea0198 100644
--- a/errors/get-initial-props-as-an-instance-method.md
+++ b/errors/get-initial-props-as-an-instance-method.md
@@ -10,11 +10,11 @@ Use the static keyword.
```js
export default class YourEntryComponent extends React.Component {
- static getInitialProps () {
+ static getInitialProps() {
return {}
}
- render () {
+ render() {
return 'foo'
}
}
@@ -23,7 +23,7 @@ export default class YourEntryComponent extends React.Component {
or
```js
-const YourEntryComponent = function () {
+const YourEntryComponent = function() {
return 'foo'
}
@@ -36,4 +36,4 @@ export default YourEntryComponent
### Useful Links
-- [Fetching data and component lifecycle](https://github.com/zeit/next.js#fetching-data-and-component-lifecycle)
+- [Fetching data and component lifecycle](https://nextjs.org/docs#fetching-data-and-component-lifecycle)
diff --git a/errors/gssp-export.md b/errors/gssp-export.md
new file mode 100644
index 00000000000000..b9908fadc58d0f
--- /dev/null
+++ b/errors/gssp-export.md
@@ -0,0 +1,14 @@
+# getServerSideProps Export Error
+
+#### Why This Error Occurred
+
+You attempted to export a page with `getServerSideProps` which is not allowed. `getServerSideProps` is meant for requesting up to date information on every request which means exporting it defeats the purpose of the method.
+
+#### Possible Ways to Fix It
+
+If you would like the page be static you can leverage the `getStaticProps` method instead.
+
+### Useful Links
+
+- [`getStaticProps` documentation](https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation)
+- [`exportPathMap` documentation](https://nextjs.org/docs/api-reference/next.config.js/exportPathMap)
diff --git a/errors/incompatible-href-as.md b/errors/incompatible-href-as.md
new file mode 100644
index 00000000000000..550fea5a21bbc3
--- /dev/null
+++ b/errors/incompatible-href-as.md
@@ -0,0 +1,44 @@
+# Incompatible `href` and `as` values
+
+#### Why This Error Occurred
+
+Somewhere you are utilizing the `next/link` component, `Router#push`, or `Router#replace` with a dynamic route in your `href` that has an incompatible `as` value. The `as` value is incompatible when the path doesn't provide only the expected parameters for the dynamic route.
+
+Note: this error will only show when the `next/link` component is clicked not when only rendered.
+
+**Incompatible `href` and `as`**
+
+```jsx
+import Link from 'next/link'
+
+export default () => (
+ <>
+
+ Invalid link
+
+ >
+)
+```
+
+**Compatible `href` and `as`**
+
+```jsx
+import Link from 'next/link'
+
+export default () => (
+ <>
+
+ Valid link
+
+ >
+)
+```
+
+#### Possible Ways to Fix It
+
+Look for any usage of the `next/link` component, `Router#push`, or `Router#replace` and make sure that the provided `href` and `as` values are compatible
+
+### Useful Links
+
+- [Routing section in Documentation](https://nextjs.org/docs#routing)
+- [Dynamic routing section in Documentation](https://nextjs.org/docs#dynamic-routing)
diff --git a/errors/install-sass.md b/errors/install-sass.md
new file mode 100644
index 00000000000000..91b7d1301f3956
--- /dev/null
+++ b/errors/install-sass.md
@@ -0,0 +1,19 @@
+# Install `sass` to Use Built-In Sass Support
+
+#### Why This Error Occurred
+
+Using Next.js' [built-in Sass support](https://nextjs.org/docs/basic-features/built-in-css-support#sass-support) requires that you bring your own version of Sass.
+
+#### Possible Ways to Fix It
+
+Please install the `sass` package in your project.
+
+```bash
+npm i sass
+# or
+yarn add sass
+```
+
+### Useful Links
+
+- [Sass Support in Documentation](https://nextjs.org/docs/basic-features/built-in-css-support#sass-support)
diff --git a/errors/invalid-assetprefix.md b/errors/invalid-assetprefix.md
new file mode 100644
index 00000000000000..a1415cfe0320bd
--- /dev/null
+++ b/errors/invalid-assetprefix.md
@@ -0,0 +1,17 @@
+# Invalid assetPrefix
+
+#### Why This Error Occurred
+
+The value of `assetPrefix` in `next.config.js` is set to something that is not a `string`.
+
+#### Possible Ways to Fix It
+
+Ensure that `assetPrefix` is a `string`.
+
+Example:
+
+```js
+module.exports = {
+ assetPrefix: '/',
+}
+```
diff --git a/errors/invalid-getstaticpaths-value.md b/errors/invalid-getstaticpaths-value.md
new file mode 100644
index 00000000000000..f1e8543d9503e6
--- /dev/null
+++ b/errors/invalid-getstaticpaths-value.md
@@ -0,0 +1,40 @@
+# Invalid getStaticPaths Return Value
+
+#### Why This Error Occurred
+
+In one of the page's `getStaticPaths` the return value had the incorrect shape.
+
+#### Possible Ways to Fix It
+
+Make sure to return the following shape from `getStaticPaths`:
+
+```js
+export async function getStaticPaths() {
+ return {
+ paths: Array,
+ fallback: boolean
+ }
+}
+```
+
+There are two required properties:
+
+1. `paths`: this property is an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of URLs ("paths") that should be statically generated at build-time. The returned paths must match the dynamic route shape.
+ - You may return a [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String) or an [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) that explicitly defines all URL `params`.
+ ```js
+ // pages/blog/[slug].js
+ export async function getStaticPaths() {
+ return {
+ paths: [
+ // String variant:
+ '/blog/first-post',
+ // Object variant:
+ { params: { slug: 'second-post' } },
+ ],
+ fallback: true,
+ }
+ }
+ ```
+1. `fallback`: this property is a [Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean), specifying whether or not a fallback version of this page should be generated.
+ - Enabling `fallback` (via `true`) allows you to return a subset of all the possible paths that should be statically generated. At runtime, Next.js will statically generate the remaining paths the **first time they are requested**. Consecutive calls to the path will be served as-if it was statically generated at build-time. This reduces build times when dealing with thousands or millions of pages.
+ - Disabling `fallback` (via `false`) requires you return the full collection of paths you would like to statically generate at build-time. At runtime, any path that was not generated at build-time **will 404**.
diff --git a/errors/invalid-getstaticprops-value.md b/errors/invalid-getstaticprops-value.md
new file mode 100644
index 00000000000000..ccbfd7232d0772
--- /dev/null
+++ b/errors/invalid-getstaticprops-value.md
@@ -0,0 +1,21 @@
+# Invalid getStaticProps Return Value
+
+#### Why This Error Occurred
+
+In one of the page's `getStaticProps` the return value had the incorrect shape.
+
+#### Possible Ways to Fix It
+
+Make sure to return the following shape from `getStaticProps`:
+
+```js
+export async function getStaticProps(ctx: {
+ params?: ParsedUrlQuery
+ preview?: boolean
+ previewData?: any
+}) {
+ return {
+ props: { [key: string]: any }
+ }
+}
+```
diff --git a/errors/invalid-href-passed.md b/errors/invalid-href-passed.md
new file mode 100644
index 00000000000000..d01d327d923a16
--- /dev/null
+++ b/errors/invalid-href-passed.md
@@ -0,0 +1,19 @@
+# Invalid href passed to router
+
+#### Why This Error Occurred
+
+Next.js provides a router which can be utilized via a component imported via `next/link`, a wrapper `withRouter(Component)`, and now a hook `useRouter()`.
+When using any of these, it is expected they are only used for internal navigation, i.e. navigating between pages in the same Next.js application.
+
+Either you passed a non-internal `href` to a `next/link` component or you called `Router#push` or `Router#replace` with one.
+
+Invalid `href`s include external sites (https://google.com) and `mailto:` links. In the past, usage of these invalid `href`s could have gone unnoticed but since they can cause unexpected behavior.
+We now show a warning in development for them.
+
+#### Possible Ways to Fix It
+
+Look for any usage of `next/link` or `next/router` that is being passed a non-internal `href` and replace them with either an anchor tag (``) or `window.location.href = YOUR_HREF`.
+
+### Useful Links
+
+- [Routing section in Documentation](https://nextjs.org/docs#routing)
diff --git a/errors/invalid-multi-match.md b/errors/invalid-multi-match.md
new file mode 100644
index 00000000000000..cf9596b23d77a8
--- /dev/null
+++ b/errors/invalid-multi-match.md
@@ -0,0 +1,27 @@
+# Invalid Multi-match
+
+#### Why This Error Occurred
+
+In one of your custom-routes you specified a multi-match `/:path*` and used it in your `destination` without adding the `*` in your `destination` e.g. `destination: '/another/:path'`
+
+#### Possible Ways to Fix It
+
+Add `*` to your usage of the multi-match param in your `destination`.
+
+**Before**
+
+```js
+{
+ source: '/:path*',
+ destination: '/another/:path'
+}
+```
+
+**After**
+
+```js
+{
+ source: '/:path*',
+ destination: '/another/:path*'
+}
+```
diff --git a/errors/invalid-page-config.md b/errors/invalid-page-config.md
new file mode 100644
index 00000000000000..a71fb1862d6682
--- /dev/null
+++ b/errors/invalid-page-config.md
@@ -0,0 +1,26 @@
+# Invalid Page Config
+
+#### Why This Error Occurred
+
+In one of your pages you did `export const config` with an invalid value.
+
+#### Possible Ways to Fix It
+
+The page's config must be an object initialized directly when being exported.
+
+This is not allowed
+
+```js
+export const config = 'hello world'
+```
+
+This is allowed
+
+```js
+export const config = { amp: true }
+```
+
+### Useful Links
+
+- [Enabling AMP Support](https://nextjs.org/docs#enabling-amp-support)
+- [API Middlewares](https://nextjs.org/docs#api-middlewares)
diff --git a/errors/invalid-resolve-alias.md b/errors/invalid-resolve-alias.md
new file mode 100644
index 00000000000000..feacf2e3a62eba
--- /dev/null
+++ b/errors/invalid-resolve-alias.md
@@ -0,0 +1,22 @@
+# Invalid webpack resolve alias
+
+#### Why This Error Occurred
+
+When overriding `config.resolve.alias` incorrectly in `next.config.js` webpack will throw an error because private-next-pages is not defined.
+
+#### Possible Ways to Fix It
+
+This is not a bug in Next.js, it's related to the user adding a custom webpack(config) config to next.config.js and overriding internals by not applying Next.js' aliases. Solution would be:
+
+```js
+webpack(config) {
+ config.resolve.alias = {
+ ...config.resolve.alias,
+ // your aliases
+ }
+}
+```
+
+### Useful Links
+
+- [Related issue](https://github.com/zeit/next.js/issues/6681)
diff --git a/errors/invalid-route-source.md b/errors/invalid-route-source.md
new file mode 100644
index 00000000000000..07f17734272664
--- /dev/null
+++ b/errors/invalid-route-source.md
@@ -0,0 +1,32 @@
+# Invalid Custom Route `source`
+
+#### Why This Error Occurred
+
+When defining custom routes a route was added that causes an error during parsing. This can be due to trying to use normal `RegExp` syntax like negative lookaheads (`?!exclude`) without following `path-to-regexp`'s syntax for it.
+
+#### Possible Ways to Fix It
+
+Wrap the `RegExp` part of your `source` as an un-named parameter.
+
+**Before**
+
+```js
+{
+ source: '/feedback/(?!general)',
+ destination: '/feedback/general'
+}
+```
+
+**After**
+
+```js
+{
+ source: '/feedback/((?!general).*)',
+ destination: '/feedback/general'
+}
+```
+
+### Useful Links
+
+- [path-to-regexp](https://github.com/pillarjs/path-to-regexp)
+- [un-named paramters](https://github.com/pillarjs/path-to-regexp#unnamed-parameters)
diff --git a/errors/minification-disabled.md b/errors/minification-disabled.md
new file mode 100644
index 00000000000000..ca0bffeec711ea
--- /dev/null
+++ b/errors/minification-disabled.md
@@ -0,0 +1,14 @@
+# Minification Disabled in Production
+
+#### Why This Error Occurred
+
+Code optimization has been disabled for your **production build**.
+The `optimization.minimize` or `optimization.minimizer` was incorrectly overridden in `next.config.js`.
+
+This severely degrades your application's performance at runtime. It can also result in server-side-only code being downloaded by your users.
+
+#### Possible Ways to Fix It
+
+Be sure your `next.config.js` has not modified `optimization.minimize` or `optimization.minimizer`.
+
+You can file an issue on our GitHub if you do not understand why minification is being disabled by your `next.config.js`.
diff --git a/errors/missing-env-value.md b/errors/missing-env-value.md
new file mode 100644
index 00000000000000..7c2d3865f4ef0b
--- /dev/null
+++ b/errors/missing-env-value.md
@@ -0,0 +1,28 @@
+# Missing Env Value
+
+#### Why This Error Occurred
+
+One of your pages' config requested an env value that wasn't populated.
+
+```js
+// pages/index.js
+export const config = {
+ // this value isn't provided in `.env`
+ env: ['MISSING_KEY'],
+}
+```
+
+```
+// .env (notice no `MISSING_KEY` provided here)
+NOTION_KEY='...'
+```
+
+#### Possible Ways to Fix It
+
+Either remove the requested env value from the page's config, populate it in your `.env` file, or manually populate it in your environment before running `next dev` or `next build`.
+
+### Useful Links
+
+- [dotenv](https://npmjs.com/package/dotenv)
+- [dotenv-expand](https://npmjs.com/package/dotenv-expand)
+- [Environment Variables](https://en.wikipedia.org/wiki/Environment_variable)
diff --git a/errors/multi-tabs.md b/errors/multi-tabs.md
index 9b3b8320698246..bf4f3f3d4abe30 100644
--- a/errors/multi-tabs.md
+++ b/errors/multi-tabs.md
@@ -10,4 +10,3 @@ More info here: https://tools.ietf.org/html/rfc6202#section-5.1
- Don't have too many tabs open to the same Next.js site open in development in the same browser at the same time.
- If using Firefox you can increase this limit by navigating to `about:config` and setting `network.http.max-persistent-connections-per-server` to a higher number
-
diff --git a/errors/next-dynamic-modules.md b/errors/next-dynamic-modules.md
new file mode 100644
index 00000000000000..74838f30297663
--- /dev/null
+++ b/errors/next-dynamic-modules.md
@@ -0,0 +1,66 @@
+# `next/dynamic` has deprecated loading multiple modules at once
+
+#### Why This Error Occurred
+
+The ability to load multiple modules at once has been deprecated in `next/dynamic` to be closer to React's implementation (`React.lazy` and `Suspense`).
+
+Updating code that relies on this behavior is relatively straightforward! We've provided an example of a before/after to help you migrate your application:
+
+#### Possible Ways To Fix It
+
+Migrate to using separate dynamic calls for each module.
+
+Before
+
+```js
+import dynamic from 'next/dynamic'
+
+const HelloBundle = dynamic({
+ modules: () => {
+ const components = {
+ Hello1: () => import('../components/hello1').then(m => m.default),
+ Hello2: () => import('../components/hello2').then(m => m.default),
+ }
+
+ return components
+ },
+ render: (props, { Hello1, Hello2 }) => (
+
+ You can import AMP components using next/head. Checkout{' '}
+ components/amp/AmpCustomElement for a simple way to
+ import AMP components. Once the component is imported, you can use
+ it like any other HTML element.
+
+
+
+
+
+
+
+
+
+
+
amp-bind & amp-state
+
+ It's no problem to use amp-bind and{' '}
+ amp-state with Next.js. There are two things to be
+ aware of:
+
+
+ The [...] binding syntax{' '}
+ [text]="myStateVariable"is not supported in JSX.
+ Use data-amp-bind-text="myStateVariable" instead.
+
+
+ Initializing amp-state via JSON string is not
+ supported in JSX:
+
{`
+
+`}
+ Instead you need to use dangerouslySetInnerHTML to
+ initialize the string. can use the{' '}
+ /components/amp/AmpState.js component to see how it
+ works. The same approach works for amp-access and{' '}
+ amp-consent as well
+
+ Mustache templates conflict with JSX and it's template literals need
+ to be escaped. A simple approach is to escape them via back ticks:{' '}
+ src={`{{imageUrl}}`}.
+
+
+
+
+ {/* */}
+
+
+
+
+
+
+
+
+ {/* */}
+
+
+ >
+)
diff --git a/examples/amp/README.md b/examples/amp/README.md
index 9fbdc15d0f77a1..faf96be3ed42cc 100644
--- a/examples/amp/README.md
+++ b/examples/amp/README.md
@@ -1,15 +1,21 @@
-[](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/amp)
-
# Google AMP
+This example shows how to create AMP pages using Next.js and the AMP feature. It shows a normal page (non-AMP), an AMP only page, and a hybrid AMP page.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/amp)
+
## How to use
### Using `create-next-app`
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
-npx create-next-app --example amp amp-app
+npm init next-app --example amp amp-app
# or
yarn create next-app --example amp amp-app
```
@@ -33,12 +39,4 @@ yarn
yarn dev
```
-Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-
-This example shows how to create AMP pages using Next.js and the experimental AMP feature. It shows a normal page (non-AMP), an AMP only page, and a hybrid AMP page.
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/amp/components/Byline.js b/examples/amp/components/Byline.js
index 51c000653e7d02..af93c93e111850 100644
--- a/examples/amp/components/Byline.js
+++ b/examples/amp/components/Byline.js
@@ -1,6 +1,6 @@
export default ({ author }) => (
<>
-
+ )
+}
+
+export default Index
+
+export async function getStaticProps() {
+ // The name will be generated at build time only
+ const name = faker.name.findName()
+
+ return {
+ props: { name },
}
}
diff --git a/examples/api-routes-apollo-server-and-client-auth/README.md b/examples/api-routes-apollo-server-and-client-auth/README.md
new file mode 100644
index 00000000000000..269a82d59b8238
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client-auth/README.md
@@ -0,0 +1,43 @@
+# Apollo Server and Client Auth Example
+
+[Apollo](https://www.apollographql.com/client/) is a GraphQL client that allows you to easily query the exact data you need from a GraphQL server. In addition to fetching and mutating data, Apollo analyzes your queries and their results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run, fetching more results from the server.
+
+In this simple example, we integrate Apollo seamlessly with Next by wrapping our _pages/\_app.js_ inside a [higher-order component (HOC)](https://facebook.github.io/react/docs/higher-order-components.html). Using the HOC pattern we're able to pass down a central store of query result data created by Apollo into our React component hierarchy defined inside each page of our Next application.
+
+On initial page load, while on the server and inside `getInitialProps`, we invoke the Apollo method, [`getDataFromTree`](https://www.apollographql.com/docs/react/api/react-ssr/#getdatafromtree). This method returns a promise; at the point in which the promise resolves, our Apollo Client store is completely initialized.
+
+Note: Do not be alarmed that you see two renders being executed. Apollo recursively traverses the React render tree looking for Apollo query components. When it has done that, it fetches all these queries and then passes the result to a cache. This cache is then used to render the data on the server side (another React render).
+https://www.apollographql.com/docs/react/api/react-ssr/#getdatafromtree
+
+## How to use
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
+
+```bash
+npx create-next-app --example api-routes-apollo-server-and-client-auth api-routes-apollo-server-and-client-auth-app
+# or
+yarn create next-app --example api-routes-apollo-server-and-client-auth api-routes-apollo-server-and-client-auth-app
+```
+
+### Download manually
+
+Download the example:
+
+```bash
+curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/api-routes-apollo-server-and-client-auth
+cd api-routes-apollo-server-and-client-auth
+```
+
+Install it and run:
+
+```bash
+npm install
+npm run dev
+# or
+yarn
+yarn dev
+```
+
+> If you have issues installing `bcrypt`, follow this instructions: https://github.com/kelektiv/node.bcrypt.js/wiki/Installation-Instructions
diff --git a/examples/api-routes-apollo-server-and-client-auth/apollo/client.js b/examples/api-routes-apollo-server-and-client-auth/apollo/client.js
new file mode 100644
index 00000000000000..55135ad4eb17cb
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client-auth/apollo/client.js
@@ -0,0 +1,152 @@
+import React from 'react'
+import Head from 'next/head'
+import { ApolloProvider } from '@apollo/react-hooks'
+import { ApolloClient } from 'apollo-client'
+import { InMemoryCache } from 'apollo-cache-inmemory'
+
+let globalApolloClient = null
+
+/**
+ * Creates and provides the apolloContext
+ * to a next.js PageTree. Use it by wrapping
+ * your PageComponent via HOC pattern.
+ * @param {Function|Class} PageComponent
+ * @param {Object} [config]
+ * @param {Boolean} [config.ssr=true]
+ */
+export function withApollo(PageComponent, { ssr = true } = {}) {
+ const WithApollo = ({ apolloClient, apolloState, ...pageProps }) => {
+ const client = apolloClient || initApolloClient(undefined, apolloState)
+ return (
+
+
+
+ )
+ }
+
+ // Set the correct displayName in development
+ if (process.env.NODE_ENV !== 'production') {
+ const displayName =
+ PageComponent.displayName || PageComponent.name || 'Component'
+
+ if (displayName === 'App') {
+ console.warn('This withApollo HOC only works with PageComponents.')
+ }
+
+ WithApollo.displayName = `withApollo(${displayName})`
+ }
+
+ if (ssr || PageComponent.getInitialProps) {
+ WithApollo.getInitialProps = async ctx => {
+ const { AppTree } = ctx
+
+ // Initialize ApolloClient, add it to the ctx object so
+ // we can use it in `PageComponent.getInitialProp`.
+ const apolloClient = (ctx.apolloClient = initApolloClient({
+ res: ctx.res,
+ req: ctx.req,
+ }))
+
+ // Run wrapped getInitialProps methods
+ let pageProps = {}
+ if (PageComponent.getInitialProps) {
+ pageProps = await PageComponent.getInitialProps(ctx)
+ }
+
+ // Only on the server:
+ if (typeof window === 'undefined') {
+ // When redirecting, the response is finished.
+ // No point in continuing to render
+ if (ctx.res && ctx.res.finished) {
+ return pageProps
+ }
+
+ // Only if ssr is enabled
+ if (ssr) {
+ try {
+ // Run all GraphQL queries
+ const { getDataFromTree } = await import('@apollo/react-ssr')
+ await getDataFromTree(
+
+ )
+ } catch (error) {
+ // Prevent Apollo Client GraphQL errors from crashing SSR.
+ // Handle them in components via the data.error prop:
+ // https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
+ console.error('Error while running `getDataFromTree`', error)
+ }
+
+ // getDataFromTree does not call componentWillUnmount
+ // head side effect therefore need to be cleared manually
+ Head.rewind()
+ }
+ }
+
+ // Extract query data from the Apollo store
+ const apolloState = apolloClient.cache.extract()
+
+ return {
+ ...pageProps,
+ apolloState,
+ }
+ }
+ }
+
+ return WithApollo
+}
+
+/**
+ * Always creates a new apollo client on the server
+ * Creates or reuses apollo client in the browser.
+ * @param {Object} initialState
+ */
+function initApolloClient(ctx, initialState) {
+ // Make sure to create a new client for every server-side request so that data
+ // isn't shared between connections (which would be bad)
+ if (typeof window === 'undefined') {
+ return createApolloClient(ctx, initialState)
+ }
+
+ // Reuse client on the client-side
+ if (!globalApolloClient) {
+ globalApolloClient = createApolloClient(ctx, initialState)
+ }
+
+ return globalApolloClient
+}
+
+/**
+ * Creates and configures the ApolloClient
+ * @param {Object} [initialState={}]
+ */
+function createApolloClient(ctx = {}, initialState = {}) {
+ const ssrMode = typeof window === 'undefined'
+ const cache = new InMemoryCache().restore(initialState)
+
+ // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient
+ return new ApolloClient({
+ ssrMode,
+ link: createIsomorphLink(ctx),
+ cache,
+ })
+}
+
+function createIsomorphLink(ctx) {
+ if (typeof window === 'undefined') {
+ const { SchemaLink } = require('apollo-link-schema')
+ const { schema } = require('./schema')
+ return new SchemaLink({ schema, context: ctx })
+ } else {
+ const { HttpLink } = require('apollo-link-http')
+
+ return new HttpLink({
+ uri: '/api/graphql',
+ credentials: 'same-origin',
+ })
+ }
+}
diff --git a/examples/api-routes-apollo-server-and-client-auth/apollo/resolvers.js b/examples/api-routes-apollo-server-and-client-auth/apollo/resolvers.js
new file mode 100644
index 00000000000000..76e6d851cdba0c
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client-auth/apollo/resolvers.js
@@ -0,0 +1,95 @@
+import { AuthenticationError, UserInputError } from 'apollo-server-micro'
+import cookie from 'cookie'
+import jwt from 'jsonwebtoken'
+import getConfig from 'next/config'
+import bcrypt from 'bcrypt'
+import v4 from 'uuid/v4'
+
+const JWT_SECRET = getConfig().serverRuntimeConfig.JWT_SECRET
+
+const users = []
+
+function createUser(data) {
+ const salt = bcrypt.genSaltSync()
+
+ return {
+ id: v4(),
+ email: data.email,
+ hashedPassword: bcrypt.hashSync(data.password, salt),
+ }
+}
+
+function validPassword(user, password) {
+ return bcrypt.compareSync(password, user.hashedPassword)
+}
+
+export const resolvers = {
+ Query: {
+ async viewer(_parent, _args, context, _info) {
+ const { token } = cookie.parse(context.req.headers.cookie ?? '')
+ if (token) {
+ try {
+ const { id, email } = jwt.verify(token, JWT_SECRET)
+
+ return users.find(user => user.id === id && user.email === email)
+ } catch {
+ throw new AuthenticationError(
+ 'Authentication token is invalid, please log in'
+ )
+ }
+ }
+ },
+ },
+ Mutation: {
+ async signUp(_parent, args, _context, _info) {
+ const user = createUser(args.input)
+
+ users.push(user)
+
+ return { user }
+ },
+
+ async signIn(_parent, args, context, _info) {
+ const user = users.find(user => user.email === args.input.email)
+
+ if (user && validPassword(user, args.input.password)) {
+ const token = jwt.sign(
+ { email: user.email, id: user.id, time: new Date() },
+ JWT_SECRET,
+ {
+ expiresIn: '6h',
+ }
+ )
+
+ context.res.setHeader(
+ 'Set-Cookie',
+ cookie.serialize('token', token, {
+ httpOnly: true,
+ maxAge: 6 * 60 * 60,
+ path: '/',
+ sameSite: 'lax',
+ secure: process.env.NODE_ENV === 'production',
+ })
+ )
+
+ return { user }
+ }
+
+ throw new UserInputError('Invalid email and password combination')
+ },
+ async signOut(_parent, _args, context, _info) {
+ context.res.setHeader(
+ 'Set-Cookie',
+ cookie.serialize('token', '', {
+ httpOnly: true,
+ maxAge: -1,
+ path: '/',
+ sameSite: 'lax',
+ secure: process.env.NODE_ENV === 'production',
+ })
+ )
+
+ return true
+ },
+ },
+}
diff --git a/examples/api-routes-apollo-server-and-client-auth/apollo/schema.js b/examples/api-routes-apollo-server-and-client-auth/apollo/schema.js
new file mode 100644
index 00000000000000..f6d70b7e86243c
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client-auth/apollo/schema.js
@@ -0,0 +1,8 @@
+import { makeExecutableSchema } from 'graphql-tools'
+import { typeDefs } from './type-defs'
+import { resolvers } from './resolvers'
+
+export const schema = makeExecutableSchema({
+ typeDefs,
+ resolvers,
+})
diff --git a/examples/api-routes-apollo-server-and-client-auth/apollo/type-defs.js b/examples/api-routes-apollo-server-and-client-auth/apollo/type-defs.js
new file mode 100644
index 00000000000000..cd77f1e5b26e7d
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client-auth/apollo/type-defs.js
@@ -0,0 +1,38 @@
+import gql from 'graphql-tag'
+
+export const typeDefs = gql`
+ type User {
+ id: ID!
+ email: String!
+ }
+
+ input SignUpInput {
+ email: String!
+ password: String!
+ }
+
+ input SignInInput {
+ email: String!
+ password: String!
+ }
+
+ type SignUpPayload {
+ user: User!
+ }
+
+ type SignInPayload {
+ user: User!
+ }
+
+ type Query {
+ user(id: ID!): User!
+ users: [User]!
+ viewer: User
+ }
+
+ type Mutation {
+ signUp(input: SignUpInput!): SignUpPayload!
+ signIn(input: SignInInput!): SignInPayload!
+ signOut: Boolean!
+ }
+`
diff --git a/examples/api-routes-apollo-server-and-client-auth/components/field.js b/examples/api-routes-apollo-server-and-client-auth/components/field.js
new file mode 100644
index 00000000000000..5ad6fa2e3548e7
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client-auth/components/field.js
@@ -0,0 +1,21 @@
+export default function Field(props) {
+ return (
+
+
+ >
+ )
+}
+
+export default withApollo(SignUp)
diff --git a/examples/api-routes-apollo-server-and-client/README.md b/examples/api-routes-apollo-server-and-client/README.md
new file mode 100644
index 00000000000000..6135512ca3b46b
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/README.md
@@ -0,0 +1,41 @@
+# Apollo Server and Client Example
+
+[Apollo](https://www.apollographql.com/client/) is a GraphQL client that allows you to easily query the exact data you need from a GraphQL server. In addition to fetching and mutating data, Apollo analyzes your queries and their results to construct a client-side cache of your data, which is kept up to date as further queries and mutations are run, fetching more results from the server.
+
+In this simple example, we integrate Apollo seamlessly with Next by wrapping our _pages/\_app.js_ inside a [higher-order component (HOC)](https://facebook.github.io/react/docs/higher-order-components.html). Using the HOC pattern we're able to pass down a central store of query result data created by Apollo into our React component hierarchy defined inside each page of our Next application.
+
+On initial page load, while on the server and inside `getInitialProps`, we invoke the Apollo method, [`getDataFromTree`](https://www.apollographql.com/docs/react/api/react-ssr/#getdatafromtree). This method returns a promise; at the point in which the promise resolves, our Apollo Client store is completely initialized.
+
+Note: Do not be alarmed that you see two renders being executed. Apollo recursively traverses the React render tree looking for Apollo query components. When it has done that, it fetches all these queries and then passes the result to a cache. This cache is then used to render the data on the server side (another React render).
+https://www.apollographql.com/docs/react/api/react-ssr/#getdatafromtree
+
+## How to use
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
+
+```bash
+npm init next-app --example api-routes-apollo-server-and-client api-routes-apollo-server-and-client-app
+# or
+yarn create next-app --example api-routes-apollo-server-and-client api-routes-apollo-server-and-client-app
+```
+
+### Download manually
+
+Download the example:
+
+```bash
+curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/api-routes-apollo-server-and-client
+cd api-routes-apollo-server-and-client
+```
+
+Install it and run:
+
+```bash
+npm install
+npm run dev
+# or
+yarn
+yarn dev
+```
diff --git a/examples/api-routes-apollo-server-and-client/apollo/client.js b/examples/api-routes-apollo-server-and-client/apollo/client.js
new file mode 100644
index 00000000000000..d39cf04f042fd0
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/apollo/client.js
@@ -0,0 +1,148 @@
+import React from 'react'
+import Head from 'next/head'
+import { ApolloProvider } from '@apollo/react-hooks'
+import { ApolloClient } from 'apollo-client'
+import { InMemoryCache } from 'apollo-cache-inmemory'
+
+let globalApolloClient = null
+
+/**
+ * Creates and provides the apolloContext
+ * to a next.js PageTree. Use it by wrapping
+ * your PageComponent via HOC pattern.
+ * @param {Function|Class} PageComponent
+ * @param {Object} [config]
+ * @param {Boolean} [config.ssr=true]
+ */
+export function withApollo(PageComponent, { ssr = true } = {}) {
+ const WithApollo = ({ apolloClient, apolloState, ...pageProps }) => {
+ const client = apolloClient || initApolloClient(apolloState)
+ return (
+
+
+
+ )
+ }
+
+ // Set the correct displayName in development
+ if (process.env.NODE_ENV !== 'production') {
+ const displayName =
+ PageComponent.displayName || PageComponent.name || 'Component'
+
+ if (displayName === 'App') {
+ console.warn('This withApollo HOC only works with PageComponents.')
+ }
+
+ WithApollo.displayName = `withApollo(${displayName})`
+ }
+
+ if (ssr || PageComponent.getInitialProps) {
+ WithApollo.getInitialProps = async ctx => {
+ const { AppTree } = ctx
+
+ // Initialize ApolloClient, add it to the ctx object so
+ // we can use it in `PageComponent.getInitialProp`.
+ const apolloClient = (ctx.apolloClient = initApolloClient())
+
+ // Run wrapped getInitialProps methods
+ let pageProps = {}
+ if (PageComponent.getInitialProps) {
+ pageProps = await PageComponent.getInitialProps(ctx)
+ }
+
+ // Only on the server:
+ if (typeof window === 'undefined') {
+ // When redirecting, the response is finished.
+ // No point in continuing to render
+ if (ctx.res && ctx.res.finished) {
+ return pageProps
+ }
+
+ // Only if ssr is enabled
+ if (ssr) {
+ try {
+ // Run all GraphQL queries
+ const { getDataFromTree } = await import('@apollo/react-ssr')
+ await getDataFromTree(
+
+ )
+ } catch (error) {
+ // Prevent Apollo Client GraphQL errors from crashing SSR.
+ // Handle them in components via the data.error prop:
+ // https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
+ console.error('Error while running `getDataFromTree`', error)
+ }
+
+ // getDataFromTree does not call componentWillUnmount
+ // head side effect therefore need to be cleared manually
+ Head.rewind()
+ }
+ }
+
+ // Extract query data from the Apollo store
+ const apolloState = apolloClient.cache.extract()
+
+ return {
+ ...pageProps,
+ apolloState,
+ }
+ }
+ }
+
+ return WithApollo
+}
+
+/**
+ * Always creates a new apollo client on the server
+ * Creates or reuses apollo client in the browser.
+ * @param {Object} initialState
+ */
+function initApolloClient(initialState) {
+ // Make sure to create a new client for every server-side request so that data
+ // isn't shared between connections (which would be bad)
+ if (typeof window === 'undefined') {
+ return createApolloClient(initialState)
+ }
+
+ // Reuse client on the client-side
+ if (!globalApolloClient) {
+ globalApolloClient = createApolloClient(initialState)
+ }
+
+ return globalApolloClient
+}
+
+/**
+ * Creates and configures the ApolloClient
+ * @param {Object} [initialState={}]
+ */
+function createApolloClient(initialState = {}) {
+ const ssrMode = typeof window === 'undefined'
+ const cache = new InMemoryCache().restore(initialState)
+
+ // Check out https://github.com/zeit/next.js/pull/4611 if you want to use the AWSAppSyncClient
+ return new ApolloClient({
+ ssrMode,
+ link: createIsomorphLink(),
+ cache,
+ })
+}
+
+function createIsomorphLink() {
+ if (typeof window === 'undefined') {
+ const { SchemaLink } = require('apollo-link-schema')
+ const { schema } = require('./schema')
+ return new SchemaLink({ schema })
+ } else {
+ const { HttpLink } = require('apollo-link-http')
+ return new HttpLink({
+ uri: '/api/graphql',
+ credentials: 'same-origin',
+ })
+ }
+}
diff --git a/examples/api-routes-apollo-server-and-client/apollo/resolvers.js b/examples/api-routes-apollo-server-and-client/apollo/resolvers.js
new file mode 100644
index 00000000000000..94a103eda6606b
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/apollo/resolvers.js
@@ -0,0 +1,7 @@
+export const resolvers = {
+ Query: {
+ viewer(_parent, _args, _context, _info) {
+ return { id: 1, name: 'John Smith', status: 'cached' }
+ },
+ },
+}
diff --git a/examples/api-routes-apollo-server-and-client/apollo/schema.js b/examples/api-routes-apollo-server-and-client/apollo/schema.js
new file mode 100644
index 00000000000000..f6d70b7e86243c
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/apollo/schema.js
@@ -0,0 +1,8 @@
+import { makeExecutableSchema } from 'graphql-tools'
+import { typeDefs } from './type-defs'
+import { resolvers } from './resolvers'
+
+export const schema = makeExecutableSchema({
+ typeDefs,
+ resolvers,
+})
diff --git a/examples/api-routes-apollo-server-and-client/apollo/type-defs.js b/examples/api-routes-apollo-server-and-client/apollo/type-defs.js
new file mode 100644
index 00000000000000..e6da839c1b6506
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/apollo/type-defs.js
@@ -0,0 +1,13 @@
+import gql from 'graphql-tag'
+
+export const typeDefs = gql`
+ type User {
+ id: ID!
+ name: String!
+ status: String!
+ }
+
+ type Query {
+ viewer: User
+ }
+`
diff --git a/examples/api-routes-apollo-server-and-client/package.json b/examples/api-routes-apollo-server-and-client/package.json
new file mode 100644
index 00000000000000..cdab52d8526d56
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "with-apollo",
+ "version": "2.0.0",
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "@apollo/react-common": "3.0.1",
+ "@apollo/react-hooks": "3.0.1",
+ "@apollo/react-ssr": "3.0.1",
+ "apollo-cache-inmemory": "1.6.3",
+ "apollo-client": "2.6.4",
+ "apollo-link-http": "1.5.15",
+ "apollo-link-schema": "1.2.3",
+ "apollo-server-micro": "2.9.0",
+ "apollo-utilities": "^1.3.2",
+ "graphql": "^14.0.2",
+ "graphql-tag": "2.10.1",
+ "next": "latest",
+ "prop-types": "^15.6.2",
+ "react": "^16.7.0",
+ "react-dom": "^16.7.0"
+ },
+ "author": "",
+ "license": "ISC"
+}
diff --git a/examples/api-routes-apollo-server-and-client/pages/about.js b/examples/api-routes-apollo-server-and-client/pages/about.js
new file mode 100644
index 00000000000000..37a11a9e09651f
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/pages/about.js
@@ -0,0 +1,11 @@
+import Link from 'next/link'
+
+export default () => (
+
+ This is a static page goto{' '}
+
+ dynamic
+ {' '}
+ page.
+
+)
diff --git a/examples/api-routes-apollo-server-and-client/pages/api/graphql.js b/examples/api-routes-apollo-server-and-client/pages/api/graphql.js
new file mode 100644
index 00000000000000..5efa800e28cd86
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/pages/api/graphql.js
@@ -0,0 +1,12 @@
+import { ApolloServer } from 'apollo-server-micro'
+import { schema } from '../../apollo/schema'
+
+const apolloServer = new ApolloServer({ schema })
+
+export const config = {
+ api: {
+ bodyParser: false,
+ },
+}
+
+export default apolloServer.createHandler({ path: '/api/graphql' })
diff --git a/examples/api-routes-apollo-server-and-client/pages/index.js b/examples/api-routes-apollo-server-and-client/pages/index.js
new file mode 100644
index 00000000000000..33ab4252a092d2
--- /dev/null
+++ b/examples/api-routes-apollo-server-and-client/pages/index.js
@@ -0,0 +1,36 @@
+import { withApollo } from '../apollo/client'
+import gql from 'graphql-tag'
+import Link from 'next/link'
+import { useQuery } from '@apollo/react-hooks'
+
+const ViewerQuery = gql`
+ query ViewerQuery {
+ viewer {
+ id
+ name
+ status
+ }
+ }
+`
+
+const Index = () => {
+ const {
+ data: { viewer },
+ } = useQuery(ViewerQuery)
+
+ if (viewer) {
+ return (
+
+ You're signed in as {viewer.name} and you're {viewer.status} goto{' '}
+
+ static
+ {' '}
+ page.
+
+ )
+ }
+
+ return null
+}
+
+export default withApollo(Index)
diff --git a/examples/api-routes-graphql/README.md b/examples/api-routes-graphql/README.md
new file mode 100644
index 00000000000000..5c583ba56e65fd
--- /dev/null
+++ b/examples/api-routes-graphql/README.md
@@ -0,0 +1,42 @@
+# API routes with GraphQL server
+
+Next.js ships with [API routes](https://github.com/zeit/next.js#api-routes), which provide an easy solution to build your own `API`. This example shows their usage alongside [apollo-server-micro](https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-micro) to provide simple GraphQL server consumed by Next.js app.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/api-routes-graphql)
+
+## How to use
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
+
+```bash
+npm init next-app --example api-routes-graphql api-routes-graphql-app
+# or
+yarn create next-app --example api-routes-graphql api-routes-graphql-app
+```
+
+### Download manually
+
+Download the example:
+
+```bash
+curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/api-routes-graphql
+cd api-routes-graphql
+```
+
+Install it and run:
+
+```bash
+npm install
+npm run dev
+# or
+yarn
+yarn dev
+```
+
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/api-routes-graphql/package.json b/examples/api-routes-graphql/package.json
new file mode 100644
index 00000000000000..f64edb42454046
--- /dev/null
+++ b/examples/api-routes-graphql/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "api-routes-graphql",
+ "version": "1.0.0",
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "apollo-server-micro": "2.6.7",
+ "graphql": "14.4.2",
+ "isomorphic-unfetch": "3.0.0",
+ "next": "latest",
+ "react": "^16.8.6",
+ "react-dom": "^16.8.6"
+ },
+ "license": "ISC"
+}
diff --git a/examples/api-routes-graphql/pages/api/graphql.js b/examples/api-routes-graphql/pages/api/graphql.js
new file mode 100644
index 00000000000000..0dcb066bbcbdcf
--- /dev/null
+++ b/examples/api-routes-graphql/pages/api/graphql.js
@@ -0,0 +1,28 @@
+import { ApolloServer, gql } from 'apollo-server-micro'
+
+const typeDefs = gql`
+ type Query {
+ users: [User!]!
+ }
+ type User {
+ name: String
+ }
+`
+
+const resolvers = {
+ Query: {
+ users(parent, args, context) {
+ return [{ name: 'Nextjs' }]
+ },
+ },
+}
+
+const apolloServer = new ApolloServer({ typeDefs, resolvers })
+
+export const config = {
+ api: {
+ bodyParser: false,
+ },
+}
+
+export default apolloServer.createHandler({ path: '/api/graphql' })
diff --git a/examples/api-routes-graphql/pages/index.js b/examples/api-routes-graphql/pages/index.js
new file mode 100644
index 00000000000000..98edfabc2770c5
--- /dev/null
+++ b/examples/api-routes-graphql/pages/index.js
@@ -0,0 +1,27 @@
+import fetch from 'isomorphic-unfetch'
+
+const Index = ({ users }) => (
+
+ {users.map((user, i) => (
+
{user.name}
+ ))}
+
+)
+
+Index.getInitialProps = async () => {
+ const response = await fetch('http://localhost:3000/api/graphql', {
+ method: 'POST',
+ headers: {
+ 'Content-type': 'application/json',
+ },
+ body: JSON.stringify({ query: '{ users { name } }' }),
+ })
+
+ const {
+ data: { users },
+ } = await response.json()
+
+ return { users }
+}
+
+export default Index
diff --git a/examples/api-routes-middleware/README.md b/examples/api-routes-middleware/README.md
new file mode 100644
index 00000000000000..4e058d564928cb
--- /dev/null
+++ b/examples/api-routes-middleware/README.md
@@ -0,0 +1,42 @@
+# API routes with middleware
+
+Next.js ships with [API routes](https://github.com/zeit/next.js#api-routes), which provide an easy solution to build your own `API`. This example shows how to implement simple `middleware` to wrap around your `API` endpoints.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/api-routes-middleware)
+
+## How to use
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
+
+```bash
+npm init next-app --example api-routes-middleware api-routes-middleware-app
+# or
+yarn create next-app --example api-routes-middleware api-routes-middleware-app
+```
+
+### Download manually
+
+Download the example:
+
+```bash
+curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/api-routes-middleware
+cd api-routes-middleware
+```
+
+Install it and run:
+
+```bash
+npm install
+npm run dev
+# or
+yarn
+yarn dev
+```
+
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/api-routes-middleware/package.json b/examples/api-routes-middleware/package.json
new file mode 100644
index 00000000000000..d817c48fa0cb98
--- /dev/null
+++ b/examples/api-routes-middleware/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "api-routes-middleware",
+ "version": "1.0.0",
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "cookie": "0.4.0",
+ "isomorphic-unfetch": "3.0.0",
+ "next": "latest",
+ "react": "^16.8.6",
+ "react-dom": "^16.8.6"
+ },
+ "license": "ISC"
+}
diff --git a/examples/api-routes-middleware/pages/api/cookies.js b/examples/api-routes-middleware/pages/api/cookies.js
new file mode 100644
index 00000000000000..d31fa9d36d01fc
--- /dev/null
+++ b/examples/api-routes-middleware/pages/api/cookies.js
@@ -0,0 +1,8 @@
+import cookies from '../../utils/cookies'
+
+const handler = (req, res) => {
+ res.cookie('Next.js', 'api-middleware!')
+ res.end('Hello Next.js middleware!')
+}
+
+export default cookies(handler)
diff --git a/examples/api-routes-middleware/pages/index.js b/examples/api-routes-middleware/pages/index.js
new file mode 100644
index 00000000000000..757276eb807c1d
--- /dev/null
+++ b/examples/api-routes-middleware/pages/index.js
@@ -0,0 +1,12 @@
+import fetch from 'isomorphic-unfetch'
+
+const Index = ({ cookie }) =>
{`Cookie from response: ${cookie}`}
+
+export async function getServerSideProps() {
+ const response = await fetch('http://localhost:3000/api/cookies')
+ const cookie = response.headers.get('set-cookie')
+
+ return { props: { cookie } }
+}
+
+export default Index
diff --git a/examples/api-routes-middleware/utils/cookies.js b/examples/api-routes-middleware/utils/cookies.js
new file mode 100644
index 00000000000000..6409c7361726ef
--- /dev/null
+++ b/examples/api-routes-middleware/utils/cookies.js
@@ -0,0 +1,27 @@
+import { serialize } from 'cookie'
+
+/**
+ * This sets `cookie` on `res` object
+ */
+const cookie = (res, name, value, options = {}) => {
+ const stringValue =
+ typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value)
+
+ if ('maxAge' in options) {
+ options.expires = new Date(Date.now() + options.maxAge)
+ options.maxAge /= 1000
+ }
+
+ res.setHeader('Set-Cookie', serialize(name, String(stringValue), options))
+}
+
+/**
+ * Adds `cookie` function on `res.cookie` to set cookies for response
+ */
+const cookies = handler => (req, res) => {
+ res.cookie = (name, value, options) => cookie(res, name, value, options)
+
+ return handler(req, res)
+}
+
+export default cookies
diff --git a/examples/api-routes-rest/README.md b/examples/api-routes-rest/README.md
new file mode 100644
index 00000000000000..abc7eab054909d
--- /dev/null
+++ b/examples/api-routes-rest/README.md
@@ -0,0 +1,25 @@
+# API routes with REST
+
+Next.js ships with [API routes](https://github.com/zeit/next.js#api-routes), which provide an easy solution to build your own `API`. This example shows how it can be used to create your [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) api.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/api-routes-rest)
+
+## How to use
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
+
+```bash
+npm init next-app --example api-routes-rest api-routes-rest-app
+# or
+yarn create next-app --example api-routes-rest api-routes-rest-app
+```
+
+### Deploy to Now
+
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/api-routes-rest/package.json b/examples/api-routes-rest/package.json
new file mode 100644
index 00000000000000..2ccd1a3e68fecd
--- /dev/null
+++ b/examples/api-routes-rest/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "api-routes-rest",
+ "version": "1.0.0",
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "next": "latest",
+ "react": "^16.8.6",
+ "react-dom": "^16.8.6",
+ "swr": "^0.1.18"
+ },
+ "license": "ISC"
+}
diff --git a/examples/api-routes-rest/pages/api/user/[id].js b/examples/api-routes-rest/pages/api/user/[id].js
new file mode 100644
index 00000000000000..07b5e4f4199d3b
--- /dev/null
+++ b/examples/api-routes-rest/pages/api/user/[id].js
@@ -0,0 +1,20 @@
+export default (req, res) => {
+ const {
+ query: { id, name },
+ method,
+ } = req
+
+ switch (method) {
+ case 'GET':
+ // Get data from your database
+ res.status(200).json({ id, name: `User ${id}` })
+ break
+ case 'PUT':
+ // Update or create data in your database
+ res.status(200).json({ id, name: name || `User ${id}` })
+ break
+ default:
+ res.setHeader('Allow', ['GET', 'PUT'])
+ res.status(405).end(`Method ${method} Not Allowed`)
+ }
+}
diff --git a/examples/api-routes-rest/pages/api/users.js b/examples/api-routes-rest/pages/api/users.js
new file mode 100644
index 00000000000000..288d6f422955e3
--- /dev/null
+++ b/examples/api-routes-rest/pages/api/users.js
@@ -0,0 +1,7 @@
+// Fake users data
+const users = [{ id: 1 }, { id: 2 }, { id: 3 }]
+
+export default (req, res) => {
+ // Get data from your database
+ res.status(200).json(users)
+}
diff --git a/examples/api-routes-rest/pages/index.js b/examples/api-routes-rest/pages/index.js
new file mode 100644
index 00000000000000..861919c5e3d846
--- /dev/null
+++ b/examples/api-routes-rest/pages/index.js
@@ -0,0 +1,23 @@
+import useSwr from 'swr'
+import Link from 'next/link'
+
+const fetcher = url => fetch(url).then(res => res.json())
+
+export default function Index() {
+ const { data, error } = useSwr('/api/users', fetcher)
+
+ if (error) return
+}
diff --git a/examples/api-routes/README.md b/examples/api-routes/README.md
new file mode 100644
index 00000000000000..84a3e2cd859921
--- /dev/null
+++ b/examples/api-routes/README.md
@@ -0,0 +1,42 @@
+# Basic API routes example
+
+Next.js ships with [API routes](https://github.com/zeit/next.js#api-routes) which provides an easy solution to build your own `API`. This example shows how to create multiple `API` endpoints with serverless functions, which can execute independently.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/api-routes)
+
+## How to use
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
+
+```bash
+npm init next-app --example api-routes api-routes-app
+# or
+yarn create next-app --example api-routes api-routes-app
+```
+
+### Download manually
+
+Download the example:
+
+```bash
+curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/api-routes
+cd api-routes
+```
+
+Install it and run:
+
+```bash
+npm install
+npm run dev
+# or
+yarn
+yarn dev
+```
+
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/api-routes/components/Person.js b/examples/api-routes/components/Person.js
new file mode 100644
index 00000000000000..d43584b1668bc3
--- /dev/null
+++ b/examples/api-routes/components/Person.js
@@ -0,0 +1,9 @@
+import Link from 'next/link'
+
+export default ({ person }) => (
+
+)
+
+export async function getServerSideProps() {
+ const response = await fetch('http://localhost:3000/api/people')
+ const people = await response.json()
+
+ return { props: { people } }
+}
+
+export default Index
diff --git a/examples/api-routes/pages/person/[id].js b/examples/api-routes/pages/person/[id].js
new file mode 100644
index 00000000000000..34d63cce840c51
--- /dev/null
+++ b/examples/api-routes/pages/person/[id].js
@@ -0,0 +1,45 @@
+import fetch from 'node-fetch'
+
+const Person = ({ data, status }) =>
+ status === 200 ? (
+
+
+
+
Name
+
Height
+
Mass
+
Hair color
+
Skin color
+
Eye color
+
Gender
+
+
+
+
+
{data.name}
+
{data.height}
+
{data.mass}
+
{data.hair_color}
+
{data.skin_color}
+
{data.eye_color}
+
{data.gender}
+
+
+
+ ) : (
+
{data.message}
+ )
+
+export async function getServerSideProps({ params }) {
+ const response = await fetch(`http://localhost:3000/api/people/${params.id}`)
+ const data = await response.json()
+
+ return {
+ props: {
+ data,
+ status: response.status,
+ },
+ }
+}
+
+export default Person
diff --git a/examples/auth0/.env.template b/examples/auth0/.env.template
new file mode 100644
index 00000000000000..52f96ccb544fbc
--- /dev/null
+++ b/examples/auth0/.env.template
@@ -0,0 +1,6 @@
+AUTH0_CLIENT_ID=
+AUTH0_DOMAIN=
+AUTH0_CLIENT_SECRET=
+REDIRECT_URI=
+POST_LOGOUT_REDIRECT_URI=
+SESSION_COOKIE_SECRET=
diff --git a/examples/auth0/.gitignore b/examples/auth0/.gitignore
new file mode 100644
index 00000000000000..120b715f547794
--- /dev/null
+++ b/examples/auth0/.gitignore
@@ -0,0 +1,3 @@
+node_modules
+.env
+.next
\ No newline at end of file
diff --git a/examples/auth0/README.md b/examples/auth0/README.md
new file mode 100644
index 00000000000000..ef4dfe8be1c38d
--- /dev/null
+++ b/examples/auth0/README.md
@@ -0,0 +1,100 @@
+# Next.js and Auth0 Example
+
+This example shows how you can use `@auth0/nextjs-auth` to easily add authentication support to your Next.js application.
+
+Read more: [https://auth0.com/blog/ultimate-guide-nextjs-authentication-auth0/](https://auth0.com/blog/ultimate-guide-nextjs-authentication-auth0/)
+
+### Using `create-next-app`
+
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
+
+```bash
+npm init next-app --example auth0 auth0
+# or
+yarn create next-app --example auth0 auth0
+```
+
+## Configuring Auth0
+
+1. Go to the [Auth0 dashboard](https://manage.auth0.com/) and create a new application of type _Regular Web Applications_ and make sure to configure the following
+2. Go to the settings page of the application
+3. Configure the following settings:
+
+- _Allowed Callback URLs_: Should be set to `http://localhost:3000/api/callback` when testing locally or typically to `https://myapp.com/api/callback` when deploying your application.
+- _Allowed Logout URLs_: Should be set to `http://localhost:3000/` when testing locally or typically to `https://myapp.com/` when deploying your application.
+
+4. Save the settings
+
+### Configuring Next.js
+
+In the Next.js configuration file (`next.config.js`) you'll see that different environment variables are being assigned.
+
+### Local Development
+
+For local development you'll want to create a `.env` file with the necessary settings.
+
+The required settings can be found on the Auth0 application's settings page:
+
+```
+AUTH0_DOMAIN=YOUR_AUTH0_DOMAIN
+AUTH0_CLIENT_ID=YOUR_AUTH0_CLIENT_ID
+AUTH0_CLIENT_SECRET=YOUR_AUTH0_CLIENT_SECRET
+
+SESSION_COOKIE_SECRET=viloxyf_z2GW6K4CT-KQD_MoLEA2wqv5jWuq4Jd0P7ymgG5GJGMpvMneXZzhK3sL (at least 32 characters, used to encrypt the cookie)
+
+REDIRECT_URI=http://localhost:3000/api/callback
+POST_LOGOUT_REDIRECT_URI=http://localhost:3000/
+```
+
+### Hosting on ZEIT Now
+
+When deploying this example to ZEIT Now you'll want to update the `now.json` configuration file.
+
+```json
+{
+ "build": {
+ "env": {
+ "AUTH0_DOMAIN": "YOUR_AUTH0_DOMAIN",
+ "AUTH0_CLIENT_ID": "YOUR_AUTH0_CLIENT_ID",
+ "AUTH0_CLIENT_SECRET": "@auth0_client_secret",
+ "REDIRECT_URI": "https://my-website.now.sh/api/callback",
+ "POST_LOGOUT_REDIRECT_URI": "https://my-website.now.sh/",
+ "SESSION_COOKIE_SECRET": "@session_cookie_secret",
+ "SESSION_COOKIE_LIFETIME": 7200
+ }
+ }
+}
+```
+
+- `AUTH0_DOMAIN` - Can be found in the Auth0 dashboard under `settings`.
+- `AUTH0_CLIENT_ID` - Can be found in the Auth0 dashboard under `settings`.
+- `AUTH0_CLIENT_SECRET` - Can be found in the Auth0 dashboard under `settings`.
+- `REDIRECT_URI` - The url where Auth0 redirects back to, make sure a consistent url is used here.
+- `POST_LOGOUT_REDIRECT_URI` - Where to redirect after logging out
+- `SESSION_COOKIE_SECRET` - A unique secret used to encrypt the cookies, has to be at least 32 characters. You can use [this generator](https://generate-secret.now.sh/32) to generate a value.
+- `SESSION_COOKIE_LIFETIME` - How long a session lasts in seconds. The default is 2 hours.
+
+The `@auth0_client_secret` and `@session_cookie_secret` are [ZEIT Now environment secrets](https://zeit.co/docs/v2/environment-variables-and-secrets/)
+
+You can create the `@auth0_client_secret` by running:
+
+```
+now secrets add auth0_client_secret PLACE_YOUR_AUTH0_CLIENT_SECRET
+```
+
+And create the `session_cookie_secret` by generating a value [here](https://generate-secret.now.sh/32) and running:
+
+```
+now secrets add session_cookie_secret PLACE_YOUR_SESSION_COOKIE_SECRET
+```
+
+## About this sample
+
+This sample tries to cover a few topics:
+
+- Signing in
+- Signing out
+- Loading the user on the server side and adding it as part of SSR (`/pages/advanced/ssr-profile.js`)
+- Loading the user on the client side and using fast/cached SSR pages (`/pages/index.js`)
+- API Routes which can load the current user (`/pages/api/me.js`)
+- Using hooks to make the user available throughout the application (`/lib/user.js`)
diff --git a/examples/auth0/components/header.js b/examples/auth0/components/header.js
new file mode 100644
index 00000000000000..18637cdc16e88f
--- /dev/null
+++ b/examples/auth0/components/header.js
@@ -0,0 +1,81 @@
+import Link from 'next/link'
+
+function Header({ user, loading }) {
+ return (
+
+
+
+
+
+ )
+}
+
+export default Header
diff --git a/examples/auth0/components/layout.js b/examples/auth0/components/layout.js
new file mode 100644
index 00000000000000..954ab790246627
--- /dev/null
+++ b/examples/auth0/components/layout.js
@@ -0,0 +1,35 @@
+import Head from 'next/head'
+import Header from './header'
+
+function Layout({ user, loading = false, children }) {
+ return (
+ <>
+
+ Next.js with Auth0
+
+
+
+
+
+
+ This is the about page, navigating between this page and Home is
+ always pretty fast. However, when you navigate to the Profile{' '}
+ page it takes more time because it uses SSR to fetch the user first;
+
+
+ )
+}
+
+export default About
diff --git a/examples/auth0/pages/advanced/ssr-profile.js b/examples/auth0/pages/advanced/ssr-profile.js
new file mode 100644
index 00000000000000..868af335020129
--- /dev/null
+++ b/examples/auth0/pages/advanced/ssr-profile.js
@@ -0,0 +1,60 @@
+import React from 'react'
+
+// This import is only needed when checking authentication status directly from getInitialProps
+import auth0 from '../../lib/auth0'
+import { fetchUser } from '../../lib/user'
+import Layout from '../../components/layout'
+
+function Profile({ user }) {
+ return (
+
+
Profile
+
+
+
Profile (server rendered)
+
+
nickname: {user.nickname}
+
name: {user.name}
+
+
+ )
+}
+
+Profile.getInitialProps = async ({ req, res }) => {
+ // On the server-side you can check authentication status directly
+ // However in general you might want to call API Routes to fetch data
+ // An example of directly checking authentication:
+ if (typeof window === 'undefined') {
+ const { user } = await auth0.getSession(req)
+ if (!user) {
+ res.writeHead(302, {
+ Location: '/api/login',
+ })
+ res.end()
+ return
+ }
+ return { user }
+ }
+
+ // To do fetches to API routes you can pass the cookie coming from the incoming request on to the fetch
+ // so that a request to the API is done on behalf of the user
+ // keep in mind that server-side fetches need a full URL, meaning that the full url has to be provided to the application
+ const cookie = req && req.headers.cookie
+ const user = await fetchUser(cookie)
+
+ // A redirect is needed to authenticate to Auth0
+ if (!user) {
+ if (typeof window === 'undefined') {
+ res.writeHead(302, {
+ Location: '/api/login',
+ })
+ return res.end()
+ }
+
+ window.location.href = '/api/login'
+ }
+
+ return { user }
+}
+
+export default Profile
diff --git a/examples/auth0/pages/api/callback.js b/examples/auth0/pages/api/callback.js
new file mode 100644
index 00000000000000..e06f9657d0d562
--- /dev/null
+++ b/examples/auth0/pages/api/callback.js
@@ -0,0 +1,10 @@
+import auth0 from '../../lib/auth0'
+
+export default async function callback(req, res) {
+ try {
+ await auth0.handleCallback(req, res, { redirectTo: '/' })
+ } catch (error) {
+ console.error(error)
+ res.status(error.status || 500).end(error.message)
+ }
+}
diff --git a/examples/auth0/pages/api/login.js b/examples/auth0/pages/api/login.js
new file mode 100644
index 00000000000000..c3f2b6d5be6062
--- /dev/null
+++ b/examples/auth0/pages/api/login.js
@@ -0,0 +1,10 @@
+import auth0 from '../../lib/auth0'
+
+export default async function login(req, res) {
+ try {
+ await auth0.handleLogin(req, res)
+ } catch (error) {
+ console.error(error)
+ res.status(error.status || 500).end(error.message)
+ }
+}
diff --git a/examples/auth0/pages/api/logout.js b/examples/auth0/pages/api/logout.js
new file mode 100644
index 00000000000000..25c3e9cef872d0
--- /dev/null
+++ b/examples/auth0/pages/api/logout.js
@@ -0,0 +1,10 @@
+import auth0 from '../../lib/auth0'
+
+export default async function logout(req, res) {
+ try {
+ await auth0.handleLogout(req, res)
+ } catch (error) {
+ console.error(error)
+ res.status(error.status || 500).end(error.message)
+ }
+}
diff --git a/examples/auth0/pages/api/me.js b/examples/auth0/pages/api/me.js
new file mode 100644
index 00000000000000..bbeaa3f5a21437
--- /dev/null
+++ b/examples/auth0/pages/api/me.js
@@ -0,0 +1,10 @@
+import auth0 from '../../lib/auth0'
+
+export default async function me(req, res) {
+ try {
+ await auth0.handleProfile(req, res)
+ } catch (error) {
+ console.error(error)
+ res.status(error.status || 500).end(error.message)
+ }
+}
diff --git a/examples/auth0/pages/index.js b/examples/auth0/pages/index.js
new file mode 100644
index 00000000000000..e16a531abdac85
--- /dev/null
+++ b/examples/auth0/pages/index.js
@@ -0,0 +1,39 @@
+import React from 'react'
+
+import Layout from '../components/layout'
+import { useFetchUser } from '../lib/user'
+
+function Home() {
+ const { user, loading } = useFetchUser()
+
+ return (
+
+
Next.js and Auth0 Example
+
+ {loading &&
Loading login info...
}
+
+ {!loading && !user && (
+ <>
+
+ To test the login click in Login
+
+
+ Once you have logged in you should be able to click in{' '}
+ Profile and Logout
+
+ >
+ )}
+
+ {user && (
+ <>
+
Rendered user info on the client
+
+
nickname: {user.nickname}
+
name: {user.name}
+ >
+ )}
+
+ )
+}
+
+export default Home
diff --git a/examples/auth0/pages/profile.js b/examples/auth0/pages/profile.js
new file mode 100644
index 00000000000000..7f2921d29d5d4a
--- /dev/null
+++ b/examples/auth0/pages/profile.js
@@ -0,0 +1,33 @@
+import React from 'react'
+
+// This import is only needed when checking authentication status directly from getInitialProps
+// import auth0 from '../lib/auth0'
+import { useFetchUser } from '../lib/user'
+import Layout from '../components/layout'
+
+function ProfileCard({ user }) {
+ return (
+ <>
+
Profile
+
+
+
Profile (server rendered)
+
+
nickname: {user.nickname}
+
name: {user.name}
+
+ >
+ )
+}
+
+function Profile() {
+ const { user, loading } = useFetchUser({ required: true })
+
+ return (
+
+ {loading ? <>Loading...> : }
+
+ )
+}
+
+export default Profile
diff --git a/examples/basic-css/README.md b/examples/basic-css/README.md
index a6d22540a2d545..aee21396b02555 100644
--- a/examples/basic-css/README.md
+++ b/examples/basic-css/README.md
@@ -1,15 +1,23 @@
-[](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/basic-css)
-
# Basic CSS example
+Next.js ships with [styled-jsx](https://github.com/zeit/styled-jsx) allowing you to write scope styled components with full css support. This is important for the modularity and code size of your bundles and also for the learning curve of the framework. If you know css you can write styled-jsx right away.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/basic-css)
+
## How to use
+[Try it on CodeSandbox](https://codesandbox.io/s/github/zeit/next.js/tree/canary/examples/basic-css)
+
### Using `create-next-app`
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
-npx create-next-app --example basic-css basic-css-app
+npm init next-app --example basic-css basic-css-app
# or
yarn create next-app --example basic-css basic-css-app
```
@@ -33,14 +41,4 @@ yarn
yarn dev
```
-Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-
-Next.js ships with [styled-jsx](https://github.com/zeit/styled-jsx) allowing you
-to write scope styled components with full css support. This is important for
-the modularity and code size of your bundles and also for the learning curve of the framework. If you know css you can write styled-jsx right away.
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/basic-css/pages/index.js b/examples/basic-css/pages/index.js
index 68debf0ddbfd49..f7764277e13fbf 100644
--- a/examples/basic-css/pages/index.js
+++ b/examples/basic-css/pages/index.js
@@ -1,5 +1,5 @@
export default () => (
-
+
Hello World
-
-)
+ {isMounted ? (
+
+
+ This section is only client-side rendered.
+
+
+ ) : (
+
+ )}
+
+
+
+ )
+}
diff --git a/examples/root-static-files/README.md b/examples/root-static-files/README.md
deleted file mode 100644
index c5106fe90578cc..00000000000000
--- a/examples/root-static-files/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-[](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/root-static-files)
-
-# Root static files example
-
-## How to use
-
-### Using `create-next-app`
-
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
-
-```bash
-npx create-next-app --example root-static-files root-static-files-app
-# or
-yarn create next-app --example root-static-files root-static-files-app
-```
-
-### Download manually
-
-Download the example:
-
-```bash
-curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/root-static-files
-cd root-static-files
-```
-
-Install it and run:
-
-```bash
-npm install
-npm run dev
-# or
-yarn
-yarn dev
-```
-
-### Serverless
-
-With now version 2, using a custom server to route files from the static folder is no longer necessary.
-
-Simply adjust your `now.json` (similar to in this example) by using the [routes configuration](https://zeit.co/docs/v2/deployments/configuration/#routes).
-
-Afterwards, deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-
-This example demonstrates how to serve files such as /robots.txt and /sitemap.xml from the root in both a serverless and non-serverless environment.
diff --git a/examples/root-static-files/next.config.js b/examples/root-static-files/next.config.js
deleted file mode 100644
index 0fbd0e535c8f4a..00000000000000
--- a/examples/root-static-files/next.config.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
- target: 'serverless'
-}
diff --git a/examples/root-static-files/now.json b/examples/root-static-files/now.json
deleted file mode 100644
index a42ab23bd0cb52..00000000000000
--- a/examples/root-static-files/now.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "version": 2,
- "alias": "https://serverless-static-files.now.sh",
- "builds": [{ "src": "next.config.js", "use": "@now/next" }],
- "routes": [
- { "src": "/_next/static/(?:[^/]+/pages|chunks|runtime)/.+", "headers": { "cache-control": "immutable" } },
- {
- "src": "^/(favicon.ico|manifest.json|humans.txt|sitemap.xml|sitemap.xsl)$",
- "dest": "/static/$1",
- "headers": { "cache-control": "max-age=300 must-revalidate" }
- }
- ]
-}
\ No newline at end of file
diff --git a/examples/root-static-files/package.json b/examples/root-static-files/package.json
deleted file mode 100644
index 6a2632d3a1444d..00000000000000
--- a/examples/root-static-files/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "name": "root-static-files",
- "version": "1.0.0",
- "scripts": {
- "dev": "node server.js",
- "build": "next build",
- "start": "NODE_ENV=production node server.js"
- },
- "dependencies": {
- "next": "latest",
- "react": "^16.7.0",
- "react-dom": "^16.7.0"
- }
-}
diff --git a/examples/root-static-files/pages/index.js b/examples/root-static-files/pages/index.js
deleted file mode 100644
index 654b779c8ca197..00000000000000
--- a/examples/root-static-files/pages/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export default () => (
-
-)
diff --git a/examples/ssr-caching/README.md b/examples/ssr-caching/README.md
index bf91ea3519a4b3..f5252c5954825e 100644
--- a/examples/ssr-caching/README.md
+++ b/examples/ssr-caching/README.md
@@ -1,15 +1,20 @@
-[](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/ssr-caching)
-
# Example app where it caches SSR'ed pages in the memory
+React Server Side rendering is very costly and takes a lot of server's CPU power for that. One of the best solutions for this problem is cache already rendered pages.
+That's what this example demonstrate.
+
+This app uses Next's [custom server and routing](https://github.com/zeit/next.js#custom-server-and-routing) mode. It also uses [express](https://expressjs.com/) to handle routing and page serving.
+
+Alternatively, see [the example using React ESI](../with-react-esi/).
+
## How to use
### Using `create-next-app`
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
-npx create-next-app --example ssr-caching ssr-caching-app
+npm init next-app --example ssr-caching ssr-caching-app
# or
yarn create next-app --example ssr-caching ssr-caching-app
```
@@ -33,17 +38,4 @@ yarn
yarn dev
```
-Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-
-React Server Side rendering is very costly and takes a lot of server's CPU power for that. One of the best solutions for this problem is cache already rendered pages.
-That's what this example demonstrate.
-
-This app uses Next's [custom server and routing](https://github.com/zeit/next.js#custom-server-and-routing) mode. It also uses [express](https://expressjs.com/) to handle routing and page serving.
-
-Alternatively, see [the example using React ESI](../with-react-esi/).
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/ssr-caching/package.json b/examples/ssr-caching/package.json
index 730ea9b865c7b0..92f27fc69aa5a7 100644
--- a/examples/ssr-caching/package.json
+++ b/examples/ssr-caching/package.json
@@ -14,4 +14,4 @@
"react-dom": "^16.7.0"
},
"license": "ISC"
-}
\ No newline at end of file
+}
diff --git a/examples/ssr-caching/pages/blog.js b/examples/ssr-caching/pages/blog.js
deleted file mode 100644
index 2a23498b6a3c4c..00000000000000
--- a/examples/ssr-caching/pages/blog.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import React from 'react'
-
-export default class extends React.Component {
- static getInitialProps ({ query: { id } }) {
- return { id }
- }
-
- render () {
- return (
-
-
My {this.props.id} blog post
-
- Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
- eiusmod tempor incididunt ut labore et dolore magna aliqua.
-
diff --git a/examples/ssr-caching/server.js b/examples/ssr-caching/server.js
index aab83d3ebfc671..0fc217c8f4b95b 100644
--- a/examples/ssr-caching/server.js
+++ b/examples/ssr-caching/server.js
@@ -10,10 +10,19 @@ const handle = app.getRequestHandler()
const ssrCache = cacheableResponse({
ttl: 1000 * 60 * 60, // 1hour
- get: async ({ req, res, pagePath, queryParams }) => ({
- data: await app.renderToHTML(req, res, pagePath, queryParams)
- }),
- send: ({ data, res }) => res.send(data)
+ get: async ({ req, res, pagePath, queryParams }) => {
+ const data = await app.renderToHTML(req, res, pagePath, queryParams)
+
+ // Add here custom logic for when you do not want to cache the page, for
+ // example when the page returns a 404 status code:
+ if (res.statusCode === 404) {
+ res.end(data)
+ return
+ }
+
+ return { data }
+ },
+ send: ({ data, res }) => res.send(data),
})
app.prepare().then(() => {
diff --git a/examples/svg-components/README.md b/examples/svg-components/README.md
index 5f78ec5c423f00..a940fd4dc88f55 100644
--- a/examples/svg-components/README.md
+++ b/examples/svg-components/README.md
@@ -1,15 +1,21 @@
-[](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/svg-components)
-
# SVG components example
+This example uses a custom `.babelrc` to add support for importing `.svg` files and rendering them as React components. [babel-plugin-inline-react-svg](https://www.npmjs.com/package/babel-plugin-inline-react-svg) is used to handle transpiling the SVGs.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/svg-components)
+
## How to use
### Using `create-next-app`
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
-npx create-next-app --example svg-components svg-components-app
+npm init next-app --example svg-components svg-components-app
# or
yarn create next-app --example svg-components svg-components-app
```
@@ -33,12 +39,4 @@ yarn
yarn dev
```
-Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-
-This example uses a custom `.babelrc` to add support for importing `.svg` files and rendering them as React components. [babel-plugin-inline-react-svg](https://www.npmjs.com/package/babel-plugin-inline-react-svg) is used to handle transpiling the SVGs.
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/svg-components/pages/index.js b/examples/svg-components/pages/index.js
index 88e57a42aaa40d..9777b8bac758db 100644
--- a/examples/svg-components/pages/index.js
+++ b/examples/svg-components/pages/index.js
@@ -2,7 +2,7 @@ import React from 'react'
import Cat from '../svgs/cat.svg'
export default () => (
-
diff --git a/examples/using-with-router/README.md b/examples/using-with-router/README.md
deleted file mode 100644
index b8003db455ade8..00000000000000
--- a/examples/using-with-router/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-[](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/using-with-router)
-# Example app utilizing `withRouter` utility for routing
-
-## How to use
-
-### Using `create-next-app`
-
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
-
-```bash
-npx create-next-app --example using-with-router using-with-router-app
-# or
-yarn create next-app --example using-with-router using-with-router-app
-```
-
-### Download manually
-
-Download the example:
-
-```bash
-curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/using-with-router
-cd using-with-router
-```
-
-Install it and run:
-
-```bash
-npm install
-npm run dev
-# or
-yarn
-yarn dev
-```
-
-Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-
-Sometimes, we want to use the `router` inside component of our app without using the singleton `next/router` API.
-
-You can do that by creating a React Higher Order Component with the help of the `withRouter` utility.
diff --git a/examples/using-with-router/components/ActiveLink.js b/examples/using-with-router/components/ActiveLink.js
deleted file mode 100644
index 3193e719ba9470..00000000000000
--- a/examples/using-with-router/components/ActiveLink.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { withRouter } from 'next/router'
-
-// typically you want to use `next/link` for this usecase
-// but this example shows how you can also access the router
-// using the withRouter utility.
-
-const ActiveLink = ({ children, router, href }) => {
- const style = {
- marginRight: 10,
- color: router.pathname === href ? 'red' : 'black'
- }
-
- const handleClick = e => {
- e.preventDefault()
- router.push(href)
- }
-
- return (
-
- {children}
-
- )
-}
-
-export default withRouter(ActiveLink)
diff --git a/examples/using-with-router/components/Header.js b/examples/using-with-router/components/Header.js
deleted file mode 100644
index 4e886aacd69dc2..00000000000000
--- a/examples/using-with-router/components/Header.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import ActiveLink from './ActiveLink'
-
-export default () => (
-
-)
diff --git a/examples/with-absolute-imports/README.md b/examples/with-absolute-imports/README.md
index cd70d295882933..7185e85ec77ab6 100644
--- a/examples/with-absolute-imports/README.md
+++ b/examples/with-absolute-imports/README.md
@@ -1,13 +1,21 @@
# Example app with absolute imports
+This example shows how to configure Babel to have absolute imports instead of relative imports without modifying the Webpack configuration.
+
+## Deploy your own
+
+Deploy the example using [ZEIT Now](https://zeit.co/now):
+
+[](https://zeit.co/import/project?template=https://github.com/zeit/next.js/tree/canary/examples/with-absolute-imports)
+
## How to use
### Using `create-next-app`
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
-npx create-next-app --example with-absolute-imports with-absolute-imports-app
+npm init next-app --example with-absolute-imports with-absolute-imports-app
# or
yarn create next-app --example with-absolute-imports with-absolute-imports-app
```
@@ -31,12 +39,4 @@ yarn
yarn dev
```
-Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-
-This example shows how to configure Babel to have absolute imports instead of relative imports without modifying the Webpack configuration.
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/with-absolute-imports/next.config.js b/examples/with-absolute-imports/next.config.js
index e8e3db29a07fc1..3c5580f17f8497 100644
--- a/examples/with-absolute-imports/next.config.js
+++ b/examples/with-absolute-imports/next.config.js
@@ -1,8 +1,8 @@
const path = require('path')
module.exports = {
- webpack (config, options) {
+ webpack(config, options) {
config.resolve.alias['components'] = path.join(__dirname, 'components')
return config
- }
+ },
}
diff --git a/examples/with-algolia-react-instantsearch/README.md b/examples/with-algolia-react-instantsearch/README.md
index 5586fbc4343302..1f2c23f3993ea3 100644
--- a/examples/with-algolia-react-instantsearch/README.md
+++ b/examples/with-algolia-react-instantsearch/README.md
@@ -1,15 +1,15 @@
-[](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-algolia-react-instantsearch)
-
# With Algolia React InstantSearch example
+The goal of this example is to illustrate how you can use [Algolia React InstantSearch](https://community.algolia.com/react-instantsearch/) to perform your search with a Server-rendered application developed with Next.js. It also illustrates how you can keep in sync the Url with the search.
+
## How to use
### Using `create-next-app`
-Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
+Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
-npx create-next-app --example with-algolia-react-instantsearch with-algolia-react-instantsearch-app
+npm init next-app --example with-algolia-react-instantsearch with-algolia-react-instantsearch-app
# or
yarn create next-app --example with-algolia-react-instantsearch with-algolia-react-instantsearch-app
```
@@ -24,6 +24,7 @@ cd with-algolia-react-instantsearch
```
Set up Algolia:
+
- create an [algolia](https://www.algolia.com/) account or use this already [configured index](https://community.algolia.com/react-instantsearch/Getting_started.html#before-we-start)
- update the appId, apikey and indexName you want to search on in components/app.js
@@ -37,13 +38,4 @@ yarn
yarn dev
```
-Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
-
-```bash
-now
-```
-
-## The idea behind the example
-The goal of this example is to illustrate how you can use [Algolia React InstantSearch](https://community.algolia.com/react-instantsearch/) to perform
-your search with a Server-rendered application developed with Next.js. It also illustrates how you
-can keep in sync the Url with the search.
+Deploy it to the cloud with [ZEIT Now](https://zeit.co/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
diff --git a/examples/with-algolia-react-instantsearch/components/app.js b/examples/with-algolia-react-instantsearch/components/app.js
index 6383711a18ebd7..5c4f65713a2477 100644
--- a/examples/with-algolia-react-instantsearch/components/app.js
+++ b/examples/with-algolia-react-instantsearch/components/app.js
@@ -6,50 +6,50 @@ import {
Hits,
Configure,
Highlight,
- Pagination
+ Pagination,
} from 'react-instantsearch/dom'
import { InstantSearch } from './instantsearch'
const HitComponent = ({ hit }) => (
-