This commit is contained in:
Kismet Hasanaj
2026-05-02 20:07:02 +02:00
parent ce8672e283
commit 34dc9aec52
9428 changed files with 1733330 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
---
title: How to set up analytics
nav_title: Analytics
description: Measure and track page performance using Next.js
source: app/guides/analytics
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to implement authentication in Next.js
nav_title: Authentication
description: Learn how to implement authentication in Next.js, covering best practices, securing routes, authorization techniques, and session management.
source: app/guides/authentication
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+66
View File
@@ -0,0 +1,66 @@
---
title: How to configure Babel in Next.js
nav_title: Babel
description: Extend the babel preset added by Next.js with your own configs.
---
<details>
<summary>Examples</summary>
- [Customizing babel configuration](https://github.com/vercel/next.js/tree/canary/examples/with-custom-babel-config)
</details>
Next.js includes the `next/babel` preset to your app, which 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.
## Adding Presets and Plugins
To start, you only need to define a `.babelrc` file (or `babel.config.js`) in the root directory of your project. If such a file is found, it will be considered as the _source of truth_, and therefore it needs to define what Next.js needs as well, which is the `next/babel` preset.
Here's an example `.babelrc` file:
```json filename=".babelrc"
{
"presets": ["next/babel"],
"plugins": []
}
```
You can [take a look at this file](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/babel/preset.ts) to learn about the presets included by `next/babel`.
To add presets/plugins **without configuring them**, you can do it this way:
```json filename=".babelrc"
{
"presets": ["next/babel"],
"plugins": ["@babel/plugin-proposal-do-expressions"]
}
```
## Customizing Presets and Plugins
To add presets/plugins **with custom configuration**, do it on the `next/babel` preset like so:
```json filename=".babelrc"
{
"presets": [
[
"next/babel",
{
"preset-env": {},
"transform-runtime": {},
"styled-jsx": {},
"class-properties": {}
}
]
],
"plugins": []
}
```
To learn more about the available options for each config, visit babel's [documentation](https://babeljs.io/docs/) site.
> **Good to know**:
>
> - Next.js uses the [**current** Node.js version](https://github.com/nodejs/release#release-schedule) for server-side compilations.
> - The `modules` option on `"preset-env"` should be kept to `false`, otherwise webpack code splitting is turned off.
+8
View File
@@ -0,0 +1,8 @@
---
title: How to configure Continuous Integration (CI) build caching
nav_title: CI Build Caching
description: Learn how to configure CI to cache Next.js builds
source: app/guides/ci-build-caching
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
@@ -0,0 +1,8 @@
---
title: How to set a Content Security Policy (CSP) for your Next.js application
nav_title: Content Security Policy
description: Learn how to set a Content Security Policy (CSP) for your Next.js application.
source: app/guides/content-security-policy
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to use CSS-in-JS libraries
nav_title: CSS-in-JS
description: Use CSS-in-JS libraries with Next.js
source: app/guides/css-in-js
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to set up a custom server in Next.js
nav_title: Custom Server
description: Start a Next.js app programmatically using a custom server.
source: app/guides/custom-server
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to use debugging tools with Next.js
nav_title: Debugging
description: Learn how to debug your Next.js application with VS Code or Chrome DevTools.
source: app/guides/debugging
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+182
View File
@@ -0,0 +1,182 @@
---
title: How to preview content with Draft Mode in Next.js
nav_title: Draft Mode
description: Next.js has draft mode to toggle between static and dynamic pages. You can learn how it works with Pages Router.
---
In the [Pages documentation](/docs/pages/building-your-application/routing/pages-and-layouts) and the [Data Fetching documentation](/docs/pages/building-your-application/data-fetching), we talked about how to prerender 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, its not ideal when youre writing a draft on your headless CMS and want to view the draft immediately on your page. Youd want Next.js to render these pages at **request time** instead of build time and fetch the draft content instead of the published content. Youd want Next.js to bypass Static Generation only for this specific case.
Next.js has a feature called **Draft Mode** which solves this problem. Here are instructions on how to use it.
## Step 1: Create and access the API route
> Take a look at the [API Routes documentation](/docs/pages/building-your-application/routing/api-routes) first if youre not familiar with Next.js API Routes.
First, create the **API route**. It can have any name - e.g. `pages/api/draft.ts`
In this API route, you need to call `setDraftMode` on the response object.
```js
export default function handler(req, res) {
// ...
res.setDraftMode({ enable: true })
// ...
}
```
This will set a **cookie** to enable draft mode. Subsequent requests containing this cookie will trigger **Draft Mode** changing the behavior for statically generated pages (more on this later).
You can test this manually by creating an API route like below and accessing it from your browser manually:
```ts filename="pages/api/draft.ts"
// simple example for testing it manually from your browser.
export default function handler(req, res) {
res.setDraftMode({ enable: true })
res.end('Draft mode is enabled')
}
```
If you open your browsers developer tools and visit `/api/draft`, youll notice a `Set-Cookie` response header with a cookie named `__prerender_bypass`.
### Securely accessing it from your Headless CMS
In practice, youd want to call this API route _securely_ from your headless CMS. The specific steps will vary depending on which headless CMS youre using, but here are some common steps you could take.
These steps assume that the headless CMS youre using supports setting **custom draft URLs**. If it doesnt, you can still use this method to secure your draft URLs, but youll need to construct and access the draft 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 dont have access to your CMS from accessing draft URLs.
**Second**, if your headless CMS supports setting custom draft URLs, specify the following as the draft URL. This assumes that your draft API route is located at `pages/api/draft.ts`.
```bash filename="Terminal"
https://<your-site>/api/draft?secret=<token>&slug=<path>
```
- `<your-site>` should be your deployment domain.
- `<token>` should be replaced with the secret token you generated.
- `<path>` should be the path for the page that you want to view. If you want to view `/posts/foo`, then you should use `&slug=/posts/foo`.
Your headless CMS might allow you to include a variable in the draft URL so that `<path>` can be set dynamically based on the CMSs data like so: `&slug=/posts/{entry.fields.slug}`
**Finally**, in the draft API route:
- Check that the secret matches and that the `slug` parameter exists (if not, the request should fail).
-
- Call `res.setDraftMode`.
- Then redirect the browser to the path specified by `slug`. (The following example uses a [307 redirect](https://developer.mozilla.org/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 draft mode from being enabled
if (!post) {
return res.status(401).json({ message: 'Invalid slug' })
}
// Enable Draft Mode by setting the cookie
res.setDraftMode({ enable: true })
// 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.redirect(post.slug)
}
```
If it succeeds, then the browser will be redirected to the path you want to view with the draft mode cookie.
## Step 2: Update `getStaticProps`
The next step is to update `getStaticProps` to support draft mode.
If you request a page which has `getStaticProps` with the cookie set (via `res.setDraftMode`), then `getStaticProps` will be called at **request time** (instead of at build time).
Furthermore, it will be called with a `context` object where `context.draftMode` will be `true`.
```js
export async function getStaticProps(context) {
if (context.draftMode) {
// dynamic data
}
}
```
We used `res.setDraftMode` in the draft API route, so `context.draftMode` will be `true`.
If youre also using `getStaticPaths`, then `context.params` will also be available.
### Fetch draft data
You can update `getStaticProps` to fetch different data based on `context.draftMode`.
For example, your headless CMS might have a different API endpoint for draft posts. If so, you can modify the API endpoint URL like below:
```js
export async function getStaticProps(context) {
const url = context.draftMode
? 'https://draft.example.com'
: 'https://production.example.com'
const res = await fetch(url)
// ...
}
```
Thats it! If you access the draft API route (with `secret` and `slug`) from your headless CMS or manually, you should now be able to see the draft content. And if you update your draft without publishing, you should be able to view the draft.
Set this as the draft URL on your headless CMS or access manually, and you should be able to see the draft.
```bash filename="Terminal"
https://<your-site>/api/draft?secret=<token>&slug=<path>
```
## More Details
### Clear the Draft Mode cookie
By default, the Draft Mode session ends when the browser is closed.
To clear the Draft Mode cookie manually, create an API route that calls `setDraftMode({ enable: false })`:
```ts filename="pages/api/disable-draft.ts"
export default function handler(req, res) {
res.setDraftMode({ enable: false })
}
```
Then, send a request to `/api/disable-draft` to invoke the API Route. If calling this route using [`next/link`](/docs/pages/api-reference/components/link), you must pass `prefetch={false}` to prevent accidentally deleting the cookie on prefetch.
### Works with `getServerSideProps`
Draft Mode works with `getServerSideProps`, and is available as a `draftMode` key in the [`context`](/docs/pages/api-reference/functions/get-server-side-props#context-parameter) object.
> **Good to know**: You shouldn't set the `Cache-Control` header when using Draft Mode because it cannot be bypassed. Instead, we recommend using [ISR](/docs/pages/guides/incremental-static-regeneration).
### Works with API Routes
API Routes will have access to `draftMode` on the request object. For example:
```js
export default function myApiRoute(req, res) {
if (req.draftMode) {
// get draft data
}
}
```
### Unique per `next build`
A new bypass cookie value will be generated each time you run `next build`.
This ensures that the bypass cookie cant be guessed.
> **Good to know**: To test Draft Mode locally over HTTP, your browser will need to allow third-party cookies and local storage access.
@@ -0,0 +1,8 @@
---
title: How to use environment variables in Next.js
nav_title: Environment Variables
description: Learn to add and access environment variables in your Next.js application.
source: app/guides/environment-variables
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+336
View File
@@ -0,0 +1,336 @@
---
title: How to create forms with API Routes
nav_title: Forms
description: Learn how to handle form submissions and data mutations with Next.js.
---
Forms enable you to create and update data in web applications. Next.js provides a powerful way to handle data mutations using **API Routes**. This guide will walk you through how to handle form submission on the server.
## Server Forms
To handle form submissions on the server, create an API endpoint that securely mutates data.
```ts filename="pages/api/submit.ts" switcher
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const data = req.body
const id = await createItem(data)
res.status(200).json({ id })
}
```
```js filename="pages/api/submit.js" switcher
export default function handler(req, res) {
const data = req.body
// call your database, etc.
// const id = await createItem(data)
// ...
res.status(200).json({ data })
}
```
Then, call the API Route from the client with an event handler:
```tsx filename="pages/index.tsx" switcher
import { FormEvent } from 'react'
export default function Page() {
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Handle response if necessary
const data = await response.json()
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
)
}
```
```jsx filename="pages/index.jsx" switcher
export default function Page() {
async function onSubmit(event) {
event.preventDefault()
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Handle response if necessary
const data = await response.json()
// ...
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
)
}
```
> **Good to know:**
>
> - API Routes [do not specify CORS headers](https://developer.mozilla.org/docs/Web/HTTP/CORS), meaning they are same-origin only by default.
> - Since API Routes run on the server, we're able to use sensitive values (like API keys) through [Environment Variables](/docs/pages/guides/environment-variables) without exposing them to the client. This is critical for the security of your application.
## Form validation
We recommend using HTML validation like `required` and `type="email"` for basic client-side form validation.
For more advanced server-side validation, you can use a schema validation library like [zod](https://zod.dev/) to validate the form fields before mutating the data:
```ts filename="pages/api/submit.ts" switcher
import type { NextApiRequest, NextApiResponse } from 'next'
import { z } from 'zod'
const schema = z.object({
// ...
})
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const parsed = schema.parse(req.body)
// ...
}
```
```js filename="pages/api/submit.js" switcher
import { z } from 'zod'
const schema = z.object({
// ...
})
export default async function handler(req, res) {
const parsed = schema.parse(req.body)
// ...
}
```
### Error handling
You can use React state to show an error message when a form submission fails:
```tsx filename="pages/index.tsx" switcher
import React, { useState, FormEvent } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState<boolean>(false)
const [error, setError] = useState<string | null>(null)
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()
setIsLoading(true)
setError(null) // Clear previous errors when a new request starts
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
if (!response.ok) {
throw new Error('Failed to submit the data. Please try again.')
}
// Handle response if necessary
const data = await response.json()
// ...
} catch (error) {
// Capture the error message to display to the user
setError(error.message)
console.error(error)
} finally {
setIsLoading(false)
}
}
return (
<div>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={onSubmit}>
<input type="text" name="name" required />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
</div>
)
}
```
```jsx filename="pages/index.jsx" switcher
import React, { useState } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState(null)
async function onSubmit(event) {
event.preventDefault()
setIsLoading(true)
setError(null) // Clear previous errors when a new request starts
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
if (!response.ok) {
throw new Error('Failed to submit the data. Please try again.')
}
// Handle response if necessary
const data = await response.json()
// ...
} catch (error) {
// Capture the error message to display to the user
setError(error.message)
console.error(error)
} finally {
setIsLoading(false)
}
}
return (
<div>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={onSubmit}>
<input type="text" name="name" required />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
</div>
)
}
```
## Displaying loading state
You can use React state to show a loading state when a form is submitting on the server:
```tsx filename="pages/index.tsx" switcher
import React, { useState, FormEvent } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState<boolean>(false)
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()
setIsLoading(true) // Set loading to true when the request starts
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Handle response if necessary
const data = await response.json()
// ...
} catch (error) {
// Handle error if necessary
console.error(error)
} finally {
setIsLoading(false) // Set loading to false when the request completes
}
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
)
}
```
```jsx filename="pages/index.jsx" switcher
import React, { useState } from 'react'
export default function Page() {
const [isLoading, setIsLoading] = useState(false)
async function onSubmit(event) {
event.preventDefault()
setIsLoading(true) // Set loading to true when the request starts
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
// Handle response if necessary
const data = await response.json()
// ...
} catch (error) {
// Handle error if necessary
console.error(error)
} finally {
setIsLoading(false) // Set loading to false when the request completes
}
}
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
)
}
```
### Redirecting
If you would like to redirect the user to a different route after a mutation, you can [`redirect`](/docs/pages/building-your-application/routing/api-routes#response-helpers) to any absolute or relative URL:
```ts filename="pages/api/submit.ts" switcher
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const id = await addPost()
res.redirect(307, `/post/${id}`)
}
```
```js filename="pages/api/submit.js" switcher
export default async function handler(req, res) {
const id = await addPost()
res.redirect(307, `/post/${id}`)
}
```
@@ -0,0 +1,8 @@
---
title: How to implement Incremental Static Regeneration (ISR)
nav_title: ISR
description: Learn how to create or update static pages at runtime with Incremental Static Regeneration.
source: app/guides/incremental-static-regeneration
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+4
View File
@@ -0,0 +1,4 @@
---
title: Guides
description: Learn how to implement common UI patterns and use cases using Next.js
---
+8
View File
@@ -0,0 +1,8 @@
---
title: How to set up instrumentation
nav_title: Instrumentation
description: Learn how to use instrumentation to run code at server startup in your Next.js app
source: app/guides/instrumentation
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+355
View File
@@ -0,0 +1,355 @@
---
title: How to implement internationalization in Next.js
nav_title: Internationalization
description: Next.js has built-in support for internationalized routing and language detection. Learn more here.
---
<details>
<summary>Examples</summary>
- [i18n routing](https://github.com/vercel/next.js/tree/canary/examples/i18n-routing-pages)
</details>
Next.js has built-in support for internationalized ([i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization#Naming)) routing since `v10.0.0`. You can provide a list of locales, the default locale, and domain-specific locales and Next.js will automatically handle the routing.
The i18n routing support is currently meant to complement existing i18n library solutions like [`react-intl`](https://formatjs.io/docs/getting-started/installation), [`react-i18next`](https://react.i18next.com/), [`lingui`](https://lingui.dev/), [`rosetta`](https://github.com/lukeed/rosetta), [`next-intl`](https://github.com/amannn/next-intl), [`next-translate`](https://github.com/aralroca/next-translate), [`next-multilingual`](https://github.com/Avansai/next-multilingual), [`tolgee`](https://tolgee.io/integrations/next), [`paraglide-next`](https://inlang.com/m/osslbuzt/paraglide-next-i18n), [`next-intlayer`](https://intlayer.org/doc/environment/nextjs/next-with-page-router), [`gt-react`](https://generaltranslation.com/en/docs/react) and others by streamlining the routes and locale parsing.
## Getting started
To get started, add the `i18n` config to your `next.config.js` file.
Locales are [UTS Locale Identifiers](https://www.unicode.org/reports/tr35/tr35-59/tr35.html#Identifiers), a standardized format for defining locales.
Generally a Locale Identifier is made up of a language, region, and script separated by a dash: `language-region-script`. The region and script are optional. An example:
- `en-US` - English as spoken in the United States
- `nl-NL` - Dutch as spoken in the Netherlands
- `nl` - Dutch, no specific region
If user locale is `nl-BE` and it is not listed in your configuration, they will be redirected to `nl` if available, or to the default locale otherwise.
If you don't plan to support all regions of a country, it is therefore a good practice to include country locales that will act as fallbacks.
```js filename="next.config.js"
module.exports = {
i18n: {
// These are all the locales you want to support in
// your application
locales: ['en-US', 'fr', 'nl-NL'],
// This is the default locale you want to be used when visiting
// a non-locale prefixed path e.g. `/hello`
defaultLocale: 'en-US',
// This is a list of locale domains and the default locale they
// should handle (these are only required when setting up domain routing)
// Note: subdomains must be included in the domain value to be matched e.g. "fr.example.com".
domains: [
{
domain: 'example.com',
defaultLocale: 'en-US',
},
{
domain: 'example.nl',
defaultLocale: 'nl-NL',
},
{
domain: 'example.fr',
defaultLocale: 'fr',
// an optional http field can also be used to test
// locale domains locally with http instead of https
http: true,
},
],
},
}
```
## Locale Strategies
There are two locale handling strategies: Sub-path Routing and Domain Routing.
### Sub-path Routing
Sub-path Routing puts the locale in the url path.
```js filename="next.config.js"
module.exports = {
i18n: {
locales: ['en-US', 'fr', 'nl-NL'],
defaultLocale: 'en-US',
},
}
```
With the above configuration `en-US`, `fr`, and `nl-NL` will be available to be routed to, and `en-US` is the default locale. If you have a `pages/blog.js` the following urls would be available:
- `/blog`
- `/fr/blog`
- `/nl-nl/blog`
The default locale does not have a prefix.
### Domain Routing
By using domain routing you can configure locales to be served from different domains:
```js filename="next.config.js"
module.exports = {
i18n: {
locales: ['en-US', 'fr', 'nl-NL', 'nl-BE'],
defaultLocale: 'en-US',
domains: [
{
// Note: subdomains must be included in the domain value to be matched
// e.g. www.example.com should be used if that is the expected hostname
domain: 'example.com',
defaultLocale: 'en-US',
},
{
domain: 'example.fr',
defaultLocale: 'fr',
},
{
domain: 'example.nl',
defaultLocale: 'nl-NL',
// specify other locales that should be redirected
// to this domain
locales: ['nl-BE'],
},
],
},
}
```
For example if you have `pages/blog.js` the following urls will be available:
- `example.com/blog`
- `www.example.com/blog`
- `example.fr/blog`
- `example.nl/blog`
- `example.nl/nl-BE/blog`
## Automatic Locale Detection
When a user visits the application root (generally `/`), Next.js will try to automatically detect which locale the user prefers based on the [`Accept-Language`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Accept-Language) header and the current domain.
If a locale other than the default locale is detected, the user will be redirected to either:
- **When using Sub-path Routing:** The locale prefixed path
- **When using Domain Routing:** The domain with that locale specified as the default
When using Domain Routing, if a user with the `Accept-Language` header `fr;q=0.9` visits `example.com`, they will be redirected to `example.fr` since that domain handles the `fr` locale by default.
When using Sub-path Routing, the user would be redirected to `/fr`.
### Prefixing the Default Locale
With Next.js 12 and [Proxy](/docs/pages/api-reference/file-conventions/proxy), we can add a prefix to the default locale with a [workaround](https://github.com/vercel/next.js/discussions/18419).
For example, here's a `next.config.js` file with support for a few languages. Note the `"default"` locale has been added intentionally.
```js filename="next.config.js"
module.exports = {
i18n: {
locales: ['default', 'en', 'de', 'fr'],
defaultLocale: 'default',
localeDetection: false,
},
trailingSlash: true,
}
```
Next, we can use [Proxy](/docs/pages/api-reference/file-conventions/proxy) to add custom routing rules:
```ts filename="proxy.ts"
import { NextRequest, NextResponse } from 'next/server'
const PUBLIC_FILE = /\.(.*)$/
export async function proxy(req: NextRequest) {
if (
req.nextUrl.pathname.startsWith('/_next') ||
req.nextUrl.pathname.includes('/api/') ||
PUBLIC_FILE.test(req.nextUrl.pathname)
) {
return
}
if (req.nextUrl.locale === 'default') {
const locale = req.cookies.get('NEXT_LOCALE')?.value || 'en'
return NextResponse.redirect(
new URL(`/${locale}${req.nextUrl.pathname}${req.nextUrl.search}`, req.url)
)
}
}
```
This [Proxy](/docs/pages/api-reference/file-conventions/proxy) skips adding the default prefix to [API Routes](/docs/pages/building-your-application/routing/api-routes) and [public](/docs/pages/api-reference/file-conventions/public-folder) files like fonts or images. If a request is made to the default locale, we redirect to our prefix `/en`.
### Disabling Automatic Locale Detection
The automatic locale detection can be disabled with:
```js filename="next.config.js"
module.exports = {
i18n: {
localeDetection: false,
},
}
```
When `localeDetection` is set to `false` Next.js will no longer automatically redirect based on the user's preferred locale and will only provide locale information detected from either the locale based domain or locale path as described above.
## Accessing the locale information
You can access the locale information via the Next.js router. For example, using the [`useRouter()`](/docs/pages/api-reference/functions/use-router) hook the following properties are available:
- `locale` contains the currently active locale.
- `locales` contains all configured locales.
- `defaultLocale` contains the configured default locale.
When [prerendering](/docs/pages/building-your-application/rendering/static-site-generation) pages with `getStaticProps` or `getServerSideProps`, the locale information is provided in [the context](/docs/pages/building-your-application/data-fetching/get-static-props) provided to the function.
When leveraging `getStaticPaths`, the configured locales are provided in the context parameter of the function under `locales` and the configured defaultLocale under `defaultLocale`.
## Transition between locales
You can use `next/link` or `next/router` to transition between locales.
For `next/link`, a `locale` prop can be provided to transition to a different locale from the currently active one. If no `locale` prop is provided, the currently active `locale` is used during client-transitions. For example:
```jsx
import Link from 'next/link'
export default function IndexPage(props) {
return (
<Link href="/another" locale="fr">
To /fr/another
</Link>
)
}
```
When using the `next/router` methods directly, you can specify the `locale` that should be used via the transition options. For example:
```jsx
import { useRouter } from 'next/router'
export default function IndexPage(props) {
const router = useRouter()
return (
<div
onClick={() => {
router.push('/another', '/another', { locale: 'fr' })
}}
>
to /fr/another
</div>
)
}
```
Note that to handle switching only the `locale` while preserving all routing information such as [dynamic route](/docs/pages/building-your-application/routing/dynamic-routes) query values or hidden href query values, you can provide the `href` parameter as an object:
```jsx
import { useRouter } from 'next/router'
const router = useRouter()
const { pathname, asPath, query } = router
// change just the locale and maintain all other route information including href's query
router.push({ pathname, query }, asPath, { locale: nextLocale })
```
See [here](/docs/pages/api-reference/functions/use-router#with-url-object) for more information on the object structure for `router.push`.
If you have a `href` that already includes the locale you can opt-out of automatically handling the locale prefixing:
```jsx
import Link from 'next/link'
export default function IndexPage(props) {
return (
<Link href="/fr/another" locale={false}>
To /fr/another
</Link>
)
}
```
## Leveraging the `NEXT_LOCALE` cookie
Next.js allows setting a `NEXT_LOCALE=the-locale` cookie, which takes priority over the accept-language header. This cookie can be set using a language switcher and then when a user comes back to the site it will leverage the locale specified in the cookie when redirecting from `/` to the correct locale location.
For example, if a user prefers the locale `fr` in their accept-language header but a `NEXT_LOCALE=en` cookie is set the `en` locale when visiting `/` the user will be redirected to the `en` locale location until the cookie is removed or expired.
## Search Engine Optimization
Since Next.js knows what language the user is visiting it will automatically add the `lang` attribute to the `<html>` tag.
Next.js doesn't know about variants of a page so it's up to you to add the `hreflang` meta tags using [`next/head`](/docs/pages/api-reference/components/head). You can learn more about `hreflang` in the [Google Webmasters documentation](https://support.google.com/webmasters/answer/189077).
## How does this work with Static Generation?
> Note that Internationalized Routing does not integrate with [`output: 'export'`](/docs/pages/guides/static-exports) as it does not leverage the Next.js routing layer. Hybrid Next.js applications that do not use `output: 'export'` are fully supported.
### Dynamic Routes and `getStaticProps` Pages
For pages using `getStaticProps` with [Dynamic Routes](/docs/pages/building-your-application/routing/dynamic-routes), all locale variants of the page desired to be prerendered need to be returned from [`getStaticPaths`](/docs/pages/building-your-application/data-fetching/get-static-paths). Along with the `params` object returned for `paths`, you can also return a `locale` field specifying which locale you want to render. For example:
```jsx filename="pages/blog/[slug].js"
export const getStaticPaths = ({ locales }) => {
return {
paths: [
// if no `locale` is provided only the defaultLocale will be generated
{ params: { slug: 'post-1' }, locale: 'en-US' },
{ params: { slug: 'post-1' }, locale: 'fr' },
],
fallback: true,
}
}
```
For [Automatically Statically Optimized](/docs/pages/building-your-application/rendering/automatic-static-optimization) and non-dynamic `getStaticProps` pages, **a version of the page will be generated for each locale**. This is important to consider because it can increase build times depending on how many locales are configured inside `getStaticProps`.
For example, if you have 50 locales configured with 10 non-dynamic pages using `getStaticProps`, this means `getStaticProps` will be called 500 times. 50 versions of the 10 pages will be generated during each build.
To decrease the build time of dynamic pages with `getStaticProps`, use a [`fallback` mode](/docs/pages/api-reference/functions/get-static-paths#fallback-true). This allows you to return only the most popular paths and locales from `getStaticPaths` for prerendering during the build. Then, Next.js will build the remaining pages at runtime as they are requested.
### Automatically Statically Optimized Pages
For pages that are [automatically statically optimized](/docs/pages/building-your-application/rendering/automatic-static-optimization), a version of the page will be generated for each locale.
### Non-dynamic getStaticProps Pages
For non-dynamic `getStaticProps` pages, a version is generated for each locale like above. `getStaticProps` is called with each `locale` that is being rendered. If you would like to opt-out of a certain locale from being prerendered, you can return `notFound: true` from `getStaticProps` and this variant of the page will not be generated.
```js
export async function getStaticProps({ locale }) {
// Call an external API endpoint to get posts.
// You can use any data fetching library
const res = await fetch(`https://.../posts?locale=${locale}`)
const posts = await res.json()
if (posts.length === 0) {
return {
notFound: true,
}
}
// By returning { props: posts }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts,
},
}
}
```
## Limits for the i18n config
- `locales`: 100 total locales
- `domains`: 100 total locale domain items
> **Good to know**: These limits have been added initially to prevent potential [performance issues at build time](#dynamic-routes-and-getstaticprops-pages). You can workaround these limits with custom routing using [Proxy](/docs/pages/api-reference/file-conventions/proxy) in Next.js 12.
+8
View File
@@ -0,0 +1,8 @@
---
title: How to lazy load Client Components and libraries
nav_title: Lazy Loading
description: Lazy load imported libraries and React Components to improve your application's overall loading performance.
source: app/guides/lazy-loading
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to use markdown and MDX in Next.js
nav_title: MDX
description: Learn how to configure MDX to write JSX in your markdown files.
source: app/guides/mdx
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
@@ -0,0 +1,8 @@
---
title: How to migrate from Pages to the App Router
nav_title: App Router
description: Learn how to upgrade your existing Next.js application from the Pages Router to the App Router.
source: app/guides/migrating/app-router-migration
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
@@ -0,0 +1,8 @@
---
title: How to migrate from Create React App to Next.js
nav_title: Create React App
description: Learn how to migrate your existing React application from Create React App to Next.js.
source: app/guides/migrating/from-create-react-app
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
@@ -0,0 +1,8 @@
---
title: How to migrate from Vite to Next.js
nav_title: Vite
description: Learn how to migrate your existing React application from Vite to Next.js.
source: app/guides/migrating/from-vite
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+4
View File
@@ -0,0 +1,4 @@
---
title: Migrating
description: Learn how to migrate from popular frameworks to Next.js
---
+8
View File
@@ -0,0 +1,8 @@
---
title: How to build micro-frontends using multi-zones and Next.js
nav_title: Multi-Zones
description: Learn how to build micro-frontends using Next.js Multi-Zones to deploy multiple Next.js apps under a single domain.
source: app/guides/multi-zones
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to instrument your Next.js app with OpenTelemetry
nav_title: OpenTelemetry
description: Learn how to instrument your Next.js app with OpenTelemetry.
source: app/guides/open-telemetry
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+12
View File
@@ -0,0 +1,12 @@
---
title: How to optimize package bundling
nav_title: Package Bundling
description: Learn how to optimize your application's server and client bundles.
source: app/guides/package-bundling
related:
description: Learn more about optimizing your application for production.
links:
- pages/guides/production-checklist
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+163
View File
@@ -0,0 +1,163 @@
---
title: How to configure PostCSS in Next.js
nav_title: PostCSS
description: Extend the PostCSS config and plugins added by Next.js with your own.
---
## Default Behavior
Next.js compiles CSS for its [built-in CSS support](/docs/app/getting-started/css) using PostCSS.
Out of the box, with no configuration, Next.js compiles CSS with the following transformations:
- [Autoprefixer](https://github.com/postcss/autoprefixer) automatically adds vendor prefixes to CSS rules (back to IE11).
- [Cross-browser Flexbox bugs](https://github.com/philipwalton/flexbugs) are corrected to behave like [the spec](https://www.w3.org/TR/css-flexbox-1/).
- New CSS features are automatically compiled for Internet Explorer 11 compatibility:
- [`all` Property](https://developer.mozilla.org/docs/Web/CSS/all)
- [Break Properties](https://developer.mozilla.org/docs/Web/CSS/break-after)
- [`font-variant` Property](https://developer.mozilla.org/docs/Web/CSS/font-variant)
- [Gap Properties](https://developer.mozilla.org/docs/Web/CSS/gap)
- [Media Query Ranges](https://developer.mozilla.org/docs/Web/CSS/Media_Queries/Using_media_queries#Syntax_improvements_in_Level_4)
By default, [CSS Grid](https://www.w3.org/TR/css-grid-1/) and [Custom Properties](https://developer.mozilla.org/docs/Web/CSS/var) (CSS variables) are **not compiled** for IE11 support.
To compile [CSS Grid Layout](https://developer.mozilla.org/docs/Web/CSS/grid) for IE11, you can place the following comment at the top of your CSS file:
```css
/* autoprefixer grid: autoplace */
```
You can also enable IE11 support for [CSS Grid Layout](https://developer.mozilla.org/docs/Web/CSS/grid)
in your entire project by configuring autoprefixer with the configuration shown below (collapsed).
See ["Customizing Plugins"](#customizing-plugins) below for more information.
<details>
<summary>Click to view the configuration to enable CSS Grid Layout</summary>
```json filename="postcss.config.json"
{
"plugins": [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
"autoprefixer": {
"flexbox": "no-2009",
"grid": "autoplace"
},
"stage": 3,
"features": {
"custom-properties": false
}
}
]
]
}
```
</details>
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 filename="package.json"
{
"browserslist": [">0.3%", "not dead", "not op_mini all"]
}
```
You can use the [browsersl.ist](https://browsersl.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/app/getting-started/css).
## 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).
> You also need to install any plugins included in your custom configuration manually, i.e. `npm install postcss-flexbugs-fixes postcss-preset-env`.
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 filename="postcss.config.json"
{
"plugins": [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
"autoprefixer": {
"flexbox": "no-2009"
},
"stage": 3,
"features": {
"custom-properties": false
}
}
]
]
}
```
> **Good to know**: 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 filename="postcss.config.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
],
}
```
> **Good to know**: 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.
> **Good to know**: 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,
> },
> },
> },
> }
> ```
+252
View File
@@ -0,0 +1,252 @@
---
title: How to preview content with Preview Mode in Next.js
nav_title: Preview Mode
description: Next.js has the preview mode for statically generated pages. You can learn how it works here.
version: legacy
---
> **Note**: This feature is superseded by [Draft Mode](/docs/pages/guides/draft-mode).
<details>
<summary>Examples</summary>
- [Agility CMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-agilitycms) ([Demo](https://next-blog-agilitycms.vercel.app/))
- [Builder.io Example](https://github.com/vercel/next.js/tree/canary/examples/cms-builder-io) ([Demo](https://cms-builder-io.vercel.app/))
- [ButterCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-buttercms) ([Demo](https://next-blog-buttercms.vercel.app/))
- [Contentful Example](https://github.com/vercel/next.js/tree/canary/examples/cms-contentful) ([Demo](https://app-router-contentful.vercel.app/))
- [Cosmic Example](https://github.com/vercel/next.js/tree/canary/examples/cms-cosmic) ([Demo](https://next-blog-cosmic.vercel.app/))
- [DatoCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-datocms) ([Demo](https://next-blog-datocms.vercel.app/))
- [DotCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-dotcms) ([Demo](https://nextjs-dotcms-blog.vercel.app/))
- [Drupal Example](https://github.com/vercel/next.js/tree/canary/examples/cms-drupal) ([Demo](https://cms-drupal.vercel.app/))
- [Enterspeed Example](https://github.com/vercel/next.js/tree/canary/examples/cms-enterspeed) ([Demo](https://next-blog-demo.enterspeed.com/))
- [GraphCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms) ([Demo](https://next-blog-graphcms.vercel.app/))
- [Keystone Example](https://github.com/vercel/next.js/tree/canary/examples/cms-keystonejs-embedded) ([Demo](https://nextjs-keystone-demo.vercel.app/))
- [Kontent.ai Example](https://github.com/vercel/next.js/tree/canary/examples/cms-kontent-ai) ([Demo](https://next-blog-kontent-ai.vercel.app/))
- [Makeswift Example](https://github.com/vercel/next.js/tree/canary/examples/cms-makeswift) ([Demo](https://nextjs-makeswift-example.vercel.app/))
- [Plasmic Example](https://github.com/vercel/next.js/tree/canary/examples/cms-plasmic) ([Demo](https://nextjs-plasmic-example.vercel.app/))
- [Prepr Example](https://github.com/vercel/next.js/tree/canary/examples/cms-prepr) ([Demo](https://next-blog-prepr.vercel.app/))
- [Prismic Example](https://github.com/vercel/next.js/tree/canary/examples/cms-prismic) ([Demo](https://next-blog-prismic.vercel.app/))
- [Sanity Example](https://github.com/vercel/next.js/tree/canary/examples/cms-sanity) ([Demo](https://next-blog.sanity.build/))
- [Sitecore XM Cloud Example](https://github.com/vercel/next.js/tree/canary/examples/cms-sitecore-xmcloud) ([Demo](https://vercel-sitecore-xmcloud-demo.vercel.app/))
- [Storyblok Example](https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok) ([Demo](https://next-blog-storyblok.vercel.app/))
- [Strapi Example](https://github.com/vercel/next.js/tree/canary/examples/cms-strapi) ([Demo](https://next-blog-strapi.vercel.app/))
- [TakeShape Example](https://github.com/vercel/next.js/tree/canary/examples/cms-takeshape) ([Demo](https://next-blog-takeshape.vercel.app/))
- [Tina Example](https://github.com/vercel/next.js/tree/canary/examples/cms-tina) ([Demo](https://cms-tina-example.vercel.app/))
- [Umbraco Example](https://github.com/vercel/next.js/tree/canary/examples/cms-umbraco) ([Demo](https://nextjs-umbraco-sample-blog.vercel.app/))
- [Umbraco Heartcore Example](https://github.com/vercel/next.js/tree/canary/examples/cms-umbraco-heartcore) ([Demo](https://next-blog-umbraco-heartcore.vercel.app/))
- [Webiny Example](https://github.com/vercel/next.js/tree/canary/examples/cms-webiny) ([Demo](https://webiny-headlesscms-nextjs-example.vercel.app/))
- [WordPress Example](https://github.com/vercel/next.js/tree/canary/examples/cms-wordpress) ([Demo](https://next-blog-wordpress.vercel.app/))
- [Blog Starter Example](https://github.com/vercel/next.js/tree/canary/examples/blog-starter) ([Demo](https://next-blog-starter.vercel.app/))
</details>
In the [Pages documentation](/docs/pages/building-your-application/routing/pages-and-layouts) and the [Data Fetching documentation](/docs/pages/building-your-application/data-fetching), we talked about how to prerender 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, its not ideal when youre writing a draft on your headless CMS and want to **preview** the draft immediately on your page. Youd want Next.js to render these pages at **request time** instead of build time and fetch the draft content instead of the published content. Youd want Next.js to bypass Static Generation only for this specific case.
Next.js has a feature called **Preview Mode** which solves this problem. Here are instructions on how to use it.
## Step 1: Create and access a preview API route
> Take a look at the [API Routes documentation](/docs/pages/building-your-application/routing/api-routes) first if youre 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, well use `{}`.
```js
export default function handler(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 filename="pages/api/preview.js"
// simple example for testing it manually from your browser.
export default function handler(req, res) {
res.setPreviewData({})
res.end('Preview mode enabled')
}
```
If you open your browsers developer tools and visit `/api/preview`, youll 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, youd want to call this API route _securely_ from your headless CMS. The specific steps will vary depending on which headless CMS youre using, but here are some common steps you could take.
These steps assume that the headless CMS youre using supports setting **custom preview URLs**. If it doesnt, you can still use this method to secure your preview URLs, but youll 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 dont 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 filename="Terminal"
https://<your-site>/api/preview?secret=<token>&slug=<path>
```
- `<your-site>` should be your deployment domain.
- `<token>` should be replaced with the secret token you generated.
- `<path>` 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 `<path>` can be set dynamically based on the CMSs 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/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.redirect(post.slug)
}
```
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 youre 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' : ''}`)
// ...
}
```
Thats 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.
Set this as the preview URL on your headless CMS or access manually, and you should be able to see the preview.
```bash filename="Terminal"
https://<your-site>/api/preview?secret=<token>&slug=<path>
```
## More Details
> **Good to know**: during rendering `next/router` exposes an `isPreview` flag, see the [router object docs](/docs/pages/api-reference/functions/use-router#router-object) for more info.
### 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.
- `path`: Specifies the path the cookie should be applied under. Defaults to `/` enabling preview mode for all paths.
```js
setPreviewData(data, {
maxAge: 60 * 60, // The preview mode cookies expire in 1 hour
path: '/about', // The preview mode cookies apply to paths with /about
})
```
### Clear the Preview Mode cookies
By default, no expiration date is set for Preview Mode cookies, so the preview session ends when the browser is closed.
To clear the Preview Mode cookies manually, create an API route that calls `clearPreviewData()`:
```js filename="pages/api/clear-preview-mode-cookies.js"
export default function handler(req, res) {
res.clearPreviewData({})
}
```
Then, send a request to `/api/clear-preview-mode-cookies` to invoke the API Route. If calling this route using [`next/link`](/docs/pages/api-reference/components/link), you must pass `prefetch={false}` to prevent calling `clearPreviewData` during link prefetching.
If a path was specified in the `setPreviewData` call, you must pass the same path to `clearPreviewData`:
```js filename="pages/api/clear-preview-mode-cookies.js"
export default function handler(req, res) {
const { path } = req.query
res.clearPreviewData({ path })
}
```
### `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, theres 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`.
> **Good to know**: You shouldn't set the `Cache-Control` header when using Preview Mode because it cannot be bypassed. Instead, we recommend using [ISR](/docs/pages/guides/incremental-static-regeneration).
### Works with API Routes
API Routes will have access to `preview` and `previewData` under the request object. For example:
```js
export default function myApiRoute(req, res) {
const isPreview = req.preview
const previewData = req.previewData
// ...
}
```
### Unique per `next build`
Both the bypass cookie value and the private key for encrypting the `previewData` change when `next build` is completed.
This ensures that the bypass cookie cant be guessed.
> **Good to know**: To test Preview Mode locally over HTTP your browser will need to allow third-party cookies and local storage access.
@@ -0,0 +1,8 @@
---
title: How to optimize your Next.js application for production
nav_title: Production
description: Recommendations to ensure the best performance and user experience before taking your Next.js application to production.
source: app/guides/production-checklist
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to handle redirects in Next.js
nav_title: Redirecting
description: Learn the different ways to handle redirects in Next.js.
source: app/guides/redirecting
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to use Sass in Next.js
nav_title: Sass
description: Learn how to use Sass in your Next.js application.
source: app/guides/sass
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to load and optimize scripts
nav_title: Scripts
description: Optimize 3rd party scripts with the built-in Script component.
source: app/guides/scripts
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to self-host your Next.js application
nav_title: Self-Hosting
description: Learn how to self-host your Next.js application on a Node.js server, Docker image, or static HTML files (static exports).
source: app/guides/self-hosting
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to create a static export of your Next.js application
nav_title: Static Exports
description: Next.js enables starting as a static site or Single-Page Application (SPA), then later optionally upgrading to use features that require a server.
source: app/guides/static-exports
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+7
View File
@@ -0,0 +1,7 @@
---
title: Tailwind CSS
description: Style your Next.js Application using Tailwind CSS.
source: app/guides/tailwind-v3-css
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to set up Cypress with Next.js
nav_title: Cypress
description: Learn how to set up Next.js with Cypress for End-to-End (E2E) and Component Testing.
source: app/guides/testing/cypress
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+7
View File
@@ -0,0 +1,7 @@
---
title: Testing
description: Learn how to set up Next.js with three commonly used testing tools — Cypress, Playwright, Vitest, and Jest.
source: app/guides/testing
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to set up Jest with Next.js
nav_title: Jest
description: Learn how to set up Next.js with Jest for Unit Testing.
source: app/guides/testing/jest
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to set up Playwright with Next.js
nav_title: Playwright
description: Learn how to set up Next.js with Playwright for End-to-End (E2E) and Integration testing.
source: app/guides/testing/playwright
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+8
View File
@@ -0,0 +1,8 @@
---
title: How to set up Vitest with Next.js
nav_title: Vitest
description: Learn how to set up Next.js with Vitest and React Testing Library - two popular unit testing libraries.
source: app/guides/testing/vitest
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
@@ -0,0 +1,8 @@
---
title: How to optimize third-party libraries
nav_title: Third Party Libraries
description: Optimize the performance of third-party libraries in your application with the `@next/third-parties` package.
source: app/guides/third-party-libraries
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+7
View File
@@ -0,0 +1,7 @@
---
title: Codemods
description: Use codemods to upgrade your Next.js codebase when new features are released.
source: app/guides/upgrading/codemods
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+6
View File
@@ -0,0 +1,6 @@
---
title: Upgrading
description: Learn how to upgrade to the latest versions of Next.js.
---
Learn how to upgrade to the latest versions of Next.js following the versions-specific guides:
+27
View File
@@ -0,0 +1,27 @@
---
title: How to upgrade to version 10
nav_title: Version 10
description: Upgrade your Next.js Application from Version 9 to Version 10.
---
There were no breaking changes between versions 9 and 10.
To upgrade to version 10, run the following command:
```bash filename="Terminal"
npm i next@10
```
```bash filename="Terminal"
yarn add next@10
```
```bash filename="Terminal"
pnpm up next@10
```
```bash filename="Terminal"
bun add next@10
```
> **Good to know:** If you are using TypeScript, ensure you also upgrade `@types/react` and `@types/react-dom` to their corresponding versions.
+150
View File
@@ -0,0 +1,150 @@
---
title: How to upgrade to version 11
nav_title: Version 11
description: Upgrade your Next.js Application from Version 10 to Version 11.
---
To upgrade to version 11, run the following command:
```bash filename="Terminal"
npm i next@11 react@17 react-dom@17
```
```bash filename="Terminal"
yarn add next@11 react@17 react-dom@17
```
```bash filename="Terminal"
pnpm up next@11 react@17 react-dom@17
```
```bash filename="Terminal"
bun add next@11 react@17 react-dom@17
```
> **Good to know:** If you are using TypeScript, ensure you also upgrade `@types/react` and `@types/react-dom` to their corresponding versions.
### Webpack 5
Webpack 5 is now the default for all Next.js applications. If you did not have a custom webpack configuration, your application is already using webpack 5. If you do have a custom webpack configuration, you can refer to the [Next.js webpack 5 documentation](/docs/messages/webpack5) for upgrade guidance.
### Cleaning the `distDir` is now a default
The build output directory (defaults to `.next`) is now cleared by default except for the Next.js caches. You can refer to [the cleaning `distDir` RFC](https://github.com/vercel/next.js/discussions/6009) for more information.
If your application was relying on this behavior previously you can disable the new default behavior by adding the `cleanDistDir: false` flag in `next.config.js`.
### `PORT` is now supported for `next dev` and `next start`
Next.js 11 supports the `PORT` environment variable to set the port the application runs on. Using `-p`/`--port` is still recommended but if you were prohibited from using `-p` in any way you can now use `PORT` as an alternative:
Example:
```
PORT=4000 next start
```
### `next.config.js` customization to import images
Next.js 11 supports static image imports with `next/image`. This new feature relies on being able to process image imports. If you previously added the `next-images` or `next-optimized-images` packages you can either move to the new built-in support using `next/image` or disable the feature:
```js filename="next.config.js"
module.exports = {
images: {
disableStaticImages: true,
},
}
```
### Remove `super.componentDidCatch()` from `pages/_app.js`
The `next/app` component's `componentDidCatch` was deprecated in Next.js 9 as it's no longer needed and has since been a no-op. In Next.js 11, it was removed.
If your `pages/_app.js` has a custom `componentDidCatch` method you can remove `super.componentDidCatch` as it is no longer needed.
### Remove `Container` from `pages/_app.js`
This export was deprecated in Next.js 9 as it's no longer needed and has since been a no-op with a warning during development. In Next.js 11 it was removed.
If your `pages/_app.js` imports `Container` from `next/app` you can remove `Container` as it was removed. Learn more in [the documentation](/docs/messages/app-container-deprecated).
### Remove `props.url` usage from page components
This property was deprecated in Next.js 4 and has since shown a warning during development. With the introduction of `getStaticProps` / `getServerSideProps` these methods already disallowed the usage of `props.url`. In Next.js 11, it was removed completely.
You can learn more in [the documentation](/docs/messages/url-deprecated).
### Remove `unsized` property on `next/image`
The `unsized` property on `next/image` was deprecated in Next.js 10.0.1. You can use `layout="fill"` instead. In Next.js 11 `unsized` was removed.
### Remove `modules` property on `next/dynamic`
The `modules` and `render` option for `next/dynamic` were deprecated in Next.js 9.5. This was done in order to make the `next/dynamic` API closer to `React.lazy`. In Next.js 11, the `modules` and `render` options were removed.
This option hasn't been mentioned in the documentation since Next.js 8 so it's less likely that your application is using it.
If your application does use `modules` and `render` you can refer to [the documentation](/docs/messages/next-dynamic-modules).
### Remove `Head.rewind`
`Head.rewind` has been a no-op since Next.js 9.5, in Next.js 11 it was removed. You can safely remove your usage of `Head.rewind`.
### Moment.js locales excluded by default
Moment.js includes translations for a lot of locales by default. Next.js now automatically excludes these locales by default to optimize bundle size for applications using Moment.js.
To load a specific locale use this snippet:
```js
import moment from 'moment'
import 'moment/locale/ja'
moment.locale('ja')
```
You can opt-out of this new default by adding `excludeDefaultMomentLocales: false` to `next.config.js` if you do not want the new behavior, do note it's highly recommended to not disable this new optimization as it significantly reduces the size of Moment.js.
### Update usage of `router.events`
In case you're accessing `router.events` during rendering, in Next.js 11 `router.events` is no longer provided during prerendering. Ensure you're accessing `router.events` in `useEffect`:
```js
useEffect(() => {
const handleRouteChange = (url, { shallow }) => {
console.log(
`App is changing to ${url} ${
shallow ? 'with' : 'without'
} shallow routing`
)
}
router.events.on('routeChangeStart', handleRouteChange)
// If the component is unmounted, unsubscribe
// from the event with the `off` method:
return () => {
router.events.off('routeChangeStart', handleRouteChange)
}
}, [router])
```
If your application uses `router.router.events` which was an internal property that was not public please make sure to use `router.events` as well.
## React 16 to 17
React 17 introduced a new [JSX Transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) that brings a long-time Next.js feature to the wider React ecosystem: Not having to `import React from 'react'` when using JSX. When using React 17 Next.js will automatically use the new transform. This transform does not make the `React` variable global, which was an unintended side-effect of the previous Next.js implementation. A [codemod is available](/docs/pages/guides/upgrading/codemods#add-missing-react-import) to automatically fix cases where you accidentally used `React` without importing it.
Most applications already use the latest version of React, with Next.js 11 the minimum React version has been updated to 17.0.2.
To upgrade you can run the following command:
```
npm install react@latest react-dom@latest
```
Or using `yarn`:
```
yarn add react@latest react-dom@latest
```
+153
View File
@@ -0,0 +1,153 @@
---
title: How to upgrade to version 12
nav_title: Version 12
description: Upgrade your Next.js Application from Version 11 to Version 12.
---
To upgrade to version 12, run the following command:
```bash filename="Terminal"
npm i next@12 react@17 react-dom@17 eslint-config-next@12
```
```bash filename="Terminal"
yarn add next@12 react@17 react-dom@17 eslint-config-next@12
```
```bash filename="Terminal"
pnpm up next@12 react@17 react-dom@17 eslint-config-next@12
```
```bash filename="Terminal"
bun add next@12 react@17 react-dom@17 eslint-config-next@12
```
> **Good to know:** If you are using TypeScript, ensure you also upgrade `@types/react` and `@types/react-dom` to their corresponding versions.
### Upgrading to 12.2
[Middleware](/docs/messages/middleware-upgrade-guide) - If you were using Middleware prior to `12.2`, please see the [upgrade guide](/docs/messages/middleware-upgrade-guide) for more information.
### Upgrading to 12.0
[Minimum Node.js Version](https://nodejs.org/en/) - The minimum Node.js version has been bumped from `12.0.0` to `12.22.0` which is the first version of Node.js with native ES Modules support.
[Minimum React Version](https://react.dev/learn/add-react-to-an-existing-project) - The minimum required React version is `17.0.2`. To upgrade you can run the following command in the terminal:
```bash filename="Terminal"
npm install react@latest react-dom@latest
yarn add react@latest react-dom@latest
pnpm update react@latest react-dom@latest
bun add react@latest react-dom@latest
```
#### SWC replacing Babel
Next.js now uses the Rust-based compiler [SWC](https://swc.rs/) to compile JavaScript/TypeScript. This new compiler is up to 17x faster than Babel when compiling individual files and up to 5x faster Fast Refresh.
Next.js provides full backward compatibility with applications that have [custom Babel configuration](/docs/pages/guides/babel). All transformations that Next.js handles by default like styled-jsx and tree-shaking of `getStaticProps` / `getStaticPaths` / `getServerSideProps` have been ported to Rust.
When an application has a custom Babel configuration, Next.js will automatically opt-out of using SWC for compiling JavaScript/Typescript and will fall back to using Babel in the same way that it was used in Next.js 11.
Many of the integrations with external libraries that currently require custom Babel transformations will be ported to Rust-based SWC transforms in the near future. These include but are not limited to:
- Styled Components
- Emotion
- Relay
In order to prioritize transforms that will help you adopt SWC, please provide your `.babelrc` on [this feedback thread](https://github.com/vercel/next.js/discussions/30174).
#### SWC replacing Terser for minification
You can opt-in to replacing Terser with SWC for minifying JavaScript up to 7x faster using a flag in `next.config.js`:
```js filename="next.config.js"
module.exports = {
swcMinify: true,
}
```
Minification using SWC is an opt-in flag to ensure it can be tested against more real-world Next.js applications before it becomes the default in Next.js 12.1. If you have feedback about minification, please leave it on [this feedback thread](https://github.com/vercel/next.js/discussions/30237).
#### Improvements to styled-jsx CSS parsing
On top of the Rust-based compiler we've implemented a new CSS parser based on the one used for the styled-jsx Babel transform. This new parser has improved handling of CSS and now errors when invalid CSS is used that would previously slip through and cause unexpected behavior.
Because of this change invalid CSS will throw an error during development and `next build`. This change only affects styled-jsx usage.
#### `next/image` changed wrapping element
`next/image` now renders the `<img>` inside a `<span>` instead of `<div>`.
If your application has specific CSS targeting span such as `.container span`, upgrading to Next.js 12 might incorrectly match the wrapping element inside the `<Image>` component. You can avoid this by restricting the selector to a specific class such as `.container span.item` and updating the relevant component with that className, such as `<span className="item" />`.
If your application has specific CSS targeting the `next/image` `<div>` tag, for example `.container div`, it may not match anymore. You can update the selector `.container span`, or preferably, add a new `<div className="wrapper">` wrapping the `<Image>` component and target that instead such as `.container .wrapper`.
The `className` prop is unchanged and will still be passed to the underlying `<img>` element.
See the [documentation](/docs/pages/api-reference/components/image#styling-images) for more info.
#### HMR connection now uses a WebSocket
Previously, Next.js used a [server-sent events](https://developer.mozilla.org/docs/Web/API/Server-sent_events) connection to receive HMR events. Next.js 12 now uses a WebSocket connection.
In some cases when proxying requests to the Next.js dev server, you will need to ensure the upgrade request is handled correctly. For example, in `nginx` you would need to add the following configuration:
```nginx
location /_next/webpack-hmr {
proxy_pass http://localhost:3000/_next/webpack-hmr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
```
If you are using Apache (2.x), you can add the following configuration to enable web sockets to the server. Review the port, host name and server names.
```
<VirtualHost *:443>
# ServerName yourwebsite.local
ServerName "${WEBSITE_SERVER_NAME}"
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
# Next.js 12 uses websocket
<Location /_next/webpack-hmr>
RewriteEngine On
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule /(.*) ws://localhost:3000/_next/webpack-hmr/$1 [P,L]
ProxyPass ws://localhost:3000/_next/webpack-hmr retry=0 timeout=30
ProxyPassReverse ws://localhost:3000/_next/webpack-hmr
</Location>
</VirtualHost>
```
For custom servers, such as `express`, you may need to use `app.all` to ensure the request is passed correctly, for example:
```js
app.all('/_next/webpack-hmr', (req, res) => {
nextjsRequestHandler(req, res)
})
```
#### Webpack 4 support has been removed
If you are already using webpack 5 you can skip this section.
Next.js has adopted webpack 5 as the default for compilation in Next.js 11. As communicated in the [webpack 5 upgrading documentation](/docs/messages/webpack5) Next.js 12 removes support for webpack 4.
If your application is still using webpack 4 using the opt-out flag, you will now see an error linking to the [webpack 5 upgrading documentation](/docs/messages/webpack5).
#### `target` option deprecated
If you do not have `target` in `next.config.js` you can skip this section.
The target option has been deprecated in favor of built-in support for tracing what dependencies are needed to run a page.
During `next build`, Next.js will automatically trace each page and its dependencies to determine all of the files that are needed for deploying a production version of your application.
If you are currently using the `target` option set to `serverless`, please read the [documentation on how to leverage the new output](/docs/pages/api-reference/config/next-config-js/output).
+88
View File
@@ -0,0 +1,88 @@
---
title: How to upgrade to version 13
nav_title: Version 13
description: Upgrade your Next.js Application from Version 12 to 13.
---
## Upgrading from 12 to 13
To update to Next.js version 13, run the following command using your preferred package manager:
```bash filename="Terminal"
npm i next@13 react@latest react-dom@latest eslint-config-next@13
```
```bash filename="Terminal"
yarn add next@13 react@latest react-dom@latest eslint-config-next@13
```
```bash filename="Terminal"
pnpm i next@13 react@latest react-dom@latest eslint-config-next@13
```
```bash filename="Terminal"
bun add next@13 react@latest react-dom@latest eslint-config-next@13
```
> **Good to know:** If you are using TypeScript, ensure you also upgrade `@types/react` and `@types/react-dom` to their latest versions.
### v13 Summary
- The [Supported Browsers](/docs/architecture/supported-browsers) have been changed to drop Internet Explorer and target modern browsers.
- The minimum Node.js version has been bumped from 12.22.0 to 16.14.0, since 12.x and 14.x have reached end-of-life.
- The minimum React version has been bumped from 17.0.2 to 18.2.0.
- The `swcMinify` configuration property was changed from `false` to `true`. See [Next.js Compiler](/docs/architecture/nextjs-compiler) for more info.
- The `next/image` import was renamed to `next/legacy/image`. The `next/future/image` import was renamed to `next/image`. A [codemod is available](/docs/pages/guides/upgrading/codemods#next-image-to-legacy-image) to safely and automatically rename your imports.
- The `next/link` child can no longer be `<a>`. Add the `legacyBehavior` prop to use the legacy behavior or remove the `<a>` to upgrade. A [codemod is available](/docs/pages/guides/upgrading/codemods#new-link) to automatically upgrade your code.
- The `target` configuration property has been removed and superseded by [Output File Tracing](/docs/pages/api-reference/config/next-config-js/output).
## Migrating shared features
Next.js 13 introduces a new [`app` directory](/docs/app) with new features and conventions. However, upgrading to Next.js 13 does **not** require using the new `app` Router.
You can continue using `pages` with new features that work in both directories, such as the updated [Image component](#image-component), [Link component](#link-component), [Script component](#script-component), and [Font optimization](#font-optimization).
### `<Image/>` Component
Next.js 12 introduced many improvements to the Image Component with a temporary import: `next/future/image`. These improvements included less client-side JavaScript, easier ways to extend and style images, better accessibility, and native browser lazy loading.
Starting in Next.js 13, this new behavior is now the default for `next/image`.
There are two codemods to help you migrate to the new Image Component:
- [next-image-to-legacy-image](/docs/pages/guides/upgrading/codemods#next-image-to-legacy-image): This codemod will safely and automatically rename `next/image` imports to `next/legacy/image` to maintain the same behavior as Next.js 12. We recommend running this codemod to quickly update to Next.js 13 automatically.
- [next-image-experimental](/docs/pages/guides/upgrading/codemods#next-image-experimental): After running the previous codemod, you can optionally run this experimental codemod to upgrade `next/legacy/image` to the new `next/image`, which will remove unused props and add inline styles. Please note this codemod is experimental and only covers static usage (such as `<Image src={img} layout="responsive" />`) but not dynamic usage (such as `<Image {...props} />`).
Alternatively, you can manually update by following the [migration guide](/docs/pages/guides/upgrading/codemods#next-image-experimental) and also see the [legacy comparison](/docs/pages/api-reference/components/image-legacy#comparison).
### `<Link>` Component
The [`<Link>` Component](/docs/pages/api-reference/components/link) no longer requires manually adding an `<a>` tag as a child. This behavior was added as an experimental option in [version 12.2](https://nextjs.org/blog/next-12-2) and is now the default. In Next.js 13, `<Link>` always renders `<a>` and allows you to forward props to the underlying tag.
For example:
```jsx
import Link from 'next/link'
// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
<a>About</a>
</Link>
// Next.js 13: `<Link>` always renders `<a>` under the hood
<Link href="/about">
About
</Link>
```
To upgrade your links to Next.js 13, you can use the [`new-link` codemod](/docs/pages/guides/upgrading/codemods#new-link).
### `<Script>` Component
The behavior of [`next/script`](/docs/pages/api-reference/components/script) has been updated to support both `pages` and `app`. If incrementally adopting `app`, read the [upgrade guide](/docs/pages/guides/upgrading).
### Font Optimization
Previously, Next.js helped you optimize fonts by inlining font CSS. Version 13 introduces the new [`next/font`](/docs/pages/api-reference/components/font) module which gives you the ability to customize your font loading experience while still ensuring great performance and privacy.
See [Optimizing Fonts](/docs/pages/api-reference/components/font) to learn how to use `next/font`.
@@ -0,0 +1,8 @@
---
title: How to upgrade to version 14
nav_title: Version 14
description: Upgrade your Next.js Application from Version 13 to 14.
source: app/guides/upgrading/version-14
---
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
+226
View File
@@ -0,0 +1,226 @@
---
title: How to upgrade to version 9
nav_title: Version 9
description: Upgrade your Next.js Application from Version 8 to Version 9.
---
To upgrade to version 9, run the following command:
```bash filename="Terminal"
npm i next@9
```
```bash filename="Terminal"
yarn add next@9
```
```bash filename="Terminal"
pnpm up next@9
```
```bash filename="Terminal"
bun add next@9
```
> **Good to know:** If you are using TypeScript, ensure you also upgrade `@types/react` and `@types/react-dom` to their corresponding versions.
## Check your Custom App File (`pages/_app.js`)
If you previously copied the [Custom `<App>`](/docs/pages/building-your-application/routing/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).
The 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 an 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: () => <p>Loading</p>,
}
)
```
### `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 filename="Terminal"
curl -L https://github.com/vercel/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 <h1>My AMP Page</h1>
}
export default withAmp(Home)
// or
export default withAmp(Home, { hybrid: true })
```
**After**
```jsx
export default function Home() {
return <h1>My AMP Page</h1>
}
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 filename="next.config.js"
module.exports = {
trailingSlash: 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 }) => (
<div>
<h1>{props.title}</h1>
<Hello1 />
<Hello2 />
</div>
),
})
function DynamicBundle() {
return <HelloBundle title="Dynamic Bundle" />
}
export default DynamicBundle
```
**After**
```jsx
import dynamic from 'next/dynamic'
const Hello1 = dynamic(() => import('../components/hello1'))
const Hello2 = dynamic(() => import('../components/hello2'))
function HelloBundle({ title }) {
return (
<div>
<h1>{title}</h1>
<Hello1 />
<Hello2 />
</div>
)
}
function DynamicBundle() {
return <HelloBundle title="Dynamic Bundle" />
}
export default DynamicBundle
```