Docs Next Compressed
Docs Next Compressed
title: Installation
description: Create a new Next.js application with `create-next-app`. Set up
TypeScript, styles, and configure your `next.config.js` file.
related:
title: Next Steps
description: Learn about the files and folders in your Next.js project.
links:
- getting-started/project-structure
---
System Requirements:
## Automatic Installation
```bash filename="Terminal"
npx create-next-app@latest
```
```txt filename="Terminal"
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
What import alias would you like configured? @/*
```
After the prompts, `create-next-app` will create a folder with your project
name and install the required dependencies.
## Manual Installation
```bash filename="Terminal"
npm install next@latest react@latest react-dom@latest
```
```json filename="package.json"
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}
```
Next.js uses file-system routing, which means the routes in your application are
determined by how you structure your files.
<Image
alt="App Folder Structure"
srcLight="/docs/light/app-getting-started.png"
srcDark="/docs/dark/app-getting-started.png"
width="1600"
height="363"
/>
If you prefer to use the Pages Router instead of the App Router, you can create
a `pages/` directory at the root of your project.
Then, add an `index.tsx` file inside your `pages` folder. This will be your home
page (`/`):
Next, add an `_app.tsx` file inside `pages/` to define the global layout. Learn
more about the [custom App file](/docs/pages/building-your-application/
routing/custom-app).
> **Good to know**: Although you can use both routers in the same project,
routes in `app` will be prioritized over `pages`. We recommend using only one
router in your new project to avoid confusion.
Create a `public` folder to store static assets such as images, fonts, etc. Files
inside `public` directory can then be referenced by your code starting from the
base URL (`/`).
---
title: Next.js Project Structure
nav_title: Project Structure
description: A list of folders and files conventions in a Next.js project
---
This page provides an overview of the file and folder structure of a Next.js
project. It covers top-level files and folders, configuration files, and routing
conventions within the `app` and `pages` directories.
## Top-level folders
| | |
| ------------------------------------------------------------------------ |
---------------------------------- |
| [`app`](/docs/app/building-your-application/routing) | App Router
|
| [`pages`](/docs/pages/building-your-application/routing) | Pages
Router |
| [`public`](/docs/app/building-your-application/optimizing/static-assets) |
Static assets to be served |
| [`src`](/docs/app/building-your-application/configuring/src-directory) |
Optional application source folder |
## Top-level files
| |
|
|
-------------------------------------------------------------------------------
------------ | --------------------------------------- |
| **Next.js** |
|
| [`next.config.js`](/docs/app/api-reference/next-config-js) |
Configuration file for Next.js |
| [`package.json`](/docs/getting-started/installation#manual-installation)
| Project dependencies and scripts |
| [`instrumentation.ts`](/docs/app/building-your-application/optimizing/
instrumentation) | OpenTelemetry and Instrumentation file |
| [`middleware.ts`](/docs/app/building-your-application/routing/middleware)
| Next.js request middleware |
| [`.env`](/docs/app/building-your-application/configuring/environment-
variables) | Environment variables |
| [`.env.local`](/docs/app/building-your-application/configuring/environment-
variables) | Local environment variables |
| [`.env.production`](/docs/app/building-your-application/configuring/
environment-variables) | Production environment variables |
| [`.env.development`](/docs/app/building-your-application/configuring/
environment-variables) | Development environment variables |
| [`.eslintrc.json`](/docs/app/building-your-application/configuring/eslint)
| Configuration file for ESLint |
| `.gitignore` | Git files and
folders to ignore |
| `next-env.d.ts` | TypeScript
declaration file for Next.js |
| `tsconfig.json` | Configuration
file for TypeScript |
| `jsconfig.json` | Configuration
file for JavaScript |
| | |
|
|
-------------------------------------------------------------------------------
| ------------------- | ---------------------------- |
| [`layout`](/docs/app/api-reference/file-conventions/layout) | `.js`
`.jsx` `.tsx` | Layout |
| [`page`](/docs/app/api-reference/file-conventions/page) | `.js`
`.jsx` `.tsx` | Page |
| [`loading`](/docs/app/api-reference/file-conventions/loading) | `.js`
`.jsx` `.tsx` | Loading UI |
| [`not-found`](/docs/app/api-reference/file-conventions/not-found) |
`.js` `.jsx` `.tsx` | Not found UI |
| [`error`](/docs/app/api-reference/file-conventions/error) | `.js`
`.jsx` `.tsx` | Error UI |
| [`global-error`](/docs/app/api-reference/file-conventions/error#global-
errorjs) | `.js` `.jsx` `.tsx` | Global error UI |
| [`route`](/docs/app/api-reference/file-conventions/route) | `.js`
`.ts` | API endpoint |
| [`template`](/docs/app/api-reference/file-conventions/template) |
`.js` `.jsx` `.tsx` | Re-rendered layout |
| [`default`](/docs/app/api-reference/file-conventions/default) | `.js`
`.jsx` `.tsx` | Parallel route fallback page |
| | |
| ---------------------------------------------------------------------------- |
-------------------- |
| [`folder`](/docs/app/building-your-application/routing#route-segments) |
Route segment |
| [`folder/folder`](/docs/app/building-your-application/routing#nested-routes) |
Nested route segment |
| |
|
|
-------------------------------------------------------------------------------
---- | ------------------------------------------------ |
| [`(folder)`](/docs/app/building-your-application/routing/route-
groups#convention) | Group routes without affecting routing |
| [`_folder`](/docs/app/building-your-application/routing/colocation#private-
folders) | Opt folder and all child segments out of routing |
| | |
|
-------------------------------------------------------------------------------
--------------- | -------------------------- |
| [`@folder`](/docs/app/building-your-application/routing/parallel-
routes#convention) | Named slot |
| [`(.)folder`](/docs/app/building-your-application/routing/intercepting-
routes#convention) | Intercept same level |
| [`(..)folder`](/docs/app/building-your-application/routing/intercepting-
routes#convention) | Intercept one level above |
| [`(..)(..)folder`](/docs/app/building-your-application/routing/intercepting-
routes#convention) | Intercept two levels above |
| [`(...)folder`](/docs/app/building-your-application/routing/intercepting-
routes#convention) | Intercept from root |
| |
| |
|
-------------------------------------------------------------------------------
-------------------------------- | ----------------------------------- |
------------------------ |
| [`favicon`](/docs/app/api-reference/file-conventions/metadata/app-
icons#favicon) | `.ico` | Favicon file |
| [`icon`](/docs/app/api-reference/file-conventions/metadata/app-icons#icon)
| `.ico` `.jpg` `.jpeg` `.png` `.svg` | App Icon file |
| [`icon`](/docs/app/api-reference/file-conventions/metadata/app-
icons#generate-icons-using-code-js-ts-tsx) | `.js` `.ts` `.tsx` |
Generated App Icon |
| [`apple-icon`](/docs/app/api-reference/file-conventions/metadata/app-
icons#apple-icon) | `.jpg` `.jpeg`, `.png` | Apple App
Icon file |
| [`apple-icon`](/docs/app/api-reference/file-conventions/metadata/app-
icons#generate-icons-using-code-js-ts-tsx) | `.js` `.ts` `.tsx` |
Generated Apple App Icon |
| |
| |
|
-------------------------------------------------------------------------------
-------------------------------------------- | ---------------------------- |
-------------------------- |
| [`opengraph-image`](/docs/app/api-reference/file-conventions/metadata/
opengraph-image#opengraph-image) | `.jpg` `.jpeg` `.png` `.gif`
| Open Graph image file |
| [`opengraph-image`](/docs/app/api-reference/file-conventions/metadata/
opengraph-image#generate-images-using-code-js-ts-tsx) | `.js` `.ts` `.tsx`
| Generated Open Graph image |
| [`twitter-image`](/docs/app/api-reference/file-conventions/metadata/
opengraph-image#twitter-image) | `.jpg` `.jpeg` `.png` `.gif` |
Twitter image file |
| [`twitter-image`](/docs/app/api-reference/file-conventions/metadata/
opengraph-image#generate-images-using-code-js-ts-tsx) | `.js` `.ts` `.tsx`
| Generated Twitter image |
#### SEO
| | | |
|
-------------------------------------------------------------------------------
------------ | ----------- | --------------------- |
| [`sitemap`](/docs/app/api-reference/file-conventions/metadata/
sitemap#static-sitemapxml) | `.xml` | Sitemap file |
| [`sitemap`](/docs/app/api-reference/file-conventions/metadata/
sitemap#generate-a-sitemap) | `.js` `.ts` | Generated Sitemap |
| [`robots`](/docs/app/api-reference/file-conventions/metadata/robots#static-
robotstxt) | `.txt` | Robots file |
| [`robots`](/docs/app/api-reference/file-conventions/metadata/
robots#generate-a-robots-file) | `.js` `.ts` | Generated Robots file |
| | |
|
|
-------------------------------------------------------------------------------
---------------------------- | ------------------- | ----------------- |
| [`_app`](/docs/pages/building-your-application/routing/custom-app)
| `.js` `.jsx` `.tsx` | Custom App |
| [`_document`](/docs/pages/building-your-application/routing/custom-
document) | `.js` `.jsx` `.tsx` | Custom Document |
| [`_error`](/docs/pages/building-your-application/routing/custom-error#more-
advanced-error-page-customizing) | `.js` `.jsx` `.tsx` | Custom Error Page |
| [`404`](/docs/pages/building-your-application/routing/custom-error#404-
page) | `.js` `.jsx` `.tsx` | 404 Error Page |
| [`500`](/docs/pages/building-your-application/routing/custom-error#500-
page) | `.js` `.jsx` `.tsx` | 500 Error Page |
### Routes
| | |
|
|
-------------------------------------------------------------------------------
--------------- | ------------------- | ----------- |
| **Folder convention** |
| |
| [`index`](/docs/pages/building-your-application/routing/pages-and-
layouts#index-routes) | `.js` `.jsx` `.tsx` | Home page |
| [`folder/index`](/docs/pages/building-your-application/routing/pages-and-
layouts#index-routes) | `.js` `.jsx` `.tsx` | Nested page |
| **File convention** |
| |
| [`index`](/docs/pages/building-your-application/routing/pages-and-
layouts#index-routes) | `.js` `.jsx` `.tsx` | Home page |
| [`file`](/docs/pages/building-your-application/routing/pages-and-layouts)
| `.js` `.jsx` `.tsx` | Nested page |
### Dynamic Routes
| |
| |
|
-------------------------------------------------------------------------------
---------------------------------- | ------------------- |
-------------------------------- |
| **Folder convention**
| | |
| [`[folder]/index`](/docs/pages/building-your-application/routing/dynamic-
routes) | `.js` `.jsx` `.tsx` | Dynamic route segment |
| [`[...folder]/index`](/docs/pages/building-your-application/routing/dynamic-
routes#catch-all-segments) | `.js` `.jsx` `.tsx` | Catch-all route segment
|
| [`[[...folder]]/index`](/docs/pages/building-your-application/routing/dynamic-
routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | Optional catch-all
route segment |
| **File convention** |
| |
| [`[file]`](/docs/pages/building-your-application/routing/dynamic-routes)
| `.js` `.jsx` `.tsx` | Dynamic route segment |
| [`[...file]`](/docs/pages/building-your-application/routing/dynamic-
routes#catch-all-segments) | `.js` `.jsx` `.tsx` | Catch-all route
segment |
| [`[[...file]]`](/docs/pages/building-your-application/routing/dynamic-
routes#optional-catch-all-segments) | `.js` `.jsx` `.tsx` | Optional catch-
all route segment |
---
title: Defining Routes
description: Learn how to create your first route in Next.js.
related:
description: Learn more about creating pages and layouts.
links:
- app/building-your-application/routing/pages-and-layouts
---
This page will guide you through how to define and organize routes in your
Next.js application.
## Creating Routes
Next.js uses a file-system based router where **folders** are used to define
routes.
<Image
alt="Route segments to path segments"
srcLight="/docs/light/route-segments-to-path-segments.png"
srcDark="/docs/dark/route-segments-to-path-segments.png"
width="1600"
height="594"
/>
<Image
alt="Defining Routes"
srcLight="/docs/light/defining-routes.png"
srcDark="/docs/dark/defining-routes.png"
width="1600"
height="687"
/>
> **Good to know**: `.js`, `.jsx`, or `.tsx` file extensions can be used for
special files.
## Creating UI
For example, to create your first page, add a `page.js` file inside the `app`
directory and export a React component:
```tsx filename="app/page.tsx" switcher
export default function Page() {
return <h1>Hello, Next.js!</h1>
}
```
---
title: Pages and Layouts
description: Create your first page and shared layout with the App Router.
---
The App Router inside Next.js 13 introduced new file conventions to easily
create [pages](#pages), [shared layouts](#layouts), and [templates]
(#templates). This page will guide you through how to use these special files in
your Next.js application.
## Pages
Create your first page by adding a `page.js` file inside the `app` directory:
<Image
alt="page.js special file"
srcLight="/docs/light/page-special-file.png"
srcDark="/docs/dark/page-special-file.png"
width="1600"
height="444"
/>
## Layouts
<Image
alt="layout.js special file"
srcLight="/docs/light/layout-special-file.png"
srcDark="/docs/dark/layout-special-file.png"
width="1600"
height="606"
/>
{children}
</section>
)
}
```
{children}
</section>
)
}
```
The root layout is defined at the top level of the `app` directory and applies to
all routes. This layout enables you to modify the initial HTML returned from the
server.
> **Migrating from the `pages` directory:** The root layout replaces the
[`_app.js`](/docs/pages/building-your-application/routing/custom-app) and
[`_document.js`](/docs/pages/building-your-application/routing/custom-
document) files. [View the migration guide](/docs/app/building-your-
application/upgrading/app-router-migration#migrating-_documentjs-and-
_appjs).
<Image
alt="Nested Layout"
srcLight="/docs/light/nested-layout.png"
srcDark="/docs/dark/nested-layout.png"
width="1600"
height="606"
/>
```tsx filename="app/dashboard/layout.tsx" switcher
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
```
If you were to combine the two layouts above, the root layout (`app/layout.js`)
would wrap the dashboard layout (`app/dashboard/layout.js`), which would
wrap route segments inside `app/dashboard/*`.
<Image
alt="Nested Layouts"
srcLight="/docs/light/nested-layouts-ui.png"
srcDark="/docs/dark/nested-layouts-ui.png"
width="1600"
height="1026"
/>
## Templates
Templates are similar to layouts in that they wrap each child layout or page.
Unlike layouts that persist across routes and maintain state, templates create a
new instance for each of their children on navigation. This means that when a
user navigates between routes that share a template, a new instance of the
component is mounted, DOM elements are recreated, state is **not**
preserved, and effects are re-synchronized.
There may be cases where you need those specific behaviors, and templates
would be a more suitable option than layouts. For example:
- Features that rely on `useEffect` (e.g logging page views) and `useState`
(e.g a per-page feedback form).
- To change the default framework behavior. For example, Suspense
Boundaries inside layouts only show the fallback the first time the Layout is
loaded and not when switching pages. For templates, the fallback is shown on
each navigation.
<Image
alt="template.js special file"
srcLight="/docs/light/template-special-file.png"
srcDark="/docs/dark/template-special-file.png"
width="1600"
height="444"
/>
```jsx filename="Output"
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>
```
## Modifying `<head>`
In the `app` directory, you can modify the `<head>` HTML elements such as
`title` and `meta` using the [built-in SEO support](/docs/app/building-your-
application/optimizing/metadata).
> **Good to know**: You should **not** manually add `<head>` tags such as
`<title>` and `<meta>` to root layouts. Instead, you should use the [Metadata
API](/docs/app/api-reference/functions/generate-metadata) which
automatically handles advanced requirements such as streaming and de-
duplicating `<head>` elements.
---
title: Linking and Navigating
description: Learn how navigation works in Next.js, and how to use the Link
Component and `useRouter` hook.
related:
links:
- app/building-your-application/caching
- app/building-your-application/configuring/typescript
---
This page will go through how to use `<Link>`, `useRouter()`, and dive deeper
into how navigation works.
## `<Link>` Component
`<Link>` is a built-in component that extends the HTML `<a>` tag to provide
[prefetching](#1-prefetching) and client-side navigation between routes. It is
the primary way to navigate between routes in Next.js.
You can use it by importing it from `next/link`, and passing a `href` prop to the
component:
There are other optional props you can pass to `<Link>`. See the [API
reference](/docs/app/api-reference/components/link) for more.
### Examples
```jsx filename="app/blog/PostList.js"
import Link from 'next/link'
return (
<nav>
<ul>
<li>
<Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/">
Home
</Link>
</li>
<li>
<Link
className={`link ${pathname === '/about' ? 'active' : ''}`}
href="/about"
>
About
</Link>
</li>
</ul>
</nav>
)
}
```
return (
<nav>
<ul>
<li>
<Link className={`link ${pathname === '/' ? 'active' : ''}`} href="/">
Home
</Link>
</li>
<li>
<Link
className={`link ${pathname === '/about' ? 'active' : ''}`}
href="/about"
>
About
</Link>
</li>
</ul>
</nav>
)
}
```
The default behavior of the Next.js App Router is to scroll to the top of a new
route or to maintain the scroll position for backwards and forwards navigation.
If you'd like to scroll to a specific `id` on navigation, you can append your URL
with a `#` hash link or just pass a hash link to the `href` prop. This is possible
since `<Link>` renders to an `<a>` element.
```jsx
<Link href="/dashboard#settings">Settings</Link>
// Output
<a href="/dashboard#settings">Settings</a>
```
The default behavior of the Next.js App Router is to scroll to the top of a new
route or to maintain the scroll position for backwards and forwards navigation.
If you'd like to disable this behavior, you can pass `scroll={false}` to the
`<Link>` component, or `scroll: false` to `router.push()` or `router.replace()`.
```jsx
// next/link
<Link href="/dashboard" scroll={false}>
Dashboard
</Link>
```
```jsx
// useRouter
import { useRouter } from 'next/navigation'
## `useRouter()` Hook
This hook can only be used inside Client Components and is imported from
`next/navigation`.
```jsx filename="app/page.js"
'use client'
The App Router uses a hybrid approach for routing and navigation. On the
server, your application code is automatically code-split by route segments.
And on the client, Next.js [prefetches](#1-prefetching) and [caches](#2-
caching) the route segments. This means, when a user navigates to a new
route, the browser doesn't reload the page, and only the route segments that
change re-render - improving the navigation experience and performance.
### 1. Prefetching
Prefetching is a way to preload a route in the background before the user visits
it.
- [**Static Routes**](/docs/app/building-your-application/rendering/server-
components#static-rendering-default): `prefetch` defaults to `true`. The
entire route is prefetched and cached.
- [**Dynamic Routes**](/docs/app/building-your-application/rendering/server-
components#dynamic-rendering): `prefetch` default to automatic. Only the
shared layout down until the first `loading.js` file is prefetched and cached for
`30s`. This reduces the cost of fetching an entire dynamic route, and it means
you can show an [instant loading state](/docs/app/building-your-application/
routing/loading-ui-and-streaming#instant-loading-states) for better visual
feedback to users.
### 2. Caching
Partial rendering means only the route segments that change on navigation re-
render on the client, and any shared segments are preserved.
<Image
alt="How partial rendering works"
srcLight="/docs/light/partial-rendering.png"
srcDark="/docs/dark/partial-rendering.png"
width="1600"
height="945"
/>
Without partial rendering, each navigation would cause the full page to re-
render on the server. Rendering only the segment that changes reduces the
amount of data transferred and execution time, leading to improved
performance.
By default, the browser performs a hard navigation between pages. This means
the browser reloads the page and resets React state such as `useState` hooks
in your app and browser state such as the user's scroll position or focused
element. However, in Next.js, the App Router uses soft navigation. This means
React only renders the segments that have changed while preserving React and
browser state, and there is no full page reload.
By default, Next.js will maintain the scroll position for backwards and forwards
navigation, and re-use route segments in the [Router Cache](/docs/app/
building-your-application/data-fetching/fetching-caching-and-
revalidating#caching-data).
---
title: Route Groups
description: Route Groups can be used to partition your Next.js application into
different sections.
---
In the `app` directory, nested folders are normally mapped to URL paths.
However, you can mark a folder as a **Route Group** to prevent the folder
from being included in the route's URL path.
This allows you to organize your route segments and project files into logical
groups without affecting the URL path structure.
## Convention
To organize routes without affecting the URL, create a group to keep related
routes together. The folders in parenthesis will be omitted from the URL (e.g.
`(marketing)` or `(shop)`).
<Image
alt="Organizing Routes with Route Groups"
srcLight="/docs/light/route-group-organisation.png"
srcDark="/docs/dark/route-group-organisation.png"
width="1600"
height="930"
/>
Even though routes inside `(marketing)` and `(shop)` share the same URL
hierarchy, you can create a different layout for each group by adding a
`layout.js` file inside their folders.
<Image
alt="Route Groups with Multiple Layouts"
srcLight="/docs/light/route-group-multiple-layouts.png"
srcDark="/docs/dark/route-group-multiple-layouts.png"
width="1600"
height="768"
/>
To opt specific routes into a layout, create a new route group (e.g. `(shop)`)
and move the routes that share the same layout into the group (e.g. `account`
and `cart`). The routes outside of the group will not share the layout (e.g.
`checkout`).
<Image
alt="Route Groups with Opt-in Layouts"
srcLight="/docs/light/route-group-opt-in-layouts.png"
srcDark="/docs/dark/route-group-opt-in-layouts.png"
width="1600"
height="930"
/>
<Image
alt="Route Groups with Multiple Root Layouts"
srcLight="/docs/light/route-group-multiple-root-layouts.png"
srcDark="/docs/dark/route-group-multiple-root-layouts.png"
width="1600"
height="687"
/>
In the example above, both `(marketing)` and `(shop)` have their own root
layout.
---
---
title: Dynamic Routes
description: Dynamic Routes can be used to programmatically generate route
segments from dynamic data.
related:
title: Next Steps
description: For more information on what to do next, we recommend the
following sections
links:
- app/building-your-application/routing/linking-and-navigating
- app/api-reference/functions/generate-static-params
---
When you don't know the exact segment names ahead of time and want to
create routes from dynamic data, you can use Dynamic Segments that are filled
in at request time or [prerendered](#generating-static-params) at build time.
## Convention
## Example
## Catch-all Segments
## TypeScript
When using TypeScript, you can add types for `params` depending on your
configured route segment.
---
title: Loading UI and Streaming
description: Built on top of Suspense, Loading UI allows you to create a fallback
for specific route segments, and automatically stream content as it becomes
ready.
---
The special file `loading.js` helps you create meaningful Loading UI with [React
Suspense](https://react.dev/reference/react/Suspense). With this convention,
you can show an [instant loading state](#instant-loading-states) from the
server while the content of a route segment loads. The new content is
automatically swapped in once rendering is complete.
<Image
alt="Loading UI"
srcLight="/docs/light/loading-ui.png"
srcDark="/docs/dark/loading-ui.png"
width="1600"
height="691"
/>
<Image
alt="loading.js special file"
srcLight="/docs/light/loading-special-file.png"
srcDark="/docs/dark/loading-special-file.png"
width="1600"
height="606"
/>
```tsx filename="app/dashboard/loading.tsx" switcher
export default function Loading() {
// You can add any UI inside Loading, including a Skeleton.
return <LoadingSkeleton />
}
```
<Image
alt="loading.js overview"
srcLight="/docs/light/loading-overview.png"
srcDark="/docs/dark/loading-overview.png"
width="1600"
height="768"
/>
To learn how Streaming works in React and Next.js, it's helpful to understand
**Server-Side Rendering (SSR)** and its limitations.
With SSR, there's a series of steps that need to be completed before a user can
see and interact with a page:
<Image
alt="Chart showing Server Rendering without Streaming"
srcLight="/docs/light/server-rendering-without-streaming-chart.png"
srcDark="/docs/dark/server-rendering-without-streaming-chart.png"
width="1600"
height="612"
/>
These steps are sequential and blocking, meaning the server can only render
the HTML for a page once all the data has been fetched. And, on the client,
React can only hydrate the UI once the code for all components in the page has
been downloaded.
SSR with React and Next.js helps improve the perceived loading performance
by showing a non-interactive page to the user as soon as possible.
<Image
alt="Server Rendering without Streaming"
srcLight="/docs/light/server-rendering-without-streaming.png"
srcDark="/docs/dark/server-rendering-without-streaming.png"
width="1600"
height="748"
/>
**Streaming** allows you to break down the page's HTML into smaller chunks
and progressively send those chunks from the server to the client.
<Image
alt="How Server Rendering with Streaming Works"
srcLight="/docs/light/server-rendering-with-streaming.png"
srcDark="/docs/dark/server-rendering-with-streaming.png"
width="1600"
height="785"
/>
This enables parts of the page to be displayed sooner, without waiting for all
the data to load before any UI can be rendered.
Streaming works well with React's component model because each component
can be considered a chunk. Components that have higher priority (e.g. product
information) or that don't rely on data can be sent first (e.g. layout), and React
can start hydration earlier. Components that have lower priority (e.g. reviews,
related products) can be sent in the same server request after their data has
been fetched.
<Image
alt="Chart showing Server Rendering with Streaming"
srcLight="/docs/light/server-rendering-with-streaming-chart.png"
srcDark="/docs/dark/server-rendering-with-streaming-chart.png"
width="1600"
height="730"
/>
### Example
For more Suspense examples and use cases, please see the [React
Documentation](https://react.dev/reference/react/Suspense).
### SEO
When streaming, a `200` status code will be returned to signal that the request
was successful.
The server can still communicate errors or issues to the client within the
streamed content itself, for example, when using [`redirect`](/docs/app/api-
reference/functions/redirect) or [`notFound`](/docs/app/api-reference/
functions/not-found). Since the response headers have already been sent to
the client, the status code of the response cannot be updated. This does not
affect SEO.
---
title: Error Handling
description: Handle runtime errors by automatically wrapping route segments
and their nested children in a React Error Boundary.
related:
links:
- app/api-reference/file-conventions/error
---
- Automatically wrap a route segment and its nested children in a [React Error
Boundary](https://react.dev/reference/react/Component#catching-rendering-
errors-with-an-error-boundary).
- Create error UI tailored to specific segments using the file-system hierarchy
to adjust granularity.
- Isolate errors to affected segments while keeping the rest of the application
functional.
- Add functionality to attempt to recover from an error without a full page
reload.
Create error UI by adding an `error.js` file inside a route segment and exporting
a React component:
<Image
alt="error.js special file"
srcLight="/docs/light/error-special-file.png"
srcDark="/docs/dark/error-special-file.png"
width="1600"
height="606"
/>
return (
<div>
<h2>Something went wrong!</h2>
<button
onClick={
// Attempt to recover by trying to re-render the segment
() => reset()
}
>
Try again
</button>
</div>
)
}
```
<Image
alt="How error.js works"
srcLight="/docs/light/error-overview.png"
srcDark="/docs/dark/error-overview.png"
width="1600"
height="903"
/>
An error component can use the `reset()` function to prompt the user to
attempt to recover from the error. When executed, the function will try to re-
render the Error boundary's contents. If successful, the fallback error
component is replaced with the result of the re-render.
```tsx filename="app/dashboard/error.tsx" switcher
'use client'
For example, a nested route with two segments that both include `layout.js`
and `error.js` files are rendered in the following _simplified_ component
hierarchy:
<Image
alt="Nested Error Component Hierarchy"
srcLight="/docs/light/nested-error-component-hierarchy.png"
srcDark="/docs/dark/nested-error-component-hierarchy.png"
width="1600"
height="687"
/>
The nested component hierarchy has implications for the behavior of `error.js`
files across a nested route:
To handle errors within the root layout or template, use a variation of `error.js`
called `global-error.js`.
The root `app/error.js` boundary does **not** catch errors thrown in the root
`app/layout.js` or `app/template.js` component.
Unlike the root `error.js`, the `global-error.js` error boundary wraps the
**entire** application, and its fallback component replaces the root layout when
active. Because of this, it is important to note that `global-error.js` **must**
define its own `<html>` and `<body>` tags.
The `message` property contains a generic message about the error and the
`digest` property contains an automatically generated hash of the error that
can be used to match the corresponding error in server-side logs.
During development, the `Error` object forwarded to the client will be serialized
and include the `message` of the original error for easier debugging.
---
title: Parallel Routes
description: Simultaneously render one or more pages in the same view that
can be navigated independently. A pattern for highly dynamic applications.
---
For example, you can simultaneously render the team and analytics pages.
<Image
alt="Parallel Routes Diagram"
srcLight="/docs/light/parallel-routes.png"
srcDark="/docs/dark/parallel-routes.png"
width="1600"
height="952"
/>
Parallel Routing allows you to define independent error and loading states for
each route as they're being streamed in independently.
<Image
alt="Parallel routes enable custom error and loading states"
srcLight="/docs/light/parallel-routes-cinematic-universe.png"
srcDark="/docs/dark/parallel-routes-cinematic-universe.png"
width="1600"
height="1218"
/>
Parallel Routing also allows you to conditionally render a slot based on certain
conditions, such as authentication state. This enables fully separated code on
the same URL.
<Image
alt="Conditional routes diagram"
srcLight="/docs/light/conditional-routes-ui.png"
srcDark="/docs/dark/conditional-routes-ui.png"
width="1600"
height="898"
/>
## Convention
Parallel routes are created using named **slots**. Slots are defined with the
`@folder` convention, and are passed to the same-level layout as props.
> Slots are _not_ route segments and _do not affect the URL structure_. The
file path `/@team/members` would be accessible at `/members`.
For example, the following file structure defines two explicit slots: `@analytics`
and `@team`.
<Image
alt="Parallel Routes File-system Structure"
srcLight="/docs/light/parallel-routes-file-system.png"
srcDark="/docs/dark/parallel-routes-file-system.png"
width="1600"
height="687"
/>
The folder structure above means that the component in `app/layout.js` now
accepts the `@analytics` and `@team` slots props, and can render them in
parallel alongside the `children` prop:
> **Good to know**: The `children` prop is an implicit slot that does not need
to be mapped to a folder. This means `app/page.js` is equivalent to `app/
@children/page.js`.
## Unmatched Routes
By default, the content rendered within a slot will match the current URL.
In the case of an unmatched slot, the content that Next.js renders differs based
on the routing technique and folder structure.
### `default.js`
You can define a `default.js` file to render as a fallback when Next.js cannot
recover a slot's active state based on the current URL.
Consider the following folder structure. The `@team` slot has a `settings`
directory, but `@analytics` does not.
<Image
alt="Parallel Routes unmatched routes"
srcLight="/docs/light/parallel-routes-unmatched-routes.png"
srcDark="/docs/dark/parallel-routes-unmatched-routes.png"
width="1600"
height="930"
/>
#### Navigation
On navigation, Next.js will render the slot's previously active state, even if it
doesn't match the current URL.
#### Reload
On reload, Next.js will first try to render the unmatched slot's `default.js` file. If
that's not available, a 404 gets rendered.
> The 404 for unmatched routes helps ensure that you don't accidentally
render a route that shouldn't be parallel rendered.
## `useSelectedLayoutSegment(s)`
Both [`useSelectedLayoutSegment`](/docs/app/api-reference/functions/use-
selected-layout-segment) and [`useSelectedLayoutSegments`](/docs/app/api-
reference/functions/use-selected-layout-segments) accept a
`parallelRoutesKey`, which allows you to read the active route segment within
that slot.
## Examples
### Modals
<Image
alt="Parallel Routes Diagram"
srcLight="/docs/light/parallel-routes-auth-modal.png"
srcDark="/docs/dark/parallel-routes-auth-modal.png"
width="1600"
height="687"
/>
To ensure that the contents of the modal don't get rendered when it's not
active, you can create a `default.js` file that returns `null`.
If a modal was initiated through client navigation, e.g. by using `<Link href="/
login">`, you can dismiss the modal by calling `router.back()` or by using a
`Link` component.
If you want to navigate elsewhere and dismiss a modal, you can also use a
catch-all route.
<Image
alt="Parallel Routes Diagram"
srcLight="/docs/light/parallel-routes-catchall.png"
srcDark="/docs/dark/parallel-routes-catchall.png"
width="1600"
height="768"
/>
Parallel Routes can be used to implement conditional routing. For example, you
can render a `@dashboard` or `@login` route depending on the authentication
state.
<Image
alt="Parallel routes authentication example"
srcLight="/docs/light/conditional-routes-ui.png"
srcDark="/docs/dark/conditional-routes-ui.png"
width="1600"
height="898"
/>
---
title: Intercepting Routes
description: Use intercepting routes to load a new route within the current
layout while masking the browser URL, useful for advanced routing patterns
such as modals.
related:
title: Next Steps
description: Learn how to use modals with Intercepted and Parallel Routes.
links:
- app/building-your-application/routing/parallel-routes
---
Intercepting routes allows you to load a route from another part of your
application within the current layout. This routing paradigm can be useful when
you want to display the content of a route without the user switching to a
different context.
For example, when clicking on a photo in a feed, you can display the photo in a
modal, overlaying the feed. In this case, Next.js intercepts the `/photo/123`
route, masks the URL, and overlays it over `/feed`.
<Image
alt="Intercepting routes soft navigation"
srcLight="/docs/light/intercepting-routes-soft-navigate.png"
srcDark="/docs/dark/intercepting-routes-soft-navigate.png"
width="1600"
height="617"
/>
<Image
alt="Intercepting routes hard navigation"
srcLight="/docs/light/intercepting-routes-hard-navigate.png"
srcDark="/docs/dark/intercepting-routes-hard-navigate.png"
width="1600"
height="604"
/>
## Convention
Intercepting routes can be defined with the `(..)` convention, which is similar to
relative path convention `../` but for segments.
You can use:
For example, you can intercept the `photo` segment from within the `feed`
segment by creating a `(..)photo` directory.
<Image
alt="Intercepting routes folder structure"
srcLight="/docs/light/intercepted-routes-files.png"
srcDark="/docs/dark/intercepted-routes-files.png"
width="1600"
height="604"
/>
> Note that the `(..)` convention is based on _route segments_, not the file-
system.
## Examples
### Modals
Using this pattern to create modals overcomes some common challenges when
working with modals, by allowing you to:
<Image
alt="Intercepting routes modal example"
srcLight="/docs/light/intercepted-routes-modal-example.png"
srcDark="/docs/dark/intercepted-routes-modal-example.png"
width="1600"
height="976"
/>
> In the above example, the path to the `photo` segment can use the `(..)`
matcher since `@modal` is a _slot_ and not a _segment_. This means that the
`photo` route is only one _segment_ level higher, despite being two _file-
system_ levels higher.
Other examples could include opening a login modal in a top navbar while also
having a dedicated `/login` page, or opening a shopping cart in a side modal.
---
title: Route Handlers
description: Create custom request handlers for a given route using the Web's
Request and Response APIs.
related:
title: API Reference
description: Learn more about the route.js file.
links:
- app/api-reference/file-conventions/route
---
Route Handlers allow you to create custom request handlers for a given route
using the Web [Request](https://developer.mozilla.org/docs/Web/API/Request)
and [Response](https://developer.mozilla.org/docs/Web/API/Response) APIs.
<Image
alt="Route.js Special File"
srcLight="/docs/light/route-special-file.png"
srcDark="/docs/dark/route-special-file.png"
width="1600"
height="444"
/>
> **Good to know**: Route Handlers are only available inside the `app`
directory. They are the equivalent of [API Routes](/docs/pages/building-your-
application/routing/api-routes) inside the `pages` directory meaning you **do
not** need to use API Routes and Route Handlers together.
## Convention
Route Handlers can be nested inside the `app` directory, similar to `page.js`
and `layout.js`. But there **cannot** be a `route.js` file at the same route
segment level as `page.js`.
## Behavior
### Caching
Route Handlers are cached by default when using the `GET` method with the
`Response` object.
For example:
Similarly, the `POST` method will cause the Route Handler to be evaluated
dynamically.
return Response.json(data)
}
```
return Response.json(data)
}
```
> **Good to know**: Like API Routes, Route Handlers can be used for cases like
handling form submissions. A new abstraction for [handling forms and
mutations](/docs/app/building-your-application/data-fetching/forms-and-
mutations) that integrates deeply with React is being worked on.
Each `route.js` or `page.js` file takes over all HTTP verbs for that route.
```jsx filename="app/page.js"
export default function Page() {
return <h1>Hello, Next.js!</h1>
}
// Conflict
// `app/route.js`
export async function POST(request) {}
```
## Examples
The following examples show how to combine Route Handlers with other
Next.js APIs and features.
return Response.json(data)
}
```
return Response.json(data)
}
```
```ts
export const revalidate = 60
```
Route Handlers can be used with dynamic functions from Next.js, like
[`cookies`](/docs/app/api-reference/functions/cookies) and [`headers`](/docs/
app/api-reference/functions/headers).
#### Cookies
This `cookies` instance is read-only. To set cookies, you need to return a new
`Response` using the [`Set-Cookie`](https://developer.mozilla.org/docs/Web/
HTTP/Headers/Set-Cookie) header.
```ts filename="app/api/route.ts" switcher
import { cookies } from 'next/headers'
Alternatively, you can use abstractions on top of the underlying Web APIs to
read cookies ([`NextRequest`](/docs/app/api-reference/functions/next-
request)):
This `headers` instance is read-only. To set headers, you need to return a new
`Response` with new `headers`.
Alternatively, you can use abstractions on top of the underlying Web APIs to
read headers ([`NextRequest`](/docs/app/api-reference/functions/next-
request)):
### Redirects
### Streaming
These abstractions use the Web APIs to create a stream. You can also use the
underlying Web APIs directly.
if (done) {
controller.close()
} else {
controller.enqueue(value)
}
},
})
}
function sleep(time) {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}
You can read the `Request` body using the standard Web API methods:
Since `formData` data are all strings, you may want to use [`zod-form-data`]
(https://www.npmjs.com/zod-form-data) to validate the request and retrieve
data in the format you prefer (e.g. `number`).
### CORS
You can set CORS headers on a `Response` using the standard Web API
methods:
Route Handlers have an isomorphic Web API to support both Edge and Node.js
runtimes seamlessly, including support for streaming. Since Route Handlers use
the same [route segment configuration](/docs/app/api-reference/file-
conventions/route-segment-config) as Pages and Layouts, they support long-
awaited features like general-purpose [statically regenerated](/docs/app/
building-your-application/data-fetching/fetching-caching-and-
revalidating#revalidating-data) Route Handlers.
You can use the `runtime` segment config option to specify the runtime:
```ts
export const runtime = 'edge' // 'nodejs' is the default
```
You can use Route Handlers to return non-UI content. Note that
[`sitemap.xml`](/docs/app/api-reference/file-conventions/metadata/
sitemap#generate-a-sitemap), [`robots.txt`](/docs/app/api-reference/file-
conventions/metadata/robots#generate-a-robots-file), [`app icons`](/docs/
app/api-reference/file-conventions/metadata/app-icons#generate-icons-using-
code-js-ts-tsx), and [open graph images](/docs/app/api-reference/file-
conventions/metadata/opengraph-image) all have built-in support.
<channel>
<title>Next.js Documentation</title>
<link>https://nextjs.org/docs</link>
<description>The React Framework for the Web</description>
</channel>
</rss>`)
}
```
<channel>
<title>Next.js Documentation</title>
<link>https://nextjs.org/docs</link>
<description>The React Framework for the Web</description>
</channel>
</rss>`)
}
```
---
title: Middleware
description: Learn how to use Middleware to run code before a request is
completed.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Middleware allows you to run code before a request is completed. Then, based
on the incoming request, you can modify the response by rewriting, redirecting,
modifying the request or response headers, or responding directly.
Middleware runs before cached content and routes are matched. See [Matching
Paths](#matching-paths) for more details.
## Convention
Use the file `middleware.ts` (or `.js`) in the root of your project to define
Middleware. For example, at the same level as `pages` or `app`, or inside `src`
if applicable.
## Example
## Matching Paths
Middleware will be invoked for **every route in your project**. The following
is the execution order:
There are two ways to define which paths Middleware will run on:
### Matcher
```js filename="middleware.js"
export const config = {
matcher: '/about/:path*',
}
```
You can match a single path or multiple paths with an array syntax:
```js filename="middleware.js"
export const config = {
matcher: ['/about/:path*', '/dashboard/:path*'],
}
```
The `matcher` config allows full regex so matching like negative lookaheads or
character matching is supported. An example of a negative lookahead to match
all except specific paths can be seen here:
```js filename="middleware.js"
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
}
```
> **Good to know**: The `matcher` values need to be constants so they can
be statically analyzed at build-time. Dynamic values such as variables will be
ignored.
Configured matchers:
if (request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.rewrite(new URL('/dashboard/user', request.url))
}
}
```
if (request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.rewrite(new URL('/dashboard/user', request.url))
}
}
```
## NextResponse
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
## Using Cookies
Cookies are regular headers. On a `Request`, they are stored in the `Cookie`
header. On a `Response` they are in the `Set-Cookie` header. Next.js provides
a convenient way to access and manipulate these cookies through the
`cookies` extension on `NextRequest` and `NextResponse`.
1. For incoming requests, `cookies` comes with the following methods: `get`,
`getAll`, `set`, and `delete` cookies. You can check for the existence of a
cookie with `has` or remove all cookies with `clear`.
2. For outgoing responses, `cookies` have the following methods `get`,
`getAll`, `set`, and `delete`.
return response
}
```
return response
}
```
## Setting Headers
You can set request and response headers using the `NextResponse` API
(setting _request_ headers is available since Next.js v13.0.0).
> **Good to know**: Avoid setting large headers as it might cause [431
Request Header Fields Too Large](https://developer.mozilla.org/docs/Web/
HTTP/Status/431) error depending on your backend web server configuration.
## Producing a Response
```js filename="next.config.js"
module.exports = {
skipTrailingSlashRedirect: true,
}
```
```js filename="middleware.js"
const legacyPrefixes = ['/docs', '/blog']
```js filename="next.config.js"
module.exports = {
skipMiddlewareUrlNormalize: true,
}
```
```js filename="middleware.js"
export default async function middleware(req) {
const { pathname } = req.nextUrl
// GET /_next/data/build-id/hello.json
console.log(pathname)
// with the flag this now /_next/data/build-id/hello.json
// without the flag this would be normalized to /hello
}
```
## Runtime
## Version History
| Version | Changes |
| --------- |
-------------------------------------------------------------------------------
-------------- |
| `v13.1.0` | Advanced Middleware flags added
|
| `v13.0.0` | Middleware can modify request headers, response headers, and
send responses |
| `v12.2.0` | Middleware is stable, please see the [upgrade guide](/docs/
messages/middleware-upgrade-guide) |
| `v12.0.9` | Enforce absolute URLs in Edge Runtime ([PR](https://github.com/
vercel/next.js/pull/33410)) |
| `v12.0.0` | Middleware (Beta) added
|
---
title: Project Organization and File Colocation
nav_title: Project Organization
description: Learn how to organize your Next.js project and colocate files.
related:
links:
- app/building-your-application/routing/defining-routes
- app/building-your-application/routing/route-groups
- app/building-your-application/configuring/src-directory
- app/building-your-application/configuring/absolute-imports-and-module-
aliases
---
This page shares default behavior and features you can use to organize your
project.
<Image
alt="A diagram showing how a route is not publicly accessible until a page.js
or route.js file is added to a route segment."
srcLight="/docs/light/project-organization-not-routable.png"
srcDark="/docs/dark/project-organization-not-routable.png"
width="1600"
height="444"
/>
And, even when a route is made publicly accessible, only the **content
returned** by `page.js` or `route.js` is sent to the client.
<Image
alt="A diagram showing how page.js and route.js files make routes publicly
accessible."
srcLight="/docs/light/project-organization-routable.png"
srcDark="/docs/dark/project-organization-routable.png"
width="1600"
height="687"
/>
This means that **project files** can be **safely colocated** inside route
segments in the `app` directory without accidentally being routable.
<Image
alt="A diagram showing colocated project files are not routable even when a
segment contains a page.js or route.js file."
srcLight="/docs/light/project-organization-colocation.png"
srcDark="/docs/dark/project-organization-colocation.png"
width="1600"
height="1011"
/>
<Image
alt="An example folder structure using private folders"
srcLight="/docs/light/project-organization-private-folders.png"
srcDark="/docs/dark/project-organization-private-folders.png"
width="1600"
height="849"
/>
This indicates the folder is for organizational purposes and should **not be
included** in the route's URL path.
<Image
alt="An example folder structure using route groups"
srcLight="/docs/light/project-organization-route-groups.png"
srcDark="/docs/dark/project-organization-route-groups.png"
width="1600"
height="849"
/>
<Image
alt="An example folder structure with the `src` directory"
srcLight="/docs/light/project-organization-src-directory.png"
srcDark="/docs/dark/project-organization-src-directory.png"
width="1600"
height="687"
/>
```jsx filename="app/dashboard/settings/analytics/page.js"
// before
import { Button } from '../../../components/button'
// after
import { Button } from '@/components/button'
```
> **Good to know**: In our examples below, we're using `components` and
`lib` folders as generalized placeholders, their naming has no special
framework significance and your projects might use other folders like `ui`,
`utils`, `hooks`, `styles`, etc.
This strategy stores all application code in shared folders in the **root of your
project** and keeps the `app` directory purely for routing purposes.
<Image
alt="An example folder structure with project files outside of app"
srcLight="/docs/light/project-organization-project-root.png"
srcDark="/docs/dark/project-organization-project-root.png"
width="1600"
height="849"
/>
This strategy stores all application code in shared folders in the **root of the
`app` directory**.
<Image
alt="An example folder structure with project files inside app"
srcLight="/docs/light/project-organization-app-root.png"
srcDark="/docs/dark/project-organization-app-root.png"
width="1600"
height="849"
/>
This strategy stores globally shared application code in the root `app` directory
and **splits** more specific application code into the route segments that use
them.
<Image
alt="An example folder structure with project files split by feature or route"
srcLight="/docs/light/project-organization-app-root-split.png"
srcDark="/docs/dark/project-organization-app-root-split.png"
width="1600"
height="1011"
/>
---
title: Internationalization
description: Add support for multiple languages with internationalized routing
and localized content.
---
## Terminology
## Routing Overview
For example, using the following libraries, you can look at an incoming
`Request` to determine which locale to select, based on the `Headers`, locales
you plan to support, and the default locale.
```js filename="middleware.js"
import { match } from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
```js filename="middleware.js"
if (pathnameHasLocale) return
Finally, ensure all special files inside `app/` are nested under `app/[lang]`. This
enables the Next.js router to dynamically handle different locales in the route,
and forward the `lang` parameter to every layout and page. For example:
```jsx filename="app/[lang]/page.js"
// You now have access to the current locale
// e.g. /en-US/products -> `lang` is "en-US"
export default async function Page({ params: { lang } }) {
return ...
}
```
The root layout can also be nested in the new folder (e.g. `app/[lang]/
layout.js`).
## Localization
Let’s assume we want to support both English and Dutch content inside our
application. We might maintain two different “dictionaries”, which are objects
that give us a mapping from some key to a localized string. For example:
```json filename="dictionaries/en.json"
{
"products": {
"cart": "Add to Cart"
}
}
```
```json filename="dictionaries/nl.json"
{
"products": {
"cart": "Toevoegen aan Winkelwagen"
}
}
```
We can then create a `getDictionary` function to load the translations for the
requested locale:
```jsx filename="app/[lang]/dictionaries.js"
import 'server-only'
const dictionaries = {
en: () => import('./dictionaries/en.json').then((module) => module.default),
nl: () => import('./dictionaries/nl.json').then((module) => module.default),
}
```jsx filename="app/[lang]/page.js"
import { getDictionary } from './dictionaries'
Because all layouts and pages in the `app/` directory default to [Server
Components](/docs/app/building-your-application/rendering/server-
components), we do not need to worry about the size of the translation files
affecting our client-side JavaScript bundle size. This code will **only run on
the server**, and only the resulting HTML will be sent to the browser.
## Static Generation
```jsx filename="app/[lang]/layout.js"
export async function generateStaticParams() {
return [{ lang: 'en-US' }, { lang: 'de' }]
}
## Resources
Data fetching is a core part of any application. This page goes through how you
can fetch, cache, and revalidate data in React and Next.js.
For example:
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data')
}
return res.json()
}
return <main></main>
}
```
if (!res.ok) {
// This will activate the closest `error.js` Error Boundary
throw new Error('Failed to fetch data')
}
return res.json()
}
return <main></main>
}
```
Caching stores data so it doesn't need to be re-fetched from your data source
on every request.
By default, Next.js automatically caches the returned values of `fetch` in the
[Data Cache](/docs/app/building-your-application/caching#data-cache) on the
server. This means that the data can be fetched at build time or request time,
cached, and reused on each data request.
```js
// 'force-cache' is the default, and can be omitted
fetch('https://...', { cache: 'force-cache' })
```
`fetch` requests that use the `POST` method are also automatically cached.
Unless it's inside a [Route Handler](/docs/app/building-your-application/
routing/route-handlers) that uses the `POST` method, then it will not be
cached.
Revalidation is the process of purging the Data Cache and re-fetching the latest
data. This is useful when your data changes and you want to ensure you show
the latest information.
To revalidate data at a timed interval, you can use the `next.revalidate` option
of `fetch` to set the cache lifetime of a resource (in seconds).
```js
fetch('https://...', { next: { revalidate: 3600 } })
```
Alternatively, to revalidate all `fetch` requests in a route segment, you can use
the [Segment Config Options](/docs/app/api-reference/file-conventions/route-
segment-config).
If you have multiple fetch requests in a statically rendered route, and each has
a different revalidation frequency. The lowest time will be used for all requests.
For dynamically rendered routes, each `fetch` request will be revalidated
independently.
Next.js has a cache tagging system for invalidating `fetch` requests across
routes.
1. When using `fetch`, you have the option to tag cache entries with one or
more tags.
2. Then, you can call `revalidateTag` to revalidate all entries associated with
that tag.
For example, the following `fetch` request adds the cache tag `collection`:
You can then revalidate this `fetch` call tagged with `collection` by calling
`revalidateTag` in a Server Action:
To opt out of caching for individual `fetch` requests, you can set the `cache`
option in `fetch` to `'no-store'`. This will fetch data dynamically, on every
request.
View all the available `cache` options in the [`fetch` API reference](/docs/app/
api-reference/functions/fetch).
If you have multiple `fetch` requests in a route segment (e.g. a Layout or Page),
you can configure the caching behavior of all data requests in the segment
using the [Segment Config Options](/docs/app/api-reference/file-conventions/
route-segment-config).
In cases where you're using a third-party library that doesn't support or expose
`fetch` (for example, a database, CMS, or ORM client), you can configure the
caching and revalidating behavior of those requests using the [Route Segment
Config Option](/docs/app/api-reference/file-conventions/route-segment-
config) and React's `cache` function.
Whether the data is cached or not will depend on whether the route segment is
[statically or dynamically rendered](/docs/app/building-your-application/
rendering/server-components#server-rendering-strategies). If the segment is
static (default), the output of the request will be cached and revalidated as part
of the route segment. If the segment is dynamic, the output of the request will
_not_ be cached and will be re-fetched on every request when the segment is
rendered.
You can also use the experimental [`unstable_cache` API](/docs/app/api-
reference/functions/unstable_cache).
### Example
Although the `getItem` function is called twice, only one query will be made to
the database.
export const revalidate = 3600 // revalidate the data at most every hour
export const revalidate = 3600 // revalidate the data at most every hour
export const revalidate = 3600 // revalidate the data at most every hour
export const revalidate = 3600 // revalidate the data at most every hour
If you need to fetch data in a client component, you can call a [Route Handler](/
docs/app/building-your-application/routing/route-handlers) from the client.
Route Handlers execute on the server and return the data to the client. This is
useful when you don't want to expose sensitive information to the client, such
as API tokens.
See the [Route Handler](/docs/app/building-your-application/routing/route-
handlers) documentation for examples.
You can also fetch data on the client using a third-party library such as [SWR]
(https://swr.vercel.app/) or [React Query](https://tanstack.com/query/latest).
These libraries provide their own APIs for memoizing requests, caching,
revalidating, and mutating data.
---
title: Data Fetching Patterns
description: Learn about common data fetching patterns in React and Next.js.
---
There are a few recommended patterns and best practices for fetching data in
React and Next.js. This page will go over some of the most common patterns
and how to use them.
Whenever possible, we recommend fetching data on the server. This allows you
to:
You can fetch data on the server using Server Components, [Route Handlers](/
docs/app/building-your-application/routing/route-handlers), and [Server
Actions](/docs/app/building-your-application/data-fetching/forms-and-
mutations).
If you need to use the same data (e.g. current user) in multiple components in a
tree, you do not have to fetch data globally, nor forward props between
components. Instead, you can use `fetch` or React `cache` in the component
that needs the data without worrying about the performance implications of
making multiple requests for the same data.
> **Good to know**: This also applies to layouts, since it's not possible to pass
data between a parent layout and its children.
### Streaming
<Image
alt="Server Rendering with Streaming"
srcLight="/docs/light/server-rendering-with-streaming.png"
srcDark="/docs/dark/server-rendering-with-streaming.png"
width="1600"
height="785"
/>
To learn more about Streaming and Suspense, see the [Loading UI](/docs/app/
building-your-application/routing/loading-ui-and-streaming) and [Streaming
and Suspense](/docs/app/building-your-application/routing/loading-ui-and-
streaming#streaming-with-suspense) pages.
When fetching data inside React components, you need to be aware of two
data fetching patterns: Parallel and Sequential.
<Image
alt="Sequential and Parallel Data Fetching"
srcLight="/docs/light/sequential-parallel-data-fetching.png"
srcDark="/docs/dark/sequential-parallel-data-fetching.png"
width="1600"
height="525"
/>
If you have nested components, and each component fetches its own data,
then data fetching will happen sequentially if those data requests are different
(this doesn't apply to requests for the same data as they are automatically
[memoized](/docs/app/building-your-application/caching#request-
memoization)).
For example, the `Playlists` component will only start fetching data once the
`Artist` component has finished fetching data because `Playlists` depends on
the `artistID` prop:
return (
<ul>
{playlists.map((playlist) => (
<li key={playlist.id}>{playlist.name}</li>
))}
</ul>
)
}
return (
<>
<h1>{artist.name}</h1>
<Suspense fallback={<div>Loading...</div>}>
<Playlists artistID={artist.id} />
</Suspense>
</>
)
}
```
return (
<ul>
{playlists.map((playlist) => (
<li key={playlist.id}>{playlist.name}</li>
))}
</ul>
)
}
return (
<>
<h1>{artist.name}</h1>
<Suspense fallback={<div>Loading...</div>}>
<Playlists artistID={artist.id} />
</Suspense>
</>
)
}
```
This will prevent the whole route from being blocked by data fetching, and the
user will be able to interact with the parts of the page that are not blocked.
To fetch data in parallel, you can eagerly initiate requests by defining them
outside the components that use the data, then calling them from inside the
component. This saves time by initiating both requests in parallel, however, the
user won't see the rendered result until both promises are resolved.
return (
<>
<h1>{artist.name}</h1>
<Albums list={albums}></Albums>
</>
)
}
```
return (
<>
<h1>{artist.name}</h1>
<Albums list={albums}></Albums>
</>
)
}
```
Another way to prevent waterfalls is to use the preload pattern. You can
optionally create a `preload` function to further optimize parallel data fetching.
With this approach, you don't have to pass promises down as props. The
`preload` function can also have any name as it's a pattern, not an API.
You can combine the `cache` function, the `preload` pattern, and the `server-
only` package to create a data fetching utility that can be used throughout your
app.
With this approach, you can eagerly fetch data, cache responses, and
guarantee that this data fetching [only happens on the server](/docs/app/
building-your-application/rendering/composition-patterns#keeping-server-
only-code-out-of-the-client-environment).
---
title: Forms and Mutations
nav_title: Forms and Mutations
description: Learn how to handle form submissions and data mutations with
Next.js.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<PagesOnly>
Forms enable you to create and update data in web applications. Next.js
provides a powerful way to handle form submissions and data mutations using
**API Routes**.
</PagesOnly>
<AppOnly>
Forms enable you to create and update data in web applications. Next.js
provides a powerful way to handle form submissions and data mutations using
**Server Actions**.
<details>
<summary>Examples</summary>
</details>
With Server Actions, you don't need to manually create API endpoints. Instead,
you define asynchronous server functions that can be called directly from your
components.
> ** Watch:** Learn more about forms and mutations with the App Router →
[YouTube (10 minutes)](https://youtu.be/dDpZfOQBMaU?
si=cJZHlUu_jFhCzHUg).
Server Actions integrate deeply with the Next.js [caching and revalidation](/
docs/app/building-your-application/caching) architecture. When a form is
submitted, the Server Action can update cached data and revalidate any cache
keys that should change.
Rather than being limited to a single form per route like traditional applications,
Server Actions enable having multiple actions per route. Further, the browser
does not need to refresh on form submission. In a single network roundtrip,
Next.js can return both the updated UI and the refreshed data.
View the examples below for [revalidating data from Server Actions]
(#revalidating-data).
</AppOnly>
## Examples
<PagesOnly>
With the Pages Router, you need to manually create API endpoints to handle
securely mutating data on the server.
Then, call the API Route from the client with an event handler:
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()
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit">Submit</button>
</form>
)
}
```
</PagesOnly>
<AppOnly>
// mutate data
// revalidate cache
}
// mutate data
// revalidate cache
}
</AppOnly>
### Redirecting
<PagesOnly>
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:
</PagesOnly>
<AppOnly>
If you would like to redirect the user to a different route after the completion of
a Server Action, you can use [`redirect`](/docs/app/api-reference/functions/
redirect) and any absolute or relative URL:
</AppOnly>
For more advanced server-side validation, use a schema validation library like
[zod](https://zod.dev/) to validate the structure of the parsed form data:
<PagesOnly>
</PagesOnly>
<AppOnly>
</AppOnly>
<AppOnly>
return (
<button type="submit" aria-disabled={pending}>
Add
</button>
)
}
```
</AppOnly>
<PagesOnly>
You can use React state to show a loading state when a form is submitting on
the server:
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
)
}
```
try {
const formData = new FormData(event.currentTarget)
const response = await fetch('/api/submit', {
method: 'POST',
body: formData,
})
return (
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
)
}
```
</PagesOnly>
Then, from a Client Component, you can read this value and display an error
message.
const initialState = {
message: null,
}
function SubmitButton() {
const { pending } = useFormStatus()
return (
<button type="submit" aria-disabled={pending}>
Add
</button>
)
}
return (
<form action={formAction}>
<label htmlFor="todo">Enter Task</label>
<input type="text" id="todo" name="todo" required />
<SubmitButton />
<p aria-live="polite" className="sr-only">
{state?.message}
</p>
</form>
)
}
```
const initialState = {
message: null,
}
function SubmitButton() {
const { pending } = useFormStatus()
return (
<button type="submit" aria-disabled={pending}>
Add
</button>
)
}
</AppOnly>
<PagesOnly>
You can use React state to show an error message when a form submission
fails:
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.')
}
return (
<div>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
</div>
)
}
```
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.')
}
return (
<div>
{error && <div style={{ color: 'red' }}>{error}</div>}
<form onSubmit={onSubmit}>
<input type="text" name="name" />
<button type="submit" disabled={isLoading}>
{isLoading ? 'Loading...' : 'Submit'}
</button>
</form>
</div>
)
}
```
</PagesOnly>
<AppOnly>
Use [`useOptimistic`](https://react.dev/reference/react/useOptimistic) to
optimistically update the UI before the Server Action finishes, rather than
waiting for the response:
type Message = {
message: string
}
return (
<div>
{optimisticMessages.map((m, k) => (
<div key={k}>{m.message}</div>
))}
<form
action={async (formData: FormData) => {
const message = formData.get('message')
addOptimisticMessage(message)
await send(message)
}}
>
<input type="text" name="message" />
<button type="submit">Send</button>
</form>
</div>
)
}
```
return (
<div>
{optimisticMessages.map((m) => (
<div>{m.message}</div>
))}
<form
action={async (formData) => {
const message = formData.get('message')
addOptimisticMessage(message)
await send(message)
}}
>
<input type="text" name="message" />
<button type="submit">Send</button>
</form>
</div>
)
}
```
</AppOnly>
<PagesOnly>
You can set cookies inside an API Route using the `setHeader` method on the
response:
</PagesOnly>
<AppOnly>
You can set cookies inside a Server Action using the [`cookies`](/docs/app/api-
reference/functions/cookies) function:
```ts filename="app/actions.ts" switcher
'use server'
</AppOnly>
<PagesOnly>
You can read cookies inside an API Route using the [`cookies`](/docs/pages/
building-your-application/routing/api-routes#request-helpers) request helper:
</PagesOnly>
<AppOnly>
You can read cookies inside a Server Action using the [`cookies`](/docs/app/
api-reference/functions/cookies) function:
</AppOnly>
<PagesOnly>
You can delete cookies inside an API Route using the `setHeader` method on
the response:
</PagesOnly>
<AppOnly>
You can delete cookies inside a Server Action using the [`cookies`](/docs/app/
api-reference/functions/cookies) function:
</AppOnly>
---
title: Server Components
description: Learn how you can use React Server Components to render parts
of your application on the server.
related:
description: Learn how Next.js caches data and the result of static rendering.
links:
- app/building-your-application/caching
---
React Server Components allow you to write UI that can be rendered and
optionally cached on the server. In Next.js, the rendering work is further split by
route segments to enable streaming and partial rendering, and there are three
different server rendering strategies:
- [Static Rendering](#static-rendering-default)
- [Dynamic Rendering](#dynamic-rendering)
- [Streaming](#streaming)
This page will go through how Server Components work, when you might use
them, and the different server rendering strategies.
There are a couple of benefits to doing the rendering work on the server,
including:
1. React renders Server Components into a special data format called the
**React Server Component Payload (RSC Payload)**.
2. Next.js uses the RSC Payload and Client Component JavaScript instructions
to render **HTML** on the server.
There are three subsets of server rendering: Static, Dynamic, and Streaming.
Static rendering is useful when a route has data that is not personalized to the
user and can be known at build time, such as a static blog post or a product
page.
With Dynamic Rendering, routes are rendered for each user at **request
time**.
Dynamic rendering is useful when a route has data that is personalized to the
user or has information that can only be known at request time, such as cookies
or the URL's search params.
In the table above, for a route to be fully static, all data must be cached.
However, you can have a dynamically rendered route that uses both cached
and uncached data fetches.
Dynamic functions rely on information that can only be known at request time
such as a user's cookies, current requests headers, or the URL's search
params. In Next.js, these dynamic functions are:
- **[`cookies()`](/docs/app/api-reference/functions/cookies) and
[`headers()`](/docs/app/api-reference/functions/headers)**: Using these in
a Server Component will opt the whole route into dynamic rendering at request
time.
- **[`useSearchParams()`](/docs/app/api-reference/functions/use-
search-params)**:
- In Client Components, it'll skip static rendering and instead render all Client
Components up to the nearest parent Suspense boundary on the client.
- We recommend wrapping the Client Component that uses
`useSearchParams()` in a `<Suspense/>` boundary. This will allow any Client
Components above it to be statically rendered. [Example](/docs/app/api-
reference/functions/use-search-params#static-rendering).
- **[`searchParams`](/docs/app/api-reference/file-conventions/
page#searchparams-optional)**: Using the [Pages](/docs/app/api-reference/
file-conventions/page) prop will opt the page into dynamic rendering at request
time.
Using any of these functions will opt the whole route into dynamic rendering at
request time.
### Streaming
<Image
alt="Diagram showing parallelization of route segments during streaming,
showing data fetching, rendering, and hydration of invidiual chunks."
srcLight="/docs/light/sequential-parallel-data-fetching.png"
srcDark="/docs/dark/sequential-parallel-data-fetching.png"
width="1600"
height="525"
/>
Streaming enables you to progressively render UI from the server. Work is split
into chunks and streamed to the client as it becomes ready. This allows the
user to see parts of the page immediately, before the entire content has
finished rendering.
<Image
alt="Diagram showing partially rendered page on the client, with loading UI for
chunks that are being streamed."
srcLight="/docs/light/server-rendering-with-streaming.png"
srcDark="/docs/dark/server-rendering-with-streaming.png"
width="1600"
height="785"
/>
Streaming is built into the Next.js App Router by default. This helps improve
both the initial page loading performance, as well as UI that depends on slower
data fetches that would block rendering the whole route. For example, reviews
on a product page.
You can start streaming route segments using `loading.js` and UI components
with [React Suspense](/docs/app/building-your-application/routing/loading-ui-
and-streaming). See the [Loading UI and Streaming](/docs/app/building-your-
application/routing/loading-ui-and-streaming) section for more information.
---
title: Client Components
description: Learn how to use Client Components to render parts of your
application on the client.
---
This page will go through how Client Components work, how they're rendered,
and when you might use them.
There are a couple of benefits to doing the rendering work on the client,
including:
To use Client Components, you can add the React [`"use client"` directive]
(https://react.dev/reference/react/use-client) at the top of a file, above your
imports.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
```
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
```
The diagram below shows that using `onClick` and `useState` in a nested
component (`toggle.js`) will cause an error if the `"use client"` directive is not
defined. This is because, by default, the components are rendered on the
server where these APIs are not available. By defining the `"use client"`
directive in `toggle.js`, you can tell React to render the component and its
children on the client, where the APIs are available.
<Image
alt="Use Client Directive and Network Boundary"
srcLight="/docs/light/use-client-directive.png"
srcDark="/docs/dark/use-client-directive.png"
width="1600"
height="1320"
/>
To optimize the initial page load, Next.js will use React's APIs to render a static
HTML preview on the server for both Client and Server Components. This
means, when the user first visits your application, they will see the content of
the page immediately, without having to wait for the client to download, parse,
and execute the Client Component JavaScript bundle.
On the server:
1. React renders Server Components into a special data format called the
**React Server Component Payload (RSC Payload)**, which includes references
to Client Components.
2. Next.js uses the RSC Payload and Client Component JavaScript instructions
to render **HTML** for the route on the server.
Sometimes, after you've declared the `"use client"` boundary, you may want to
go back to the server environment. For example, you may want to reduce the
client bundle size, fetch data on the server, or use an API that is only available
on the server.
You can keep code on the server even though it's theoretically nested inside
Client Components by interleaving Client and Server Components and [Server
Actions](/docs/app/building-your-application/data-fetching/forms-and-
mutations). See the [Composition Patterns](/docs/app/building-your-
application/rendering/composition-patterns) page for more information.
---
title: Server and Client Composition Patterns
nav_title: Composition Patterns
description: Recommended patterns for using Server and Client Components.
---
When building React applications, you will need to consider what parts of your
application should be rendered on the server or the client. This page covers
some recommended composition patterns when using Server and Client
Components.
Here's a quick summary of the different use cases for Server and Client
Components:
Before opting into client-side rendering, you may wish to do some work on the
server like fetching data, or accessing your database or backend services.
Here are some common patterns when working with Server Components:
When fetching data on the server, there may be cases where you need to share
data across different components. For example, you may have a layout and a
page that depend on the same data.
Since JavaScript modules can be shared between both Server and Client
Components modules, it's possible for code that was only ever intended to be
run on the server to sneak its way into the client.
return res.json()
}
```
return res.json()
}
```
At first glance, it appears that `getData` works on both the server and the
client. However, this function contains an `API_KEY`, written with the intention
that it would only ever be executed on the server.
To prevent this sort of unintended client usage of server code, we can use the
`server-only` package to give other developers a build-time error if they ever
accidentally import one of these modules into a Client Component.
```bash filename="Terminal"
npm install server-only
```
Then import the package into any module that contains server-only code:
```js filename="lib/data.js"
import 'server-only'
return res.json()
}
```
Now, any Client Component that imports `getData()` will receive a build-time
error explaining that this module can only be used on the server.
Since Server Components are a new React feature, third-party packages and
providers in the ecosystem are just beginning to add the `"use client"`
directive to components that use client-only features like `useState`,
`useEffect`, and `createContext`.
Today, many components from `npm` packages that use client-only features
do not yet have the directive. These third-party components will work as
expected within Client Components since they have the `"use client"` directive,
but they won't work within Server Components.
If you use `<Carousel />` within a Client Component, it will work as expected:
return (
<div>
<button onClick={() => setIsOpen(true)}>View pictures</button>
return (
<div>
<button onClick={() => setIsOpen(true)}>View pictures</button>
However, if you try to use it directly within a Server Component, you'll see an
error:
{/* Error: `useState` can not be used within Server Components */}
<Carousel />
</div>
)
}
```
{/* Error: `useState` can not be used within Server Components */}
<Carousel />
</div>
)
}
```
To fix this, you can wrap third-party components that rely on client-only
features in your own Client Components:
Now, you can use `<Carousel />` directly within a Server Component:
We don't expect you to need to wrap most third-party components since it's
likely you'll be using them within Client Components. However, one exception is
providers, since they rely on React state and context, and are typically needed
at the root of an application. [Learn more about third-party context providers
below](#using-context-providers).
Context providers are typically rendered near the root of an application to share
global concerns, like the current theme. Since [React context](https://react.dev/
learn/passing-data-deeply-with-context) is not supported in Server
Components, trying to create a context at the root of your application will cause
an error:
To fix this, create your context and render its provider inside of a Client
Component:
Your Server Component will now be able to directly render your provider since
it's been marked as a Client Component:
With the provider rendered at the root, all other Client Components throughout
your app will be able to consume this context.
> **Good to know**: You should render providers as deep as possible in the
tree – notice how `ThemeProvider` only wraps `{children}` instead of the entire
`<html>` document. This makes it easier for Next.js to optimize the static parts
of your Server Components.
You can optimize your package by using ['use client' deeper in the tree]
(#moving-client-components-down-the-tree), allowing the imported modules
to be part of the Server Component module graph.
It's worth noting some bundlers might strip out `"use client"` directives. You
can find an example of how to configure esbuild to include the `"use client"`
directive in the [React Wrap Balancer](https://github.com/shuding/react-wrap-
balancer/blob/main/tsup.config.ts#L10-L13) and [Vercel Analytics](https://
github.com/vercel/analytics/blob/main/packages/web/tsup.config.js#L26-L30)
repositories.
## Client Components
For example, you may have a Layout that has static elements (e.g. logo, links,
etc) and an interactive search bar that uses state.
Instead of making the whole layout a Client Component, move the interactive
logic to a Client Component (e.g. `<SearchBar />`) and keep your layout as a
Server Component. This means you don't have to send all the component
Javascript of the layout to the client.
If you fetch data in a Server Component, you may want to pass data down as
props to Client Components. Props passed from the Server to Client
Components need to be [serializable](https://developer.mozilla.org/docs/
Glossary/Serialization) by React.
If your Client Components depend on data that is not serializable, you can
[fetch data on the client with a third party library](/docs/app/building-your-
application/data-fetching/fetching-caching-and-revalidating#fetching-data-on-
the-client-with-third-party-libraries) or on the server via a [Route Handler](/
docs/app/building-your-application/routing/route-handlers).
## Interleaving Server and Client Components
Within those client subtrees, you can still nest Server Components or call
Server Actions, however there are some things to keep in mind:
- During a request-response lifecycle, your code moves from the server to the
client. If you need to access data or resources on the server while on the client,
you'll be making a **new** request to the server - not switching back and
forth.
- When a new request is made to the server, all Server Components are
rendered first, including those nested inside Client Components. The rendered
result (RSC Payload) will contain references to the locations of Client
Components. Then, on the client, React uses the RSC Payload to reconcile
Server and Client Components into a single tree.
- Since Client Components are rendered after Server Components, you cannot
import a Server Component into a Client Component module (since it would
require a new request back to the server). Instead, you can pass a Server
Component as `props` to a Client Component. See the [unsupported pattern]
(#unsupported-pattern-importing-server-components-into-client-components)
and [supported pattern](#supported-pattern-passing-server-components-to-
client-components-as-props) sections below.
The following pattern is not supported. You cannot import a Server Component
into a Client Component:
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
<ServerComponent />
</>
)
}
```
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
<ServerComponent />
</>
)
}
```
The following pattern is supported. You can pass Server Components as a prop
to a Client Component.
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
{children}
</>
)
}
```
return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>
{children}
</>
)
}
```
---
title: Edge and Node.js Runtimes
description: Learn about the switchable runtimes (Edge and Node.js) in Next.js.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
In the context of Next.js, runtime refers to the set of libraries, APIs, and general
functionality available to your code during execution.
On the server, there are two runtimes where parts of your application code can
be rendered:
- The **Node.js Runtime** (default) has access to all Node.js APIs and
compatible packages from the ecosystem.
- The **Edge Runtime** is based on [Web APIs](/docs/app/api-reference/
edge).
## Runtime Differences
There are many considerations to make when choosing a runtime. This table
shows the major differences at a glance. If you want a more in-depth analysis of
the differences, check out the sections below.
|
| Node | Serverless | Edge |
|
-------------------------------------------------------------------------------
------------------------------------------------------ | ------ | ---------- |
---------------- |
| Cold Boot
|/ | Normal | Low |
| [HTTP Streaming](/docs/app/building-your-application/routing/loading-ui-
and-streaming) | Yes | Yes | Yes |
| IO
| All | All | `fetch` |
| Scalability
|/ | High | Highest |
| Security
| Normal | High | High |
| Latency
| Normal | Low | Lowest |
| npm Packages
| All | All | A smaller subset |
| [Static Rendering](/docs/app/building-your-application/rendering/server-
components#static-rendering-default) | Yes | Yes | No
|
| [Dynamic Rendering](/docs/app/building-your-application/rendering/server-
components#dynamic-rendering) | Yes | Yes | Yes
|
| [Data Revalidation w/ `fetch`](/docs/app/building-your-application/data-
fetching/fetching-caching-and-revalidating#revalidating-data) | Yes | Yes
| Yes |
The Edge Runtime is ideal if you need to deliver dynamic, personalized content
at low latency with small, simple functions. The Edge Runtime's speed comes
from its minimal use of resources, but that can be limiting in many scenarios.
For example, code executed in the Edge Runtime [on Vercel cannot exceed
between 1 MB and 4 MB](https://vercel.com/docs/concepts/limits/
overview#edge-middleware-and-edge-functions-size), this limit includes
imported packages, fonts and files, and will vary depending on your
deployment infrastructure.
Using the Node.js runtime gives you access to all Node.js APIs, and all npm
packages that rely on them. However, it's not as fast to start up as routes using
the Edge runtime.
Serverless is ideal if you need a scalable solution that can handle more complex
computational loads than the Edge Runtime. With Serverless Functions on
Vercel, for example, your overall code size is [50MB](https://vercel.com/docs/
concepts/limits/overview#serverless-function-size) including imported
packages, fonts, and files.
## Examples
You can specify a runtime for individual route segments in your Next.js
application. To do so, [declare a variable called `runtime` and export it](/docs/
app/api-reference/file-conventions/route-segment-config). The variable must
be a string, and must have a value of either `'nodejs'` or `'edge'` runtime.
You can also define `runtime` on a layout level, which will make all routes under
the layout run on the edge runtime:
If the segment runtime is _not_ set, the default `nodejs` runtime will be used.
You do not need to use the `runtime` option if you do not plan to change from
the Node.js runtime.
</AppOnly>
---
title: Rendering
description: Learn the differences between Next.js rendering environments,
strategies, and runtimes.
---
Rendering converts the code you write into user interfaces. React and Next.js
allow you to create hybrid web applications where parts of your code can be
rendered on the server or the client. This section will help you understand the
differences between these rendering environments, strategies, and runtimes.
## Fundamentals
There are two environments where web applications can be rendered: the client
and the server.
<Image
alt="Client and Server Environments"
srcLight="/docs/light/client-and-server-environments.png"
srcDark="/docs/dark/client-and-server-environments.png"
width="1600"
height="672"
/>
- The **client** refers to the browser on a user's device that sends a request to
a server for your application code. It then turns the response from the server
into a user interface.
- The **server** refers to the computer in a data center that stores your
application code, receives requests from a client, and sends back an
appropriate response.
1. **User Action:** The user interacts with a web application. This could be
clicking a link, submitting a form, or typing a URL directly into the browser's
address bar.
2. **HTTP Request:** The client sends an [HTTP](https://developer.mozilla.org/
docs/Web/HTTP) request to the server that contains necessary information
about what resources are being requested, what method is being used (e.g.
`GET`, `POST`), and additional data if necessary.
3. **Server:** The server processes the request and responds with the
appropriate resources. This process may take a couple of steps like routing,
fetching data, etc.
4. **HTTP Response:** After processing the request, the server sends an HTTP
response back to the client. This response contains a status code (which tells
the client whether the request was successful or not) and requested resources
(e.g. HTML, CSS, JavaScript, static assets, etc).
5. **Client:** The client parses the resources to render the user interface.
6. **User Action:** Once the user interface is rendered, the user can interact
with it, and the whole process starts again.
A major part of building a hybrid web application is deciding how to split the
work in the lifecycle, and where to place the Network Boundary.
Behind the scenes, the work is split into two parts: the **client module graph**
and the **server module graph**. The server module graph contains all the
components that are rendered on the server, and the client module graph
contains all components that are rendered on the client.
{/* For example, if you have a file called `Page.jsx` that imports a file called
`Button.jsx` on the server, the module graph would look something like this: -
Diagram - */}
You can use the React `"use client"` convention to define the boundary.
There's also a `"use server"` convention, which tells React to do some
computational work on the server.
When working in these environments, it's helpful to think of the flow of the
code in your application as **unidirectional**. In other words, during a
response, your application code flows in one direction: from the server to the
client.
If you need to access the server from the client, you send a **new** request to
the server rather than re-use the same request. This makes it easier to
understand where to render your components and where to place the Network
Boundary.
In practice, this model encourages developers to think about what they want to
execute on the server first, before sending the result to the client and making
the application interactive.
This concept will become clearer when we look at how you can [interleave
client and server components](/docs/app/building-your-application/rendering/
composition-patterns) in the same component tree.
---
title: Caching in Next.js
nav_title: Caching
description: An overview of caching mechanisms in Next.js.
---
Next.js improves your application's performance and reduces costs by caching
rendering work and data requests. This page provides an in-depth look at
Next.js caching mechanisms, the APIs you can use to configure them, and how
they interact with each other.
> **Good to know**: This page helps you understand how Next.js works under
the hood but is **not** essential knowledge to be productive with Next.js. Most
of Next.js' caching heuristics are determined by your API usage and have
defaults for the best performance with zero or minimal configuration.
## Overview
<Image
alt="Diagram showing the default caching behavior in Next.js for the four
mechanisms, with HIT, MISS and SET at build time and when a route is first
visited."
srcLight="/docs/light/caching-overview.png"
srcDark="/docs/dark/caching-overview.png"
width="1600"
height="1179"
/>
Caching behavior changes depending on whether the route is statically or
dynamically rendered, data is cached or uncached, and whether a request is
part of an initial visit or a subsequent navigation. Depending on your use case,
you can configure the caching behavior for individual routes and data requests.
## Request Memoization
<Image
alt="Deduplicated Fetch Requests"
srcLight="/docs/light/deduplicated-fetch-requests.png"
srcDark="/docs/dark/deduplicated-fetch-requests.png"
width="1600"
height="857"
/>
For example, if you need to use the same data across a route (e.g. in a Layout,
Page, and multiple components), you do not have to fetch data at the top of the
tree then forward props between components. Instead, you can fetch data in
the components that need it without worrying about the performance
implications of making multiple requests across the network for the same data.
// This function is called twice, but only executed the first time
const item = await getItem() // cache MISS
// This function is called twice, but only executed the first time
const item = await getItem() // cache MISS
<Image
alt="Diagram showing how fetch memoization works during React rendering."
srcLight="/docs/light/request-memoization.png"
srcDark="/docs/dark/request-memoization.png"
width="1600"
height="742"
/>
- While rendering a route, the first time a particular request is called, its result
will not be in memory and it'll be a cache `MISS`.
- Therefore, the function will be executed, and the data will be fetched from the
external source, and the result will be stored in memory.
- Subsequent function calls of the request in the same render pass will be a
cache `HIT`, and the data will be returned from memory without executing the
function.
- Once the route has been rendered and the rendering pass is complete,
memory is "reset" and all request memoization entries are cleared.
### Duration
The cache lasts the lifetime of a server request until the React component tree
has finished rendering.
### Revalidating
Since the memoization is not shared across server requests and only applies
during rendering, there is no need to revalidate it.
```js filename="app/example.js"
const { signal } = new AbortController()
fetch(url, { signal })
```
## Data Cache
Next.js has a built-in Data Cache that **persists** the result of data fetches
across incoming **server requests** and **deployments**. This is possible
because Next.js extends the native `fetch` API to allow each request on the
server to set its own persistent caching semantics.
> **Good to know**: In the browser, the `cache` option of `fetch` indicates
how a request will interact with the browser's HTTP cache, in Next.js, the
`cache` option indicates how a server-side request will interact with the
server's Data Cache.
By default, data requests that use `fetch` are **cached**. You can use the
[`cache`](#fetch-optionscache) and [`next.revalidate`](#fetch-
optionsnextrevalidate) options of `fetch` to configure the caching behavior.
<Image
alt="Diagram showing how cached and uncached fetch requests interact with
the Data Cache. Cached requests are stored in the Data Cache, and memoized,
uncached requests are fetched from the data source, not stored in the Data
Cache, and memoized."
srcLight="/docs/light/data-cache.png"
srcDark="/docs/dark/data-cache.png"
width="1600"
height="661"
/>
- The first time a `fetch` request is called during rendering, Next.js checks the
Data Cache for a cached response.
- If a cached response is found, it's returned immediately and [memoized]
(#request-memoization).
- If a cached response is not found, the request is made to the data source, the
result is stored in the Data Cache, and memoized.
- For uncached data (e.g. `{ cache: 'no-store' }`), the result is always fetched
from the data source, and memoized.
- Whether the data is cached or uncached, the requests are always memoized
to avoid making duplicate requests for the same data during a React render
pass.
### Duration
### Revalidating
To revalidate data at a timed interval, you can use the `next.revalidate` option
of `fetch` to set the cache lifetime of a resource (in seconds).
```js
// Revalidate at most every hour
fetch('https://...', { next: { revalidate: 3600 } })
```
<Image
alt="Diagram showing how time-based revalidation works, after the
revalidation period, stale data is returned for the first request, then data is
revalidated."
srcLight="/docs/light/time-based-revalidation.png"
srcDark="/docs/dark/time-based-revalidation.png"
width="1600"
height="1252"
/>
- The first time a fetch request with `revalidate` is called, the data will be
fetched from the external data source and stored in the Data Cache.
- Any requests that are called within the specified timeframe (e.g. 60-seconds)
will return the cached data.
- After the timeframe, the next request will still return the cached (now stale)
data.
- Next.js will trigger a revalidation of the data in the background.
- Once the data is fetched successfully, Next.js will update the Data Cache
with the fresh data.
- If the background revalidation fails, the previous data will be kept unaltered.
<Image
alt="Diagram showing how on-demand revalidation works, the Data Cache is
updated with fresh data after a revalidation request."
srcLight="/docs/light/on-demand-revalidation.png"
srcDark="/docs/dark/on-demand-revalidation.png"
width="1600"
height="1082"
/>
- The first time a `fetch` request is called, the data will be fetched from the
external data source and stored in the Data Cache.
- When an on-demand revalidation is triggered, the appropriate cache entries
will be purged from the cache.
- This is different from time-based revalidation, which keeps the stale data in
the cache until the fresh data is fetched.
- The next time a request is made, it will be a cache `MISS` again, and the data
will be fetched from the external data source and stored in the Data Cache.
For individual data fetches, you can opt out of caching by setting the [`cache`]
(#fetch-optionscache) option to `no-store`. This means data will be fetched
whenever `fetch` is called.
```jsx
// Opt out of caching for an individual `fetch` request
fetch(`https://...`, { cache: 'no-store' })
```
Alternatively, you can also use the [Route Segment Config options](#segment-
config-options) to opt out of caching for a specific route segment. This will
affect all data requests in the route segment, including third-party libraries.
```jsx
// Opt out of caching for all data requests in the route segment
export const dynamic = 'force-dynamic'
```
To understand how the Full Route Cache works, it's helpful to look at how React
handles rendering, and how Next.js caches the result:
1. React renders Server Components into a special data format, optimized for
streaming, called the **React Server Component Payload**.
2. Next.js uses the React Server Component Payload and Client Component
JavaScript instructions to render **HTML** on the server.
This means we don't have to wait for everything to render before caching the
work or sending a response. Instead, we can stream a response as work is
completed.
<Image
alt="Default behavior of the Full Route Cache, showing how the React Server
Component Payload and HTML are cached on the server for statically rendered
routes."
srcLight="/docs/light/full-route-cache.png"
srcDark="/docs/dark/full-route-cache.png"
width="1600"
height="888"
/>
The default behavior of Next.js is to cache the rendered result (React Server
Component Payload and HTML) of a route on the server. This applies to
statically rendered routes at build time, or during revalidation.
If the route segments are not in the cache, Next.js will fetch the React Server
Components Payload from the server, and populate the Router Cache on the
client.
This diagram shows the difference between statically and dynamically rendered
routes, with cached and uncached data:
<Image
alt="How static and dynamic rendering affects the Full Route Cache. Static
routes are cached at build time or after data revalidation, whereas dynamic
routes are never cached"
srcLight="/docs/light/static-and-dynamic-routes.png"
srcDark="/docs/dark/static-and-dynamic-routes.png"
width="1600"
height="1314"
/>
### Duration
By default, the Full Route Cache is persistent. This means that the render
output is cached across user requests.
### Invalidation
There are two ways you can invalidate the Full Route Cache:
- **[Revalidating Data](/docs/app/building-your-application/
caching#revalidating)**: Revalidating the [Data Cache](#data-cache), will in
turn invalidate the Router Cache by re-rendering components on the server and
caching the new render output.
- **Redeploying**: Unlike the Data Cache, which persists across deployments,
the Full Route Cache is cleared on new deployments.
You can opt out of the Full Route Cache, or in other words, dynamically render
components for every incoming request, by:
Next.js has an in-memory client-side cache that stores the React Server
Component Payload, split by individual route segments, for the duration of a
user session. This is called the Router Cache.
<Image
alt="How the Router cache works for static and dynamic routes, showing MISS
and HIT for initial and subsequent navigations."
srcLight="/docs/light/router-cache.png"
srcDark="/docs/dark/router-cache.png"
width="1600"
height="1375"
/>
As a user navigates between routes, Next.js caches visited route segments and
[prefetches](/docs/app/building-your-application/routing/linking-and-
navigating#1-prefetching) the routes the user is likely to navigate to (based on
`<Link>` components in their viewport).
> **Difference between the Router Cache and Full Route Cache**:
>
> The Router Cache temporarily stores the React Server Component Payload in
the browser for the duration of a user session, whereas the Full Route Cache
persistently stores the React Server Component Payload and HTML on the
server across multiple user requests.
>
> While the Full Route Cache only caches statically rendered routes, the Router
Cache applies to both statically and dynamically rendered routes.
### Duration
The cache is stored in the browser's temporary memory. Two factors determine
how long the router cache lasts:
While a page refresh will clear **all** cached segments, the automatic
invalidation period only affects the individual segment from the time it was last
accessed or created.
### Invalidation
There are two ways you can invalidate the Router Cache:
- In a **Server Action**:
- Revalidating data on-demand by path with ([`revalidatePath`](/docs/app/
api-reference/functions/revalidatePath)) or by cache tag with ([`revalidateTag`]
(/docs/app/api-reference/functions/revalidateTag))
- Using [`cookies.set`](/docs/app/api-reference/functions/
cookies#cookiessetname-value-options) or [`cookies.delete`](/docs/app/api-
reference/functions/cookies#deleting-cookies) invalidates the Router Cache to
prevent routes that use cookies from becoming stale (e.g. authentication).
- Calling [`router.refresh`](/docs/app/api-reference/functions/use-router) will
invalidate the Router Cache and make a new request to the server for the
current route.
## Cache Interactions
- Revalidating or opting out of the Data Cache **will** invalidate the Full Route
Cache, as the render output depends on data.
- Invalidating or opting out of the Full Route Cache **does not** affect the Data
Cache. You can dynamically render a route that has both cached and uncached
data. This is useful when most of your page uses cached data, but you have a
few components that rely on data that needs to be fetched at request time. You
can dynamically render without worrying about the performance impact of re-
fetching all the data.
## APIs
The following table provides an overview of how different Next.js APIs affect
caching:
### `<Link>`
To disable prefetching, you can set the `prefetch` prop to `false`. But this will
not skip the cache permanently, the route segment will still be cached client-
side when the user visits the route.
### `router.prefetch`
### `router.refresh`
The `refresh` option of the `useRouter` hook can be used to manually refresh a
route. This completely clears the Router Cache, and makes a new request to
the server for the current route. `refresh` does not affect the Data or Full Route
Cache.
The rendered result will be reconciled on the client while preserving React state
and browser state.
### `fetch`
```jsx
// Cached by default. `force-cache` is the default option and can be ommitted.
fetch(`https://...`, { cache: 'force-cache' })
```
You can opt out individual `fetch` requests of data caching by setting the
`cache` option to `no-store`:
```jsx
// Opt out of caching
fetch(`https://...`, { cache: 'no-store' })
```
Since the render output depends on data, using `cache: 'no-store'` will also
skip the Full Route Cache for the route where the `fetch` request is used. That
is, the route will be dynamically rendered every request, but you can still have
other cached data requests in the same route.
You can use the `next.revalidate` option of `fetch` to set the revalidation
period (in seconds) of an individual `fetch` request. This will revalidate the
Data Cache, which in turn will revalidate the Full Route Cache. Fresh data will
be fetched, and components will be re-rendered on the server.
```jsx
// Revalidate at most after 1 hour
fetch(`https://...`, { next: { revalidate: 3600 } })
```
Next.js has a cache tagging system for fine-grained data caching and
revalidation.
```jsx
// Cache data with a tag
fetch(`https://...`, { next: { tags: ['a', 'b', 'c'] } })
```
```jsx
// Revalidate entries with a specific tag
revalidateTag('a')
```
There are two places you can use `revalidateTag`, depending on what you're
trying to achieve:
1. [Route Handlers](/docs/app/building-your-application/routing/route-
handlers) - to revalidate data in response of a third party event (e.g. webhook).
This will not invalidate the Router Cache immediately as the Router Handler
isn't tied to a specific route.
2. [Server Actions](/docs/app/building-your-application/data-fetching/forms-
and-mutations) - to revalidate data after a user action (e.g. form submission).
This will invalidate the Router Cache for the associated route.
### `revalidatePath`
```jsx
revalidatePath('/')
```
There are two places you can use `revalidatePath`, depending on what you're
trying to achieve:
1. [Route Handlers](/docs/app/building-your-application/routing/route-
handlers) - to revalidate data in response to a third party event (e.g. webhook).
2. [Server Actions](/docs/app/building-your-application/data-fetching/forms-
and-mutations) - to revalidate data after a user interaction (e.g. form
submission, clicking a button).
#### `cookies`
Using `cookies.set` or `cookies.delete` in a Server Action invalidates the
Router Cache to prevent routes that use cookies from becoming stale (e.g. to
reflect authentication changes).
The Route Segment Config options can be used to override the route segment
defaults or when you're not able to use the `fetch` API (e.g. database client or
3rd party libraries).
The following Route Segment Config options will opt out of the Data Cache and
Full Route Cache:
### `generateStaticParams`
You can disable caching at request time by using `export const dynamicParams
= false` option in a route segment. When this config option is used, only paths
provided by `generateStaticParams` will be served, and other routes will 404
or match (in the case of [catch-all routes](/docs/app/building-your-application/
routing/dynamic-routes#catch-all-segments)).
The React `cache` function allows you to memoize the return value of a
function, allowing you to call the same function multiple times while only
executing it once.
Since `fetch` requests are automatically memoized, you do not need to wrap it
in React `cache`. However, you can use `cache` to manually memoize data
requests for use cases when the `fetch` API is not suitable. For example, some
database clients, CMS clients, or GraphQL clients.
---
title: CSS Modules
description: Style your Next.js Application with CSS Modules.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<PagesOnly>
<details open>
<summary>Examples</summary>
</details>
</PagesOnly>
Next.js has built-in support for CSS Modules using the `.module.css`
extension.
CSS Modules locally scope CSS by automatically creating a unique class name.
This allows you to use the same class name in different files without worrying
about collisions. This behavior makes CSS Modules the ideal way to include
component-level CSS.
## Example
<AppOnly>
CSS Modules can be imported into any file inside the `app` directory:
```css filename="app/dashboard/styles.module.css"
.dashboard {
padding: 24px;
}
```
</AppOnly>
<PagesOnly>
```css filename="Button.module.css"
/*
You do not need to worry about .error {} colliding with any other `.css` or
`.module.css` files!
*/
.error {
color: white;
background-color: red;
}
```
Then, create `components/Button.js`, importing and using the above CSS file:
```jsx filename="components/Button.js"
import styles from './Button.module.css'
</PagesOnly>
CSS Modules are an _optional feature_ and are **only enabled for files with
the `.module.css` extension**.
Regular `<link>` stylesheets and global CSS files are still supported.
## Global Styles
<AppOnly>
Global styles can be imported into any layout, page, or component inside the
`app` directory.
> **Good to know**: This is different from the `pages` directory, where you can
only import global styles inside the `_app.js` file.
```css
body {
padding: 20px 20px 60px;
max-width: 680px;
margin: 0 auto;
}
```
</AppOnly>
<PagesOnly>
To add a stylesheet to your application, import the CSS file within `pages/
_app.js`.
```css filename="styles.css"
body {
font-family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica',
'Arial', sans-serif;
padding: 20px 20px 60px;
max-width: 680px;
margin: 0 auto;
}
```
```jsx filename="pages/_app.js"
import '../styles.css'
These styles (`styles.css`) will apply to all pages and components in your
application.
Due to the global nature of stylesheets, and to avoid conflicts, you may **only
import them inside [`pages/_app.js`](/docs/pages/building-your-application/
routing/custom-app)**.
</PagesOnly>
## External Stylesheets
<AppOnly>
</AppOnly>
<PagesOnly>
For global stylesheets, like `bootstrap` or `nprogress`, you should import the
file inside `pages/_app.js`.
For example:
```jsx filename="pages/_app.js"
import 'bootstrap/dist/css/bootstrap.css'
```jsx filename="components/example-dialog.js"
import { useState } from 'react'
import { Dialog } from '@reach/dialog'
import VisuallyHidden from '@reach/visually-hidden'
import '@reach/dialog/styles.css'
function ExampleDialog(props) {
const [showDialog, setShowDialog] = useState(false)
const open = () => setShowDialog(true)
const close = () => setShowDialog(false)
return (
<div>
<button onClick={open}>Open Dialog</button>
<Dialog isOpen={showDialog} onDismiss={close}>
<button className="close-button" onClick={close}>
<VisuallyHidden>Close</VisuallyHidden>
<span aria-hidden>×</span>
</button>
<p>Hello there. I am a dialog</p>
</Dialog>
</div>
)
}
```
</PagesOnly>
## Additional Features
- When running locally with `next dev`, local stylesheets (either global or CSS
modules) will take advantage of [Fast Refresh](/docs/architecture/fast-refresh)
to instantly reflect changes as edits are saved.
- When building for production with `next build`, CSS files will be bundled into
fewer minified `.css` files to reduce the number of network requests needed to
retrieve styles.
- If you disable JavaScript, styles will still be loaded in the production build
(`next start`). However, JavaScript is still required for `next dev` to enable
[Fast Refresh](/docs/architecture/fast-refresh).
---
title: Tailwind CSS
description: Style your Next.js Application using Tailwind CSS.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<PagesOnly>
<details open>
<summary>Examples</summary>
</details>
</PagesOnly>
## Installing Tailwind
Install the Tailwind CSS packages and run the `init` command to generate both
the `tailwind.config.js` and `postcss.config.js` files:
```bash filename="Terminal"
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```
## Configuring Tailwind
Inside `tailwind.config.js`, add paths to the files that will use Tailwind CSS class
names:
```js filename="tailwind.config.js"
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}', // Note the addition of the `app` directory.
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
<AppOnly>
## Importing Styles
```css filename="app/globals.css"
@tailwind base;
@tailwind components;
@tailwind utilities;
```
## Using Classes
After installing Tailwind CSS and adding the global styles, you can use
Tailwind's utility classes in your application.
</AppOnly>
<PagesOnly>
## Importing Styles
```css filename="styles/globals.css"
@tailwind base;
@tailwind components;
@tailwind utilities;
```
## Using Classes
After installing Tailwind CSS and adding the global styles, you can use
Tailwind's utility classes in your application.
</PagesOnly>
---
title: CSS-in-JS
description: Use CSS-in-JS libraries with Next.js
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
> **Warning:** CSS-in-JS libraries which require runtime JavaScript are not
currently supported in Server Components. Using CSS-in-JS with newer React
features like Server Components and Streaming requires library authors to
support the latest version of React, including [concurrent rendering](https://
react.dev/blog/2022/03/29/react-v18#what-is-concurrent-react).
>
> We're working with the React team on upstream APIs to handle CSS and
JavaScript assets with support for React Server Components and streaming
architecture.
- [`kuma-ui`](https://kuma-ui.com)
- [`@mui/material`](https://mui.com/material-ui/guides/next-js-app-router/)
- [`pandacss`](https://panda-css.com)
- [`styled-jsx`](#styled-jsx)
- [`styled-components`](#styled-components)
- [`style9`](https://github.com/johanholmerin/style9)
- [`tamagui`](https://tamagui.dev/docs/guides/next-js#server-components)
- [`tss-react`](https://tss-react.dev/)
- [`vanilla-extract`](https://github.com/vercel/next.js/tree/canary/examples/
with-vanilla-extract)
- [`emotion`](https://github.com/emotion-js/emotion/issues/2928)
> **Good to know**: We're testing out different CSS-in-JS libraries and we'll be
adding more examples for libraries that support React 18 features and/or the
`app` directory.
If you want to style Server Components, we recommend using [CSS Modules](/
docs/app/building-your-application/styling/css-modules) or other solutions that
output CSS files, like PostCSS or [Tailwind CSS](/docs/app/building-your-
application/styling/tailwind-css).
### `styled-jsx`
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
useServerInsertedHTML(() => {
const styles = jsxStyleRegistry.styles()
jsxStyleRegistry.flush()
return <>{styles}</>
})
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}</>
})
if (typeof window !== 'undefined') return <>{children}</>
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
```
useServerInsertedHTML(() => {
const styles = styledComponentsStyleSheet.getStyleElement()
styledComponentsStyleSheet.instance.clearTag()
return <>{styles}</>
})
return (
<StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
{children}
</StyleSheetManager>
)
}
```
Wrap the `children` of the root layout with the style registry component:
</AppOnly>
<PagesOnly>
<details>
<summary>Examples</summary>
- [Styled JSX](https://github.com/vercel/next.js/tree/canary/examples/with-
styled-jsx)
- [Styled Components](https://github.com/vercel/next.js/tree/canary/examples/
with-styled-components)
- [Emotion](https://github.com/vercel/next.js/tree/canary/examples/with-
emotion)
- [Linaria](https://github.com/vercel/next.js/tree/canary/examples/with-linaria)
- [Tailwind CSS + Emotion](https://github.com/vercel/next.js/tree/canary/
examples/with-tailwindcss-emotion)
- [Styletron](https://github.com/vercel/next.js/tree/canary/examples/with-
styletron)
- [Cxs](https://github.com/vercel/next.js/tree/canary/examples/with-cxs)
- [Aphrodite](https://github.com/vercel/next.js/tree/canary/examples/with-
aphrodite)
- [Fela](https://github.com/vercel/next.js/tree/canary/examples/with-fela)
- [Stitches](https://github.com/vercel/next.js/tree/canary/examples/with-
stitches)
</details>
It's possible to use any existing CSS-in-JS solution.The simplest one is inline
styles:
```jsx
function HiThere() {
return <p style={{ color: 'red' }}>hi there</p>
}
See the above examples for other popular CSS-in-JS solutions (like Styled
Components).
```jsx
function HelloWorld() {
return (
<div>
Hello world
<p>scoped!</p>
<style jsx>{`
p{
color: blue;
}
div {
background: red;
}
@media (max-width: 600px) {
div {
background: blue;
}
}
`}</style>
<style global jsx>{`
body {
background: black;
}
`}</style>
</div>
)
}
Yes, if you disable JavaScript the CSS will still be loaded in the production build
(`next start`). During development, we require JavaScript to be enabled to
provide the best developer experience with [Fast Refresh](https://nextjs.org/
blog/next-9-4#fast-refresh).
</PagesOnly>
---
title: Sass
description: Style your Next.js application using Sass.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Next.js has built-in support for integrating with Sass after the package is
installed using both the `.scss` and `.sass` extensions. You can use
component-level Sass via CSS Modules and the `.module.scss`or
`.module.sass` extension.
```bash filename="Terminal"
npm install --save-dev sass
```
```js filename="next.config.js"
const path = require('path')
module.exports = {
sassOptions: {
includePaths: [path.join(__dirname, 'styles')],
},
}
```
```scss filename="app/variables.module.scss"
$primary-color: #64ff00;
:export {
primaryColor: $primary-color;
}
```
<AppOnly>
```jsx filename="app/page.js"
// maps to root `/` URL
</AppOnly>
<PagesOnly>
```jsx filename="pages/_app.js"
import variables from '../styles/variables.module.scss'
</PagesOnly>
---
title: Styling
description: Learn the different ways you can style your Next.js application.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
- **Global CSS**: Simple to use and familiar for those experienced with
traditional CSS, but can lead to larger CSS bundles and difficulty managing
styles as the application grows.
- **CSS Modules**: Create locally scoped CSS classes to avoid naming
conflicts and improve maintainability.
- **Tailwind CSS**: A utility-first CSS framework that allows for rapid custom
designs by composing utility classes.
- **Sass**: A popular CSS preprocessor that extends CSS with features like
variables, nested rules, and mixins.
- **CSS-in-JS**: Embed CSS directly in your JavaScript components, enabling
dynamic and scoped styling.
---
title: Image Optimization
nav_title: Images
description: Optimize your images with the built-in `next/image` component.
related:
title: API Reference
description: Learn more about the next/image API.
links:
- app/api-reference/components/image
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<details>
<summary>Examples</summary>
- [Image Component](https://github.com/vercel/next.js/tree/canary/examples/
image-component)
</details>
The Next.js Image component extends the HTML `<img>` element with
features for automatic image optimization:
## Usage
```js
import Image from 'next/image'
```
You can then define the `src` for your image (either local or remote).
To use a local image, `import` your `.jpg`, `.png`, or `.webp` image files.
<AppOnly>
```jsx filename="app/page.js"
import Image from 'next/image'
import profilePic from './me.png'
</AppOnly>
<PagesOnly>
```jsx filename="pages/index.js"
import Image from 'next/image'
import profilePic from '../public/me.png'
</PagesOnly>
Since Next.js does not have access to remote files during the build process,
you'll need to provide the [`width`](/docs/app/api-reference/components/
image#width), [`height`](/docs/app/api-reference/components/image#height)
and optional [`blurDataURL`](/docs/app/api-reference/components/
image#blurdataurl) props manually.
The `width` and `height` attributes are used to infer the correct aspect ratio of
image and avoid layout shift from the image loading in. The `width` and
`height` do _not_ determine the rendered size of the image file. Learn more
about [Image Sizing](#image-sizing).
```jsx filename="app/page.js"
import Image from 'next/image'
```js filename="next.config.js"
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
},
],
},
}
```
### Domains
Sometimes you may want to optimize a remote image, but still use the built-in
Next.js Image Optimization API. To do this, leave the `loader` at its default
setting and enter an absolute URL for the Image `src` prop.
To protect your application from malicious users, you must define a list of
remote hostnames you intend to use with the `next/image` component.
### Loaders
A loader is a function that generates the URLs for your image. It modifies the
provided `src`, and generates multiple URLs to request the image at different
sizes. These multiple URLs are used in the automatic [srcset](https://
developer.mozilla.org/docs/Web/API/HTMLImageElement/srcset) generation, so
that visitors to your site will be served an image that is the right size for their
viewport.
The default loader for Next.js applications uses the built-in Image Optimization
API, which optimizes images from anywhere on the web, and then serves them
directly from the Next.js web server. If you would like to serve your images
directly from a CDN or image server, you can write your own loader function
with a few lines of JavaScript.
## Priority
You should add the `priority` property to the image that will be the [Largest
Contentful Paint (LCP) element](https://web.dev/lcp/#what-elements-are-
considered) for each page. Doing so allows Next.js to specially prioritize the
image for loading (e.g. through preload tags or priority hints), leading to a
meaningful boost in LCP.
The LCP element is typically the largest image or text block visible within the
viewport of the page. When you run `next dev`, you'll see a console warning if
the LCP element is an `<Image>` without the `priority` property.
Once you've identified the LCP image, you can add the property like this:
<PagesOnly>
```jsx filename="app/page.js"
import Image from 'next/image'
</PagesOnly>
<AppOnly>
```jsx filename="app/page.js"
import Image from 'next/image'
import profilePic from '../public/me.png'
</AppOnly>
## Image Sizing
One of the ways that images most commonly hurt performance is through
_layout shift_, where the image pushes other elements around on the page as it
loads in. This performance problem is so annoying to users that it has its own
Core Web Vital, called [Cumulative Layout Shift](https://web.dev/cls/). The way
to avoid image-based layout shifts is to [always size your images](https://
web.dev/optimize-cls/#images-without-dimensions). This allows the browser to
reserve precisely enough space for the image before it loads.
If none of the suggested methods works for sizing your images, the `next/
image` component is designed to work well on a page alongside standard
`<img>` elements.
## Styling
Styling the Image component is similar to styling a normal `<img>` element,
but there are a few guidelines to keep in mind:
## Examples
### Responsive
<Image
alt="Responsive image filling the width and height of its parent container"
srcLight="/docs/light/responsive-image.png"
srcDark="/docs/dark/responsive-image.png"
width="1600"
height="629"
/>
```jsx
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
<Image
alt="Grid of images filling parent container width"
srcLight="/docs/light/fill-container.png"
srcDark="/docs/dark/fill-container.png"
width="1600"
height="529"
/>
```jsx
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
<Image
alt="Background image taking full width and height of page"
srcLight="/docs/light/background-image.png"
srcDark="/docs/dark/background-image.png"
width="1600"
height="427"
/>
```jsx
import Image from 'next/image'
import mountains from '../public/mountains.jpg'
For examples of the Image component used with the various styles, see the
[Image Component Demo](https://image-component.nextjs.gallery).
## Other Properties
## Configuration
---
title: Font Optimization
nav_title: Fonts
description: Optimize your application's web fonts with the built-in `next/font`
loaders.
related:
title: API Reference
description: Learn more about the next/font API.
links:
- app/api-reference/components/font
---
{/* The content of this doc is shared between the app and pages router. 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. */}
This new font system also allows you to conveniently use all Google Fonts with
performance and privacy in mind. CSS and font files are downloaded at build
time and self-hosted with the rest of your static assets. **No requests are
sent to Google by the browser.**
## Google Fonts
Automatically self-host any Google Font. Fonts are included in the deployment
and served from the same domain as your deployment. **No requests are sent
to Google by the browser.**
Get started by importing the font you would like to use from `next/font/google`
as a function. We recommend using [variable fonts](https://fonts.google.com/
variablefonts) for the best performance and flexibility.
<AppOnly>
// If loading a variable font, you don't need to specify the font weight
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
// If loading a variable font, you don't need to specify the font weight
const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
If you can't use a variable font, you will **need to specify a weight**:
</AppOnly>
<PagesOnly>
```jsx filename="pages/_app.js"
import { Inter } from 'next/font/google'
// If loading a variable font, you don't need to specify the font weight
const inter = Inter({ subsets: ['latin'] })
If you can't use a variable font, you will **need to specify a weight**:
```jsx filename="pages/_app.js"
import { Roboto } from 'next/font/google'
</PagesOnly>
```jsx filename="app/layout.js"
const roboto = Roboto({
weight: ['400', '700'],
style: ['normal', 'italic'],
subsets: ['latin'],
display: 'swap',
})
```
> **Good to know**: Use an underscore (\_) for font names with multiple
words. E.g. `Roboto Mono` should be imported as `Roboto_Mono`.
<PagesOnly>
You can also use the font without a wrapper and `className` by injecting it
inside the `<head>` as follows:
```jsx filename="pages/_app.js"
import { Inter } from 'next/font/google'
To use the font on a single page, add it to the specific page as shown below:
```jsx filename="pages/index.js"
import { Inter } from 'next/font/google'
</PagesOnly>
### Specifying a subset
<AppOnly>
</AppOnly>
<PagesOnly>
```jsx filename="pages/_app.js"
const inter = Inter({ subsets: ['latin'] })
```
</PagesOnly>
You can import and use multiple fonts in your application. There are two
approaches you can take.
The first approach is to create a utility function that exports a font, imports it,
and applies its `className` where needed. This ensures the font is preloaded
only when it's rendered:
<AppOnly>
</AppOnly>
In the example above, `Inter` will be applied globally, and `Roboto Mono` can
be imported and applied as needed.
<AppOnly>
</AppOnly>
```css filename="app/global.css"
html {
font-family: var(--font-inter);
}
h1 {
font-family: var(--font-roboto-mono);
}
```
In the example above, `Inter` will be applied globally, and any `<h1>` tags will
be styled with `Roboto Mono`.
> **Recommendation**: Use multiple fonts conservatively since each new font
is an additional resource the client has to download.
## Local Fonts
Import `next/font/local` and specify the `src` of your local font file. We
recommend using [variable fonts](https://fonts.google.com/variablefonts) for
the best performance and flexibility.
<AppOnly>
</AppOnly>
<PagesOnly>
```jsx filename="pages/_app.js"
import localFont from 'next/font/local'
</PagesOnly>
If you want to use multiple files for a single font family, `src` can be an array:
```js
const roboto = localFont({
src: [
{
path: './Roboto-Regular.woff2',
weight: '400',
style: 'normal',
},
{
path: './Roboto-Italic.woff2',
weight: '400',
style: 'italic',
},
{
path: './Roboto-Bold.woff2',
weight: '700',
style: 'normal',
},
{
path: './Roboto-BoldItalic.woff2',
weight: '700',
style: 'italic',
},
],
})
```
In the example below, we use the font `Inter` from `next/font/google` (you can
use any font from Google or Local Fonts). Load your font with the `variable`
option to define your CSS variable name and assign it to `inter`. Then, use
`inter.variable` to add the CSS variable to your HTML document.
<AppOnly>
<PagesOnly>
```jsx filename="pages/_app.js"
import { Inter } from 'next/font/google'
</PagesOnly>
```js filename="tailwind.config.js"
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}',
'./app/**/*.{js,ts,jsx,tsx}',
],
theme: {
extend: {
fontFamily: {
sans: ['var(--font-inter)'],
mono: ['var(--font-roboto-mono)'],
},
},
},
plugins: [],
}
```
You can now use the `font-sans` and `font-mono` utility classes to apply the
font to your elements.
## Preloading
<AppOnly>
When a font function is called on a page of your site, it is not globally available
and preloaded on all routes. Rather, the font is only preloaded on the related
routes based on the type of file where it is used:
</AppOnly>
<PagesOnly>
When a font function is called on a page of your site, it is not globally available
and preloaded on all routes. Rather, the font is only preloaded on the related
route/s based on the type of file where it is used:
</PagesOnly>
## Reusing fonts
Every time you call the `localFont` or Google font function, that font is hosted
as one instance in your application. Therefore, if you load the same font
function in multiple files, multiple instances of the same font are hosted. In this
situation, it is recommended to do the following:
---
title: Script Optimization
nav_title: Scripts
description: Optimize 3rd party scripts with the built-in Script component.
related:
title: API Reference
description: Learn more about the next/script API.
links:
- app/api-reference/components/script
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
To load a third-party script for multiple routes, import `next/script` and include
the script directly in your layout component:
The third-party script is fetched when the folder route (e.g. `dashboard/
page.js`) or any nested route (e.g. `dashboard/settings/page.js`) is accessed
by the user. Next.js will ensure the script will **only load once**, even if a user
navigates between multiple routes in the same layout.
</AppOnly>
<AppOnly>
To load a third-party script for all routes, import `next/script` and include the
script directly in your root layout:
<PagesOnly>
To load a third-party script for all routes, import `next/script` and include the
script directly in your custom `_app`:
```jsx filename="pages/_app.js"
import Script from 'next/script'
</PagesOnly>
This script will load and execute when _any_ route in your application is
accessed. Next.js will ensure the script will **only load once**, even if a user
navigates between multiple pages.
### Strategy
- `beforeInteractive`: Load the script before any Next.js code and before any
page hydration occurs.
- `afterInteractive`: (**default**) Load the script early but after some
hydration on the page occurs.
- `lazyOnload`: Load the script later during browser idle time.
- `worker`: (experimental) Load the script in a web worker.
> **Warning:** The `worker` strategy is not yet stable and does not yet work
with the [`app`](/docs/app/building-your-application/routing/defining-routes)
directory. Use with caution.
Scripts that use the `worker` strategy are offloaded and executed in a web
worker with [Partytown](https://partytown.builder.io/). This can improve the
performance of your site by dedicating the main thread to the rest of your
application code.
```js filename="next.config.js"
module.exports = {
experimental: {
nextScriptWorkers: true,
},
}
```
Then, run `next` (normally `npm run dev` or `yarn dev`) and Next.js will guide
you through the installation of the required packages to finish the setup:
```bash filename="Terminal"
npm run dev
```
You'll see instructions like these: Please install Partytown by running `npm
install @builder.io/partytown`
Inline scripts, or scripts not loaded from an external file, are also supported by
the Script component. They can be written by placing the JavaScript within
curly braces:
```jsx
<Script id="show-banner">
{`document.getElementById('banner').classList.remove('hidden')`}
</Script>
```
```jsx
<Script
id="show-banner"
dangerouslySetInnerHTML={{
__html: `document.getElementById('banner').classList.remove('hidden')`,
}}
/>
```
> **Warning**: An `id` property must be assigned for inline scripts in order for
Next.js to track and optimize the script.
Event handlers can be used with the Script component to execute additional
code after a certain event occurs:
- `onLoad`: Execute code after the script has finished loading.
- `onReady`: Execute code after the script has finished loading and every time
the component is mounted.
- `onError`: Execute code if the script fails to load.
<AppOnly>
These handlers will only work when `next/script` is imported and used inside of
a [Client Component](/docs/app/building-your-application/rendering/client-
components) where `"use client"` is defined as the first line of code:
</AppOnly>
<PagesOnly>
These handlers will only work when `next/script` is imported and used inside of
a [Client Component](/docs/app/building-your-application/rendering/client-
components) where `"use client"` is defined as the first line of code:
</PagesOnly>
There are many DOM attributes that can be assigned to a `<script>` element
that are not used by the Script component, like [`nonce`](https://
developer.mozilla.org/docs/Web/HTML/Global_attributes/nonce) or [custom
data attributes](https://developer.mozilla.org/docs/Web/HTML/
Global_attributes/data-*). Including any additional attributes will automatically
forward it to the final, optimized `<script>` element that is included in the
HTML.
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
---
title: Metadata
description: Use the Metadata API to define metadata in any layout or page.
related:
description: View all the Metadata API options.
links:
- app/api-reference/functions/generate-metadata
- app/api-reference/file-conventions/metadata
- app/api-reference/functions/generate-viewport
---
Next.js has a Metadata API that can be used to define your application
metadata (e.g. `meta` and `link` tags inside your HTML `head` element) for
improved SEO and web shareability.
There are two ways you can add metadata to your application:
With both these options, Next.js will automatically generate the relevant
`<head>` elements for your pages. You can also create dynamic OG images
using the [`ImageResponse`](/docs/app/api-reference/functions/image-
response) constructor.
## Static Metadata
## Dynamic Metadata
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
export default function Page({ params, searchParams }: Props) {}
```
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
## File-based metadata
You can use these for static metadata, or you can programmatically generate
these files with code.
## Behavior
File-based metadata has the higher priority and will override any config-based
metadata.
There are two default `meta` tags that are always added even if a route doesn't
define metadata:
```html
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
```
### Ordering
Metadata is evaluated in order, starting from the root segment down to the
segment closest to the final `page.js` segment. For example:
```jsx filename="app/layout.js"
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}
```
```jsx filename="app/blog/page.js"
export const metadata = {
title: 'Blog',
openGraph: {
title: 'Blog',
},
}
// Output:
// <title>Blog</title>
// <meta property="og:title" content="Blog" />
```
If you'd like to share some nested fields between segments while overwriting
others, you can pull them out into a separate variable:
```jsx filename="app/shared-metadata.js"
export const openGraphImage = { images: ['http://...'] }
```
```jsx filename="app/page.js"
import { openGraphImage } from './shared-metadata'
```jsx filename="app/about/page.js"
import { openGraphImage } from '../shared-metadata'
```jsx filename="app/layout.js"
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}
```
```jsx filename="app/about/page.js"
export const metadata = {
title: 'About',
}
// Output:
// <title>About</title>
// <meta property="og:title" content="Acme" />
// <meta property="og:description" content="Acme is a..." />
```
**Notes**
```jsx filename="app/about/route.js"
import { ImageResponse } from 'next/og'
## JSON-LD
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
description: product.description,
}
return (
<section>
{/* Add JSON-LD to your page */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* ... */}
</section>
)
}
```
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'Product',
name: product.name,
image: product.image,
description: product.description,
}
return (
<section>
{/* Add JSON-LD to your page */}
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
{/* ... */}
</section>
)
}
```
You can validate and test your structured data with the [Rich Results Test]
(https://search.google.com/test/rich-results) for Google or the generic [Schema
Markup Validator](https://validator.schema.org/).
You can type your JSON-LD with TypeScript using community packages like
[`schema-dts`](https://www.npmjs.com/package/schema-dts):
```tsx
import { Product, WithContext } from 'schema-dts'
---
title: Static Assets
description: Next.js allows you to serve static files, like images, in the public
directory. You can learn how it works here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Next.js can serve static files, like images, under a folder called `public` in the
root directory. Files inside `public` can then be referenced by your code
starting from the base URL (`/`).
For example, if you add `me.png` inside `public`, the following code will
access the image:
```jsx filename="Avatar.js"
import Image from 'next/image'
<PagesOnly>
This folder is also useful for `robots.txt`, `favicon.ico`, Google Site Verification,
and any other static files (including `.html`). But make sure to not have a static
file with the same name as a file in the `pages/` directory, as this will result in
an error. [Read more](/docs/messages/conflicting-public-file-page).
</PagesOnly>
<AppOnly>
For static metadata files, such as `robots.txt`, `favicon.ico`, etc, you should
use [special metadata files](/docs/app/api-reference/file-conventions/
metadata) inside the `app` folder.
</AppOnly>
---
title: Lazy Loading
description: Lazy load imported libraries and React Components to improve
your application's loading performance.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
[Lazy loading](https://developer.mozilla.org/docs/Web/Performance/
Lazy_loading) in Next.js helps improve the initial loading performance of an
application by decreasing the amount of JavaScript needed to render a route.
## `next/dynamic`
## Examples
<AppOnly>
### Importing Client Components
```jsx filename="app/page.js"
'use client'
// Client Components:
const ComponentA = dynamic(() => import('../components/A'))
const ComponentB = dynamic(() => import('../components/B'))
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })
return (
<div>
{/* Load immediately, but in a separate client bundle */}
<ComponentA />
If you want to disable pre-rendering for a Client Component, you can use the
`ssr` option set to `false`:
```jsx
const ComponentC = dynamic(() => import('../components/C'), { ssr: false })
```
If you dynamically import a Server Component, only the Client Components that
are children of the Server Component will be lazy-loaded - not the Server
Component itself.
```jsx filename="app/page.js"
import dynamic from 'next/dynamic'
// Server Component:
const ServerComponent = dynamic(() => import('../components/
ServerComponent'))
```jsx filename="app/page.js"
'use client'
return (
<div>
<input
type="text"
placeholder="Search"
onChange={async (e) => {
const { value } = e.currentTarget
// Dynamically load fuse.js
const Fuse = (await import('fuse.js')).default
const fuse = new Fuse(names)
setResults(fuse.search(value))
}}
/>
<pre>Results: {JSON.stringify(results, null, 2)}</pre>
</div>
)
}
```
```jsx filename="app/page.js"
import dynamic from 'next/dynamic'
To dynamically import a named export, you can return it from the Promise
returned by [`import()`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Operators/import) function:
```jsx filename="components/hello.js"
'use client'
```jsx filename="app/page.js"
import dynamic from 'next/dynamic'
</AppOnly>
<PagesOnly>
```jsx
import dynamic from 'next/dynamic'
To dynamically import a named export, you can return it from the [Promise]
(https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/
Promise) returned by [`import()`](https://github.com/tc39/proposal-dynamic-
import#example):
```jsx filename="components/hello.js"
export function Hello() {
return <p>Hello!</p>
}
// pages/index.js
import dynamic from 'next/dynamic'
## With no SSR
To dynamically load a component on the client side, you can use the `ssr`
option to disable server-rendering. This is useful if an external dependency or
component relies on browser APIs like `window`.
```jsx
import dynamic from 'next/dynamic'
```jsx
import { useState } from 'react'
return (
<div>
<input
type="text"
placeholder="Search"
onChange={async (e) => {
const { value } = e.currentTarget
// Dynamically load fuse.js
const Fuse = (await import('fuse.js')).default
const fuse = new Fuse(names)
setResults(fuse.search(value))
}}
/>
<pre>Results: {JSON.stringify(results, null, 2)}</pre>
</div>
)
}
```
</PagesOnly>
---
title: Analytics
description: Measure and track page performance using Next.js Speed Insights
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Next.js has built-in support for measuring and reporting performance metrics.
You can either use the `useReportWebVitals` hook to manage reporting
yourself, or alternatively, Vercel provides a [managed service](https://
vercel.com/analytics?utm_source=next-
site&utm_medium=docs&utm_campaign=next-website) to automatically collect
and visualize metrics for you.
<PagesOnly>
```jsx filename="pages/_app.js"
import { useReportWebVitals } from 'next/web-vitals'
</PagesOnly>
<AppOnly>
```jsx filename="app/_components/web-vitals.js"
'use client'
```jsx filename="app/layout.js"
import { WebVitals } from './_components/web-vitals'
> Since the `useReportWebVitals` hook requires the `"use client"` directive,
the most performant approach is to create a separate component that the root
layout imports. This confines the client boundary exclusively to the `WebVitals`
component.
</AppOnly>
## Web Vitals
You can handle all the results of these metrics using the `name` property.
<PagesOnly>
```jsx filename="pages/_app.js"
import { useReportWebVitals } from 'next/web-vitals'
</PagesOnly>
<AppOnly>
</AppOnly>
<PagesOnly>
## Custom Metrics
In addition to the core metrics listed above, there are some additional custom
metrics that
measure the time it takes for the page to hydrate and render:
- `Next.js-hydration`: Length of time it takes for the page to start and finish
hydrating (in ms)
- `Next.js-route-change-to-render`: Length of time it takes for a page to start
rendering after a
route change (in ms)
- `Next.js-render`: Length of time it takes for a page to finish render after a
route change (in ms)
```js
export function reportWebVitals(metric) {
switch (metric.name) {
case 'Next.js-hydration':
// handle hydration results
break
case 'Next.js-route-change-to-render':
// handle route-change to render results
break
case 'Next.js-render':
// handle render results
break
default:
break
}
}
```
These metrics work in all browsers that support the [User Timing API](https://
caniuse.com/#feat=user-timing).
</PagesOnly>
```js
useReportWebVitals((metric) => {
const body = JSON.stringify(metric)
const url = 'https://example.com/analytics'
> ```js
> useReportWebVitals(metric => {
> // Use `window.gtag` if you initialized Google Analytics as this example:
> // https://github.com/vercel/next.js/blob/canary/examples/with-google-
analytics/pages/_app.js
> window.gtag('event', metric.name, {
> value: Math.round(metric.name === 'CLS' ? metric.value * 1000 :
metric.value), // values must be integers
> event_label: metric.id, // id unique to current page load
> non_interaction: true, // avoids affecting bounce rate.
> });
>}
> ```
>
> Read more about [sending results to Google Analytics](https://github.com/
GoogleChrome/web-vitals#send-the-results-to-google-analytics).
---
title: OpenTelemetry
description: Learn how to instrument your Next.js app with OpenTelemetry.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
## Getting Started
```bash filename="Terminal"
npm install @vercel/otel
```
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
If our wrapper `@vercel/otel` doesn't suit your needs, you can configure
OpenTelemetry manually.
```bash filename="Terminal"
npm install @opentelemetry/sdk-node @opentelemetry/resources
@opentelemetry/semantic-conventions @opentelemetry/sdk-trace-node
@opentelemetry/exporter-trace-otlp-http
```
Doing this is equivalent to using `@vercel/otel`, but it's possible to modify and
extend.
For example, you could use `@opentelemetry/exporter-trace-otlp-grpc`
instead of `@opentelemetry/exporter-trace-otlp-http` or you can specify more
resource attributes.
If everything works well you should be able to see the root server span labeled
as `GET /requested/pathname`.
All other spans from that particular trace will be nested under it.
## Deployment
When you are deploying with OpenTelemetry Collector, you can use `@vercel/
otel`.
It will work both on Vercel and when self-hosted.
#### Self-hosting
Once you have your collector up and running, you can deploy your Next.js app
to your chosen platform following their respective deployment guides.
## Custom Spans
```bash filename="Terminal"
npm install @opentelemetry/api
```
The following example demonstrates a function that fetches GitHub stars and
adds a custom `fetchGithubStars` span to track the fetch request's result:
```ts
import { trace } from '@opentelemetry/api'
The `register` function will execute before your code runs in a new
environment.
You can start creating new spans, and they should be correctly added to the
exported trace.
- `next.span_type`: `BaseServer.handleRequest`
This span represents the root span for each incoming request to your Next.js
application. It tracks the HTTP method, route, target, and status code of the
request.
Attributes:
- `next.span_type`: `AppRender.getBodyResult`.
This span represents the process of rendering a route in the app router.
Attributes:
- `next.span_name`
- `next.span_type`
- `next.route`
- `next.span_type`: `AppRender.fetch`
Attributes:
- `next.span_type`: `AppRouteRouteHandlers.runHandler`.
This span represents the execution of an API route handler in the app router.
Attributes:
- `next.span_name`
- `next.span_type`
- `next.route`
- `next.span_type`: `Render.getServerSideProps`.
Attributes:
- `next.span_name`
- `next.span_type`
- `next.route`
- `next.span_type`: `Render.getStaticProps`.
Attributes:
- `next.span_name`
- `next.span_type`
- `next.route`
- `next.span_type`: `Render.renderDocument`.
This span represents the process of rendering the document for a specific
route.
Attributes:
- `next.span_name`
- `next.span_type`
- `next.route`
- `next.span_type`: `ResolveMetadata.generateMetadata`.
This span represents the process of generating metadata for a specific page (a
single route can have multiple of these spans).
Attributes:
- `next.span_name`
- `next.span_type`
- `next.page`
---
title: Instrumentation
description: Learn how to use instrumentation to run code at server startup in
your Next.js app
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
When your `register` function is deployed, it will be called on each cold boot
(but exactly once in each environment).
Sometimes, it may be useful to import a file in your code because of the side
effects it will cause. For example, you might import a file that defines a set of
global variables, but never explicitly use the imported file in your code. You
would still have access to the global variables the package has declared.
You can import files with side effects in `instrumentation.ts`, which you might
want to use in your `register` function as demonstrated in the following
example:
However, we recommend importing files with side effects using `import` from
within your `register` function instead. The following example demonstrates a
basic usage of `import` in a `register` function:
By doing this, you can colocate all of your side effects in one place in your
code, and avoid any unintended consequences from importing files.
---
title: Third Party Libraries
description: Optimize the performance of third-party libraries in your
application with the `@next/third-parties` package.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
## Getting Started
```bash filename="Terminal"
npm install @next/third-parties
```
## Google Third-Parties
All supported third-party libraries from Google can be imported from `@next/
third-parties/google`.
<AppOnly>
To load Google Tag Manager for all routes, include the component directly in
your root layout:
</AppOnly>
<PagesOnly>
To load Google Tag Manager for all routes, include the component directly in
your custom `_app`:
```jsx filename="pages/_app.js"
import { GoogleTagManager } from '@next/third-parties/google'
</PagesOnly>
To load Google Tag Manager for a single route, include the component in your
page file:
<AppOnly>
```jsx filename="app/page.js"
import { GoogleTagManager } from '@next/third-parties/google'
</AppOnly>
<PagesOnly>
```jsx filename="pages/index.js"
import { GoogleTagManager } from '@next/third-parties/google'
</PagesOnly>
<AppOnly>
```jsx filename="app/page.js"
'use client'
<PagesOnly>
```jsx filename="pages/index.js"
import { sendGTMEvent } from '@next/third-parties/google'
</PagesOnly>
#### Options
Options to pass to the Google Tag Manager. For a full list of options, read the
[Google Tag Manager
docs](https://developers.google.com/tag-platform/tag-manager/datalayer).
<AppOnly>
```jsx filename="app/page.js"
import { GoogleMapsEmbed } from '@next/third-parties/google'
</AppOnly>
<PagesOnly>
```jsx filename="pages/index.js"
import { GoogleMapsEmbed } from '@next/third-parties/google'
#### Options
Options to pass to the Google Maps Embed. For a full list of options, read the
[Google Map Embed
docs](https://developers.google.com/maps/documentation/embed/embedding-
map).
<AppOnly>
```jsx filename="app/page.js"
import { YouTubeEmbed } from '@next/third-parties/google'
</AppOnly>
<PagesOnly>
```jsx filename="pages/index.js"
import { YouTubeEmbed } from '@next/third-parties/google'
</PagesOnly>
#### Options
---
title: Optimizations
nav_title: Optimizing
description: Optimize your Next.js application for best performance and user
experience.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
## Built-in Components
## Metadata
Metadata helps search engines understand your content better (which can
result in better SEO), and allows you to customize how your content is
presented on social media, helping you create a more engaging and consistent
user experience across various platforms.
<AppOnly>
The Metadata API in Next.js allows you to modify the `<head>` element of a
page. You can configure metadata in two ways:
- **Config-based Metadata**: Export a [static `metadata` object](/docs/app/
api-reference/functions/generate-metadata#metadata-object) or a dynamic
[`generateMetadata` function](/docs/app/api-reference/functions/generate-
metadata#generatemetadata-function) in a `layout.js` or `page.js` file.
- **File-based Metadata**: Add static or dynamically generated special files to
route segments.
Additionally, you can create dynamic Open Graph Images using JSX and CSS
with [imageResponse](/docs/app/api-reference/functions/image-response)
constructor.
</AppOnly>
<PagesOnly>
The Head Component in Next.js allows you to modify the `<head>` of a page.
Learn more in the [Head Component](/docs/pages/api-reference/components/
head) documentation.
</PagesOnly>
## Static Assets
Next.js `/public` folder can be used to serve static assets like images, fonts,
and other files. Files inside `/public` can also be cached by CDN providers so
that they are delivered efficiently.
For large applications, Next.js integrates with popular analytics and monitoring
tools to help you understand how your application is performing. Learn more in
the <PagesOnly>[Analytics](/docs/app/building-your-application/optimizing/
analytics), </PagesOnly> [OpenTelemetry](/docs/pages/building-your-
application/optimizing/open-telemetry)<PagesOnly>,</PagesOnly> and
[Instrumentation](/docs/pages/building-your-application/optimizing/
instrumentation) guides.
---
title: TypeScript
description: Next.js provides a TypeScript-first development experience for
building your React application.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
</AppOnly>
## New Projects
```bash filename="Terminal"
npx create-next-app@latest
```
## Existing Projects
Add TypeScript to your project by renaming a file to `.ts` / `.tsx`. Run `next
dev` and `next build` to automatically install the necessary dependencies and
add a `tsconfig.json` file with the recommended config options.
If you already had a `jsconfig.json` file, copy the `paths` compiler option from
the old `jsconfig.json` into the new `tsconfig.json` file, and delete the old
`jsconfig.json` file.
<AppOnly>
## TypeScript Plugin
Next.js includes a custom TypeScript plugin and type checker, which VSCode
and other code editors can use for advanced type-checking and auto-
completion.
<Image
alt="TypeScript Command Palette"
srcLight="/docs/light/typescript-command-palette.png"
srcDark="/docs/dark/typescript-command-palette.png"
width="1600"
height="637"
/>
Now, when editing files, the custom plugin will be enabled. When running `next
build`, the custom type checker will be used.
</AppOnly>
<AppOnly>
Next.js can statically type links to prevent typos and other errors when using
`next/link`, improving type safety when navigating between pages.
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
typedRoutes: true,
},
}
module.exports = nextConfig
```
```tsx
import type { Route } from 'next';
import Link from 'next/link'
```tsx
import type { Route } from 'next'
import Link from 'next/link'
1. **No serialization of data between fetching function and page**: You can
`fetch` directly in components, layouts, and pages on the server. This data
_does not_ need to be serialized (converted to a string) to be passed to the
client side for consumption in React. Instead, since `app` uses Server
Components by default, we can use values like `Date`, `Map`, `Set`, and more
without any extra steps. Previously, you needed to manually type the boundary
between server and client with Next.js-specific types.
2. **Streamlined data flow between components**: With the removal of `_app`
in favor of root layouts, it is now easier to visualize the data flow between
components and pages. Previously, data flowing between individual `pages`
and `_app` were difficult to type and could introduce confusing bugs. With
[colocated data fetching](/docs/app/building-your-application/data-fetching/
fetching-caching-and-revalidating) in Next.js 13, this is no longer an issue.
We're able to type the response data as you would expect with normal
TypeScript. For example:
```tsx filename="app/page.tsx"
async function getData() {
const res = await fetch('https://api.example.com/...')
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
return res.json()
}
return '...'
}
```
For _complete_ end-to-end type safety, this also requires your database or
content provider to support TypeScript. This could be through using an [ORM]
(https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) or type-
safe query builder.
To use an `async` Server Component with TypeScript, ensure you are using
TypeScript `5.1.3` or higher and `@types/react` `18.2.8` or higher.
When passing data between a Server and Client Component through props, the
data is still serialized (converted to a string) for use in the browser. However, it
does not need a special type. It’s typed the same as passing any other props
between components.
Further, there is less code to be serialized, as un-rendered data does not cross
between the server and client (it remains on the server). This is only now
possible through support for Server Components.
</AppOnly>
<PagesOnly>
For [`getStaticProps`](/docs/pages/api-reference/functions/get-static-props),
[`getStaticPaths`](/docs/pages/api-reference/functions/get-static-paths), and
[`getServerSideProps`](/docs/pages/api-reference/functions/get-server-side-
props), you can use the `GetStaticProps`, `GetStaticPaths`, and
`GetServerSideProps` types respectively:
```tsx filename="pages/blog/[slug].tsx"
import { GetStaticProps, GetStaticPaths, GetServerSideProps } from 'next'
## API Routes
The following is an example of how to use the built-in types for API routes:
```ts
import type { NextApiRequest, NextApiResponse } from 'next'
```ts
import type { NextApiRequest, NextApiResponse } from 'next'
type Data = {
name: string
}
## Custom `App`
```ts
import type { AppProps } from 'next/app'
</PagesOnly>
<AppOnly>
You can learn more about this feature on the [Module Path aliases
documentation](/docs/app/building-your-application/configuring/absolute-
imports-and-module-aliases).
</AppOnly>
<PagesOnly>
You can learn more about this feature on the [Module Path aliases
documentation](/docs/pages/building-your-application/configuring/absolute-
imports-and-module-aliases).
</PagesOnly>
The `next.config.js` file must be a JavaScript file as it does not get parsed by
Babel or TypeScript, however you can add some type checking in your IDE
using JSDoc as below:
```js
// @ts-check
/**
* @type {import('next').NextConfig}
**/
const nextConfig = {
/* config options here */
}
module.exports = nextConfig
```
Next.js fails your **production build** (`next build`) when TypeScript errors are
present in your project.
If you'd like Next.js to dangerously produce production code even when your
application has errors, you can disable the built-in type checking step.
If disabled, be sure you are running type checks as part of your build or deploy
process, otherwise this can be very dangerous.
```js filename="next.config.js"
module.exports = {
typescript: {
// !! WARN !!
// Dangerously allow production builds to successfully complete even if
// your project has type errors.
// !! WARN !!
ignoreBuildErrors: true,
},
}
```
## Version Changes
| Version | Changes
|
| --------- |
-------------------------------------------------------------------------------
----------------------------------------------------- |
| `v13.2.0` | Statically typed links are available in beta.
|
| `v12.0.0` | [SWC](/docs/architecture/nextjs-compiler) is now used by default
to compile TypeScript and TSX for faster builds. |
| `v10.2.1` | [Incremental type checking](https://www.typescriptlang.org/
tsconfig#incremental) support added when enabled in your `tsconfig.json`. |
---
title: ESLint
description: Next.js provides an integrated ESLint experience by default. These
conformance rules help you use Next.js in an optimal way.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
```json filename="package.json"
{
"scripts": {
"lint": "next lint"
}
}
```
```bash filename="Terminal"
yarn lint
```
If you don't already have ESLint configured in your application, you will be
guided through the installation and configuration process.
```bash filename="Terminal"
yarn lint
```
```json filename=".eslintrc.json"
{
"extends": "next/core-web-vitals"
}
```
```json filename=".eslintrc.json"
{
"extends": "next"
}
```
- **Cancel**: Does not include any ESLint configuration. Only select this option
if you plan on setting up your own custom ESLint configuration.
If either of the two configuration options are selected, Next.js will automatically
install `eslint` and `eslint-config-next` as dependencies in your application and
create an `.eslintrc.json` file in the root of your project that includes your
selected configuration.
You can now run `next lint` every time you want to run ESLint to catch errors.
Once ESLint has been set up, it will also automatically run during every build
(`next build`). Errors will fail the build, while warnings will not.
<AppOnly>
> If you do not want ESLint to run during `next build`, refer to the
documentation for [Ignoring ESLint](/docs/app/api-reference/next-config-js/
eslint).
</AppOnly>
<PagesOnly>
> If you do not want ESLint to run during `next build`, refer to the
documentation for [Ignoring ESLint](/docs/pages/api-reference/next-config-js/
eslint).
</PagesOnly>
## ESLint Config
> If you would like to use `eslint-config-next` along with other ESLint
configurations, refer to the [Additional Configurations](#additional-
configurations) section to learn how to do so without causing any conflicts.
Recommended rule-sets from the following ESLint plugins are all used within
`eslint-config-next`:
- [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react)
- [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-
react-hooks)
- [`eslint-plugin-next`](https://www.npmjs.com/package/@next/eslint-plugin-
next)
## ESLint Plugin
| | Rule
| Description |
| :-----------------: |
-------------------------------------------------------------------------------
----------------------------------------- |
-------------------------------------------------------------------------------
--------------------------------- |
| <Check size={18} /> | [@next/next/google-font-display](/docs/messages/
google-font-display) | Enforce font-display
behavior with Google Fonts. |
| <Check size={18} /> | [@next/next/google-font-preconnect](/docs/messages/
google-font-preconnect) | Ensure `preconnect` is
used with Google Fonts. |
| <Check size={18} /> | [@next/next/inline-script-id](/docs/messages/inline-
script-id) | Enforce `id` attribute on `next/
script` components with inline content. |
| <Check size={18} /> | [@next/next/next-script-for-ga](/docs/messages/next-
script-for-ga) | Prefer `next/script` component
when using the inline script for Google Analytics. |
| <Check size={18} /> | [@next/next/no-assign-module-variable](/docs/
messages/no-assign-module-variable) | Prevent
assignment to the `module` variable. |
| <Check size={18} /> | [@next/next/no-async-client-component](/docs/
messages/no-async-client-component) | Prevent client
components from being async functions. |
| <Check size={18} /> | [@next/next/no-before-interactive-script-outside-
document](/docs/messages/no-before-interactive-script-outside-document) |
Prevent usage of `next/script`'s `beforeInteractive` strategy outside of `pages/
_document.js`. |
| <Check size={18} /> | [@next/next/no-css-tags](/docs/messages/no-css-tags)
| Prevent manual stylesheet tags.
|
| <Check size={18} /> | [@next/next/no-document-import-in-page](/docs/
messages/no-document-import-in-page) | Prevent
importing `next/document` outside of `pages/_document.js`.
|
| <Check size={18} /> | [@next/next/no-duplicate-head](/docs/messages/no-
duplicate-head) | Prevent duplicate usage of
`<Head>` in `pages/_document.js`. |
| <Check size={18} /> | [@next/next/no-head-element](/docs/messages/no-
head-element) | Prevent usage of `<head>`
element. |
| <Check size={18} /> | [@next/next/no-head-import-in-document](/docs/
messages/no-head-import-in-document) | Prevent
usage of `next/head` in `pages/_document.js`.
|
| <Check size={18} /> | [@next/next/no-html-link-for-pages](/docs/messages/
no-html-link-for-pages) | Prevent usage of `<a>`
elements to navigate to internal Next.js pages. |
| <Check size={18} /> | [@next/next/no-img-element](/docs/messages/no-img-
element) | Prevent usage of `<img>`
element due to slower LCP and higher bandwidth. |
| <Check size={18} /> | [@next/next/no-page-custom-font](/docs/messages/no-
page-custom-font) | Prevent page-only custom
fonts. |
| <Check size={18} /> | [@next/next/no-script-component-in-head](/docs/
messages/no-script-component-in-head) | Prevent usage
of `next/script` in `next/head` component. |
| <Check size={18} /> | [@next/next/no-styled-jsx-in-document](/docs/
messages/no-styled-jsx-in-document) | Prevent usage
of `styled-jsx` in `pages/_document.js`. |
| <Check size={18} /> | [@next/next/no-sync-scripts](/docs/messages/no-sync-
scripts) | Prevent synchronous scripts.
|
| <Check size={18} /> | [@next/next/no-title-in-document-head](/docs/
messages/no-title-in-document-head) | Prevent usage
of `<title>` with `Head` component from `next/document`.
|
| <Check size={18} /> | @next/next/no-typos
| Prevent common typos in [Next.js's data fetching functions](/docs/pages/
building-your-application/data-fetching) |
| <Check size={18} /> | [@next/next/no-unwanted-polyfillio](/docs/messages/
no-unwanted-polyfillio) | Prevent duplicate polyfills
from Polyfill.io. |
#### `rootDir`
```json filename=".eslintrc.json"
{
"extends": "next",
"settings": {
"next": {
"rootDir": "packages/my-app/"
}
}
}
```
By default, Next.js will run ESLint for all files in the `pages/`, `app/`,
`components/`, `lib/`, and `src/` directories. However, you can specify which
directories using the `dirs` option in the `eslint` config in `next.config.js` for
production builds:
```js filename="next.config.js"
module.exports = {
eslint: {
dirs: ['pages', 'utils'], // Only run ESLint on the 'pages' and 'utils' directories
during production builds (next build)
},
}
```
Similarly, the `--dir` and `--file` flags can be used for `next lint` to lint specific
directories and files:
```bash filename="Terminal"
next lint --dir pages --dir utils --file bar.js
```
## Caching
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
```bash filename="Terminal"
next lint --no-cache
```
## Disabling Rules
If you would like to modify or disable any rules provided by the supported
plugins (`react`, `react-hooks`, `next`), you can directly change them using
the `rules` property in your `.eslintrc`:
```json filename=".eslintrc.json"
{
"extends": "next",
"rules": {
"react/no-unescaped-entities": "off",
"@next/next/no-page-custom-font": "off"
}
}
```
The `next/core-web-vitals` rule set is enabled when `next lint` is run for the
first time and the **strict** option is selected.
```json filename=".eslintrc.json"
{
"extends": "next/core-web-vitals"
}
```
### Prettier
ESLint also contains code formatting rules, which can conflict with your existing
[Prettier](https://prettier.io/) setup. We recommend including [eslint-config-
prettier](https://github.com/prettier/eslint-config-prettier) in your ESLint config
to make ESLint and Prettier work together.
First, install the dependency:
```bash filename="Terminal"
npm install --save-dev eslint-config-prettier
```json filename=".eslintrc.json"
{
"extends": ["next", "prettier"]
}
```
### lint-staged
```js filename=".lintstagedrc.js"
const path = require('path')
module.exports = {
'*.{js,jsx,ts,tsx}': [buildEslintCommand],
}
```
If you already have ESLint configured in your application and any of the
following conditions are true:
- You have one or more of the following plugins already installed (either
separately or through a different config such as `airbnb` or `react-app`):
- `react`
- `react-hooks`
- `jsx-a11y`
- `import`
- You've defined specific `parserOptions` that are different from how Babel is
configured within Next.js (this is not recommended unless you have
[customized your Babel configuration](/docs/pages/building-your-application/
configuring/babel))
- You have `eslint-plugin-import` installed with Node.js and/or TypeScript
[resolvers](https://github.com/benmosher/eslint-plugin-import#resolvers)
defined to handle imports
Then we recommend either removing these settings if you prefer how these
properties have been configured within [`eslint-config-next`](https://
github.com/vercel/next.js/blob/canary/packages/eslint-config-next/index.js) or
extending directly from the Next.js ESLint plugin instead:
```js
module.exports = {
extends: [
//...
'plugin:@next/next/recommended',
],
}
```
The plugin can be installed normally in your project without needing to run
`next lint`:
```bash filename="Terminal"
npm install --save-dev @next/eslint-plugin-next
This eliminates the risk of collisions or errors that can occur due to importing
the same plugin or parser across multiple configurations.
```json filename=".eslintrc.json"
{
"extends": ["eslint:recommended", "next"]
}
```
The `next` configuration already handles setting default values for the
`parser`, `plugins` and `settings` properties. There is no need to manually re-
declare any of these properties unless you need a different configuration for
your use case.
If you include any other shareable configurations, **you will need to make
sure that these properties are not overwritten or modified**. Otherwise, we
recommend removing any configurations that share behavior with the `next`
configuration or extending directly from the Next.js ESLint plugin as mentioned
above.
---
title: Environment Variables
description: Learn to add and access environment variables in your Next.js
application.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<details>
<summary>Examples</summary>
- [Environment Variables](https://github.com/vercel/next.js/tree/canary/
examples/environment-variables)
</details>
Next.js comes with built-in support for environment variables, which allows you
to do the following:
Next.js has built-in support for loading environment variables from `.env.local`
into `process.env`.
```txt filename=".env.local"
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
```
<PagesOnly>
```js filename="pages/index.js"
export async function getStaticProps() {
const db = await myDB.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS,
})
// ...
}
```
</PagesOnly>
<AppOnly>
> **Note**: Next.js also supports multiline variables inside of your `.env*` files:
>
> ```bash
> # .env.local
>
> # you can write with line breaks
> PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
> ...
> Kh9NV...
> ...
> -----END DSA PRIVATE KEY-----"
>
> # or with `\n` inside double quotes
> PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nKh9NV...\n-----END DSA
PRIVATE KEY-----\n"
> ```
> **Note**: If you are using a `/src` folder, please note that Next.js will load
the .env files **only** from the parent folder and **not** from the `/src` folder.
> This loads `process.env.DB_HOST`, `process.env.DB_USER`, and
`process.env.DB_PASS` into the Node.js environment automatically allowing
you to use them in [Route Handlers](/docs/app/building-your-application/
routing/route-handlers).
For example:
```js filename="app/api/route.js"
export async function GET() {
const db = await myDB.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS,
})
// ...
}
```
</AppOnly>
Next.js will automatically expand variables that use `$` to reference other
variables e.g. `$VARIABLE` inside of your `.env*` files. This allows you to
reference other secrets. For example:
```txt filename=".env"
TWITTER_USER=nextjs
TWITTER_URL=https://twitter.com/$TWITTER_USER
```
> **Good to know**: If you need to use variable with a `$` in the actual value,
it needs to be escaped e.g. `\$`.
## Bundling Environment Variables for the Browser
```txt filename="Terminal"
NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk
```
> **Note**: After being built, your app will no longer respond to changes to
these environment variables. For instance, if you use a Heroku pipeline to
promote slugs built in one environment to another environment, or if you build
and deploy a single Docker image to multiple environments, all
`NEXT_PUBLIC_` variables will be frozen with the value evaluated at build time,
so these values need to be set appropriately when the project is built. If you
need access to runtime environment values, you'll have to setup your own API
to provide them to the client (either on demand or during initialization).
```js filename="pages/index.js"
import setupAnalyticsService from '../lib/my-analytics-service'
function HomePage() {
return <h1>Hello World</h1>
}
```js
// This will NOT be inlined, because it uses a variable
const varName = 'NEXT_PUBLIC_ANALYTICS_ID'
setupAnalyticsService(process.env[varName])
Next.js can support both build time and runtime environment variables.
```jsx
import { unstable_noStore as noStore } from 'next/cache'
**Good to know:**
- You can run code on server startup using the [`register` function](/docs/app/
building-your-application/optimizing/instrumentation).
- We do not recommend using the [runtimeConfig](/docs/pages/api-reference/
next-config-js/runtime-configuration) option, as this does not work with the
standalone output mode. Instead, we recommend [incrementally adopting](/
docs/app/building-your-application/upgrading/app-router-migration) the App
Router.
In general only one `.env.local` file is needed. However, sometimes you might
want to add some defaults for the `development` (`next dev`) or `production`
(`next start`) environment.
```bash filename="Terminal"
vercel env pull .env.local
```
This one is useful when running tests with tools like `jest` or `cypress` where
you need to set specific environment vars only for testing purposes. Test
default values will be loaded if `NODE_ENV` is set to `test`, though you usually
don't need to do this manually as testing tools will address it for you.
While running unit tests you can make sure to load your environment variables
the same way Next.js does by leveraging the `loadEnvConfig` function from the
`@next/env` package.
```js
// The below can be used in a Jest global setup file or similar for your testing
set-up
import { loadEnvConfig } from '@next/env'
1. `process.env`
1. `.env.$(NODE_ENV).local`
1. `.env.local` (Not checked when `NODE_ENV` is `test`.)
1. `.env.$(NODE_ENV)`
1. `.env`
> **Good to know**: The allowed values for `NODE_ENV` are `production`,
`development` and `test`.
## Good to know
## Version History
| Version | Changes |
| -------- | --------------------------------------------- |
| `v9.4.0` | Support `.env` and `NEXT_PUBLIC_` introduced. |
---
title: Absolute Imports and Module Path Aliases
description: Configure module path aliases that allow you to remap certain
import paths.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<details>
<summary>Examples</summary>
</details>
Next.js has in-built support for the `"paths"` and `"baseUrl"` options of
`tsconfig.json` and `jsconfig.json` files.
These options allow you to alias project directories to absolute paths, making it
easier to import modules. For example:
```tsx
// before
import { Button } from '../../../components/button'
// after
import { Button } from '@/components/button'
```
## Absolute Imports
The `baseUrl` configuration option allows you to import directly from the root
of the project.
## Module Aliases
In addition to configuring the `baseUrl` path, you can use the `"paths"` option
to "alias" module paths.
Each of the `"paths"` are relative to the `baseUrl` location. For example:
```json
// tsconfig.json or jsconfig.json
{
"compilerOptions": {
"baseUrl": "src/",
"paths": {
"@/styles/*": ["styles/*"],
"@/components/*": ["components/*"]
}
}
}
```
```jsx
// pages/index.js
import Button from '@/components/button'
import '@/styles/styles.css'
import Helper from 'utils/helper'
---
title: Markdown and MDX
nav_title: MDX
description: Learn how to configure MDX to write JSX in your markdown files.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
[Markdown](https://daringfireball.net/projects/markdown/syntax) is a
lightweight markup language used to format text. It allows you to write using
plain text syntax and convert it to structurally valid HTML. It's commonly used
for writing content on websites and blogs.
You write...
```md
I **love** using [Next.js](https://nextjs.org/)
```
Output:
```html
<p>I <strong>love</strong> using <a href="https://nextjs.org/">Next.js</a></
p>
```
Next.js can support both local MDX content inside your application, as well as
remote MDX files fetched dynamically on the server. The Next.js plugin handles
transforming markdown and React components into HTML, including support
for usage in Server Components (the default in App Router).
## `@next/mdx`
Let's walk through how to configure and use MDX with Next.js.
## Getting Started
```bash filename="Terminal"
npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
```
<AppOnly>
</AppOnly>
```js filename="next.config.js"
const withMDX = require('@next/mdx')()
module.exports = withMDX(nextConfig)
```
<AppOnly>
```txt
your-project
├── app
│ └── my-mdx-page
│ └── page.mdx
└── package.json
```
</AppOnly>
<PagesOnly>
```txt
your-project
├── pages
│ └── my-mdx-page.mdx
└── package.json
```
</PagesOnly>
Now you can use markdown and import React components directly inside your
MDX page:
```mdx
import { MyComponent } from 'my-components'
- One
- Two
- Three
<MyComponent />
```
## Remote MDX
If your markdown or MDX files or content lives _somewhere else_, you can fetch
it dynamically on the server. This is useful for content stored in a separate local
folder, CMS, database, or anywhere else.
There are two popular community packages for fetching MDX content:
- [`next-mdx-remote`](https://github.com/hashicorp/next-mdx-remote#react-
server-components-rsc--nextjs-app-directory-support)
- [`contentlayer`](https://www.contentlayer.dev/)
> **Good to know**: Please proceed with caution. MDX compiles to JavaScript
and is executed on the server. You should only fetch MDX content from a
trusted source, otherwise this can lead to remote code execution (RCE).
<AppOnly>
</AppOnly>
<PagesOnly>
interface Props {
mdxSource: MDXRemoteSerializeResult
}
</PagesOnly>
## Layouts
<AppOnly>
To share a layout amongst MDX pages, you can use the [built-in layouts
support](/docs/app/building-your-application/routing/pages-and-
layouts#layouts) with the App Router.
</AppOnly>
<PagesOnly>
To share a layout around MDX pages, create a layout component:
Then, import the layout component into the MDX page, wrap the MDX content
in the layout, and export it:
```mdx
import MdxLayout from '../components/mdx-layout'
}
```
</PagesOnly>
You can optionally provide `remark` and `rehype` plugins to transform the
MDX content.
For example, you can use `remark-gfm` to support GitHub Flavored Markdown.
Since the `remark` and `rehype` ecosystem is ESM only, you'll need to use
`next.config.mjs` as the configuration file.
```js filename="next.config.mjs"
import remarkGfm from 'remark-gfm'
import createMDX from '@next/mdx'
/** @type {import('next').NextConfig} */
const nextConfig = {
// Configure `pageExtensions`` to include MDX files
pageExtensions: ['js', 'jsx', 'mdx', 'ts', 'tsx'],
// Optionally, add any other Next.js config below
}
## Frontmatter
Frontmatter is a YAML like key/value pairing that can be used to store data
about a page. `@next/mdx` does **not** support frontmatter by default,
though there are many solutions for adding frontmatter to your MDX content,
such as:
- [remark-frontmatter](https://github.com/remarkjs/remark-frontmatter)
- [gray-matter](https://github.com/jonschlinkert/gray-matter).
To access page metadata with `@next/mdx`, you can export a metadata object
from within the `.mdx` file:
```mdx
export const metadata = {
author: 'John Doe',
}
# My MDX page
```
## Custom Elements
```md
This is a list in markdown:
- One
- Two
- Three
```
```html
<p>This is a list in markdown:</p>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
```
When you want to style your own elements for a custom feel to your website or
application, you can pass in shortcodes. These are your own custom
components that map to `HTML` elements.
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
React does not natively understand markdown. The markdown plaintext needs
to first be transformed into HTML. This can be accomplished with `remark` and
`rehype`.
```js
import { unified } from 'unified'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import rehypeSanitize from 'rehype-sanitize'
import rehypeStringify from 'rehype-stringify'
main()
When using `@next/mdx` as shown above, you **do not** need to use
`remark` or `rehype` directly, as it is handled for you. We're describing it here
for a deeper understanding of what the `@next/mdx` package is doing
underneath.
Next.js supports a new MDX compiler written in Rust. This compiler is still
experimental and is not recommended for production use. To use the new
compiler, you need to configure `next.config.js` when you pass it to
`withMDX`:
```js filename="next.config.js"
module.exports = withMDX({
experimental: {
mdxRs: true,
},
})
```
## Helpful Links
- [MDX](https://mdxjs.com)
- [`@next/mdx`](https://www.npmjs.com/package/@next/mdx)
- [remark](https://github.com/remarkjs/remark)
- [rehype](https://github.com/rehypejs/rehype)
---
title: src Directory
description: Save pages under the `src` directory as an alternative to the root
`pages` directory.
related:
links:
- app/building-your-application/routing/colocation
---
{/* The content of this doc is shared between the app and pages router. 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. */}
This separates application code from project configuration files which mostly
live in the root of a project, which is preferred by some individuals and teams.
To use the `src` directory, move the `app` Router folder or `pages` Router
folder to `src/app` or `src/pages` respectively.
<Image
alt="An example folder structure with the `src` directory"
srcLight="/docs/light/project-organization-src-directory.png"
srcDark="/docs/dark/project-organization-src-directory.png"
width="1600"
height="687"
/>
---
title: Draft Mode
description: Next.js has draft mode to toggle between static and dynamic
pages. You can learn how it works with App Router here.
---
Static rendering is useful when your pages fetch data from a headless CMS.
However, it’s not ideal when you’re writing a draft on your headless CMS and
want to view the draft immediately on your page. You’d want Next.js to render
these pages at **request time** instead of build time and fetch the draft
content instead of the published content. You’d want Next.js to switch to
[dynamic rendering](/docs/app/building-your-application/rendering/server-
components#dynamic-rendering) 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.
Then, import `draftMode` from `next/headers` and call the `enable()` method.
You can test this manually by visiting `/api/draft` and looking at your browser’s
developer tools. Notice the `Set-Cookie` response header with a cookie named
`__prerender_bypass`.
In practice, you’d want to call this Route Handler _securely_ from your headless
CMS. The specific steps will vary depending on which headless CMS you’re
using, but here are some common steps you could take.
These steps assume that the headless CMS you’re using supports setting
**custom draft URLs**. If it doesn’t, you can still use this method to secure
your draft URLs, but you’ll 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 don’t 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 Route Handler is located
at `app/api/draft/route.ts`
```bash filename="Terminal"
https://<your-site>/api/draft?secret=<token>&slug=<path>
```
Your headless CMS might allow you to include a variable in the draft URL so
that `<path>` can be set dynamically based on the CMS’s data like so: `&slug=/
posts/{entry.fields.slug}`
**Finally**, in the Route Handler:
- Check that the secret matches and that the `slug` parameter exists (if not,
the request should fail).
- Call `draftMode.enable()` to set the cookie.
- Then redirect the browser to the path specified by `slug`.
// If the slug doesn't exist prevent draft mode from being enabled
if (!post) {
return new Response('Invalid slug', { status: 401 })
}
// If the slug doesn't exist prevent draft mode from being enabled
if (!post) {
return new Response('Invalid slug', { status: 401 })
}
If it succeeds, then the browser will be redirected to the path you want to view
with the draft mode cookie.
If you request a page which has the cookie set, then data will be fetched at
**request time** (instead of at build time).
return res.json()
}
return (
<main>
<h1>{title}</h1>
<p>{desc}</p>
</main>
)
}
```
return res.json()
}
That's it! If you access the draft Route Handler (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
By default, the Draft Mode session ends when the browser is closed.
To clear the Draft Mode cookie manually, create a Route Handler that calls
`draftMode().disable()`:
A new bypass cookie value will be generated each time you run `next build`.
> **Good to know**: To test Draft Mode locally over HTTP, your browser will
need to allow third-party cookies and local storage access.
---
title: Content Security Policy
description: Learn how to set a Content Security Policy (CSP) for your Next.js
application.
related:
links:
- app/building-your-application/routing/middleware
- app/api-reference/functions/headers
---
{/* The content of this doc is shared between the app and pages router. 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. */}
By using CSP, developers can specify which origins are permissible for content
sources, scripts, stylesheets, images, fonts, objects, media (audio, video),
iframes, and more.
<details>
<summary>Examples</summary>
- [Strict CSP](https://github.com/vercel/next.js/tree/canary/examples/with-
strict-csp)
</details>
## Nonces
A [nonce](https://developer.mozilla.org/docs/Web/HTML/Global_attributes/
nonce) is a unique, random string of characters created for a one-time use. It is
used in conjunction with CSP to selectively allow certain inline scripts or styles
to execute, bypassing strict CSP directives.
Even though CSPs are designed to block malicious scripts, there are legitimate
scenarios where inline scripts are necessary. In such cases, nonces offer a way
to allow these scripts to execute if they have the correct nonce.
[Middleware](/docs/app/building-your-application/routing/middleware) enables
you to add headers and generate nonces before the page renders.
Every time a page is viewed, a fresh nonce should be generated. This means
that you **must use dynamic rendering to add nonces**.
For example:
requestHeaders.set(
'Content-Security-Policy',
contentSecurityPolicyHeaderValue
)
return response
}
```
return response
}
```
By default, Middleware runs on all requests. You can filter Middleware to run on
specific paths using a [`matcher`](/docs/app/building-your-application/routing/
middleware#matcher).
return (
<Script
src="https://www.googletagmanager.com/gtag/js"
strategy="afterInteractive"
nonce={nonce}
/>
)
}
```
return (
<Script
src="https://www.googletagmanager.com/gtag/js"
strategy="afterInteractive"
nonce={nonce}
/>
)
}
```
## Version History
---
title: Configuring
description: Learn how to configure your Next.js application.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
---
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.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Since Next.js supports this static export, it can be deployed and hosted on any
web server that can serve HTML/CSS/JS static assets.
<PagesOnly>
> **Good to know**: We recommend using the App Router for enhanced static
export support.
</PagesOnly>
## Configuration
// Optional: Change links `/me` -> `/me/` and emit `/me.html` -> `/me/
index.html`
// trailingSlash: true,
module.exports = nextConfig
```
After running `next build`, Next.js will produce an `out` folder which contains
the HTML/CSS/JS assets for your application.
<PagesOnly>
</PagesOnly>
<AppOnly>
## Supported Features
When you run `next build` to generate a static export, Server Components
consumed inside the `app` directory will run during the build, similar to
traditional static-site generation.
The resulting component will be rendered into static HTML for the initial page
load and a static payload for client navigation between routes. No changes are
required for your Server Components when using the static export, unless they
consume [dynamic server functions](#unsupported-features).
return <main>...</main>
}
```
If you want to perform data fetching on the client, you can use a Client
Component with [SWR](https://github.com/vercel/swr) to memoize requests.
return data.title
}
```
return data.title
}
```
Since route transitions happen client-side, this behaves like a traditional SPA.
For example, the following index route allows you to navigate to different posts
on the client:
</AppOnly>
<PagesOnly>
## Supported Features
The majority of core Next.js features needed to build a static site are
supported, including:
</PagesOnly>
### Image Optimization
[Image Optimization](/docs/app/building-your-application/optimizing/images)
through `next/image` can be used with a static export by defining a custom
image loader in `next.config.js`. For example, you can optimize images with a
service like Cloudinary:
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
images: {
loader: 'custom',
loaderFile: './my-loader.ts',
},
}
module.exports = nextConfig
```
This custom loader will define how to fetch images from a remote source. For
example, the following loader will construct the URL for Cloudinary:
You can then use `next/image` in your application, defining relative paths to the
image in Cloudinary:
<AppOnly>
Route Handlers will render a static response when running `next build`. Only
the `GET` HTTP verb is supported. This can be used to generate static HTML,
JSON, TXT, or other files from cached or uncached data. For example:
The above file `app/data.json/route.ts` will render to a static file during `next
build`, producing `data.json` containing `{ name: 'Lee' }`.
If you need to read dynamic values from the incoming request, you cannot use
a static export.
### Browser APIs
```jsx
'use client';
return ...;
}
```
</AppOnly>
## Unsupported Features
<AppOnly>
- [Dynamic Routes](/docs/app/building-your-application/routing/dynamic-
routes) with `dynamicParams: true`
- [Dynamic Routes](/docs/app/building-your-application/routing/dynamic-
routes) without `generateStaticParams()`
- [Route Handlers](/docs/app/building-your-application/routing/route-handlers)
that rely on Request
- [Cookies](/docs/app/api-reference/functions/cookies)
- [Rewrites](/docs/app/api-reference/next-config-js/rewrites)
- [Redirects](/docs/app/api-reference/next-config-js/redirects)
- [Headers](/docs/app/api-reference/next-config-js/headers)
- [Middleware](/docs/app/building-your-application/routing/middleware)
- [Incremental Static Regeneration](/docs/app/building-your-application/data-
fetching/fetching-caching-and-revalidating)
- [Image Optimization](/docs/app/building-your-application/optimizing/images)
with the default `loader`
- [Draft Mode](/docs/app/building-your-application/configuring/draft-mode)
Attempting to use any of these features with `next dev` will result in an error,
similar to setting the [`dynamic`](/docs/app/api-reference/file-conventions/
route-segment-config#dynamic) option to `error` in the root layout.
```jsx
export const dynamic = 'error'
```
</AppOnly>
<PagesOnly>
- [Internationalized Routing](/docs/pages/building-your-application/routing/
internationalization)
- [API Routes](/docs/pages/building-your-application/routing/api-routes)
- [Rewrites](/docs/pages/api-reference/next-config-js/rewrites)
- [Redirects](/docs/pages/api-reference/next-config-js/redirects)
- [Headers](/docs/pages/api-reference/next-config-js/headers)
- [Middleware](/docs/pages/building-your-application/routing/middleware)
- [Incremental Static Regeneration](/docs/pages/building-your-application/
data-fetching/incremental-static-regeneration)
- [Image Optimization](/docs/pages/building-your-application/optimizing/
images) with the default `loader`
- [Draft Mode](/docs/pages/building-your-application/configuring/draft-mode)
- [`getStaticPaths` with `fallback: true`](/docs/pages/api-reference/functions/
get-static-paths#fallback-true)
- [`getStaticPaths` with `fallback: 'blocking'`](/docs/pages/api-reference/
functions/get-static-paths#fallback-blocking)
- [`getServerSideProps`](/docs/pages/building-your-application/data-fetching/
get-server-side-props)
</PagesOnly>
## Deploying
With a static export, Next.js can be deployed and hosted on any web server
that can serve HTML/CSS/JS static assets.
When running `next build`, Next.js generates the static export into the `out`
folder. For example, let's say you have the following routes:
- `/`
- `/blog/[id]`
After running `next build`, Next.js will generate the following files:
- `/out/index.html`
- `/out/404.html`
- `/out/blog/post-1.html`
- `/out/blog/post-2.html`
If you are using a static host like Nginx, you can configure rewrites from
incoming requests to the correct files:
```nginx filename="nginx.conf"
server {
listen 80;
server_name acme.com;
root /var/www/out;
location / {
try_files $uri $uri.html $uri/ =404;
}
## Version History
| Version | Changes
|
| --------- |
-------------------------------------------------------------------------------
------------------------------------- |
| `v14.0.0` | `next export` has been removed in favor of `"output": "export"`
|
| `v13.4.0` | App Router (Stable) adds enhanced static export support, including
using React Server Components and Route Handlers. |
| `v13.3.0` | `next export` is deprecated and replaced with `"output": "export"`
|
Congratulations, it's time to ship to production.
## Production Builds
[Vercel](https://vercel.com/docs/frameworks/nextjs?utm_source=next-
site&utm_medium=docs&utm_campaign=next-website), the creators and
maintainers of Next.js, provide managed infrastructure and a developer
experience platform for your Next.js applications.
## Self-Hosting
- [A Node.js server](#nodejs-server)
- [A Docker container](#docker-image)
- [A static export](#static-html-export)
### Node.js Server
Next.js can be deployed to any hosting provider that supports Node.js. Ensure
your `package.json` has the `"build"` and `"start"` scripts:
```json filename="package.json"
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
```
Then, run `npm run build` to build your application. Finally, run `npm run start`
to start the Node.js server. This server supports all Next.js features.
## Features
[Image Optimization](/docs/app/building-your-application/optimizing/images)
through `next/image` works self-hosted with zero configuration when
deploying using `next start`. If you would prefer to have a separate service to
optimize images, you can [configure an image loader](/docs/app/building-your-
application/optimizing/images#loaders).
### Middleware
[Middleware](/docs/app/building-your-application/routing/middleware) works
self-hosted with zero configuration when deploying using `next start`. Since it
requires access to the incoming request, it is not supported when using a
[static export](/docs/app/building-your-application/deploying/static-exports).
If you are looking to add logic (or use an external package) that requires all
Node.js APIs, you might be able to move this logic to a [layout](/docs/app/
building-your-application/routing/pages-and-layouts#layouts) as a [Server
Component](/docs/app/building-your-application/rendering/server-
components). For example, checking [headers](/docs/app/api-reference/
functions/headers) and [redirecting](/docs/app/api-reference/functions/
redirect). You can also use headers, cookies, or query parameters to [redirect](/
docs/app/api-reference/next-config-js/redirects#header-cookie-and-query-
matching) or [rewrite](/docs/app/api-reference/next-config-js/rewrites#header-
cookie-and-query-matching) through `next.config.js`. If that does not work,
you can also use a [custom server](/docs/pages/building-your-application/
configuring/custom-server).
Next.js can support both build time and runtime environment variables.
```jsx
import { unstable_noStore as noStore } from 'next/cache';
Next.js can cache responses, generated static pages, build outputs, and other
static assets like images, fonts, and scripts.
You can configure the Next.js cache location if you want to persist cached
pages and data to durable storage, or share the cache across multiple
containers or instances of your Next.js application.
To configure the ISR/Data Cache location when self-hosting, you can configure
a custom handler in your `next.config.js` file:
```jsx filename="next.config.js"
module.exports = {
experimental: {
incrementalCacheHandlerPath: require.resolve('./cache-handler.js'),
isrMemoryCacheSize: 0, // disable default in-memory caching
},
}
```
```jsx filename="cache-handler.js"
const cache = new Map()
async get(key) {
// This could be stored anywhere, like durable storage
return cache.get(key)
}
async revalidateTag(tag) {
// Iterate over all entries in the cache
for (let [key, value] of cache) {
// If the value's tags include the specified tag, delete this entry
if (value.tags.includes(tag)) {
cache.delete(key)
}
}
}
}
```
Using a custom cache handler will allow you to ensure consistency across all
pods hosting your Next.js application. For instance, you can save the cached
values anywhere, like [Redis](https://github.com/vercel/next.js/tree/canary/
examples/cache-handler-redis) or AWS S3.
If you are rebuilding for each stage of your environment, you will need to
generate a consistent build ID to use between containers. Use the
`generateBuildId` command in `next.config.js`:
```jsx filename="next.config.js"
module.exports = {
generateBuildId: async () => {
// This could be anything, using the latest git hash
return process.env.GIT_HASH
},
}
```
When the application is reloaded, there may be a loss of application state if it's
not designed to persist between page navigations. For example, using URL
state or local storage would persist state after a page refresh. However,
component state like `useState` would be lost in such navigations.
<PagesOnly>
When self-hosting, you might want to run code when the server shuts down on
`SIGTERM` or `SIGINT` signals.
> **Good to know**: Manual signal handling is not available in `next dev`.
```json filename="package.json"
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "NEXT_MANUAL_SIG_HANDLE=true next start"
}
}
```
```js filename="pages/_document.js"
if (process.env.NEXT_MANUAL_SIG_HANDLE) {
process.on('SIGTERM', () => {
console.log('Received SIGTERM: cleaning up')
process.exit(0)
})
process.on('SIGINT', () => {
console.log('Received SIGINT: cleaning up')
process.exit(0)
})
}
```
</PagesOnly>
---
title: Codemods
description: Use codemods to upgrade your Next.js codebase when new
features are released.
---
## Usage
In your terminal, navigate (`cd`) into your project's folder, then run:
```bash filename="Terminal"
npx @next/codemod <transform> <path>
```
## Next.js Codemods
### 14.0
```bash filename="Terminal"
npx @next/codemod@latest next-og-import .
```
For example:
```js
import { ImageResponse } from 'next/server'
```
Transforms into:
```js
import { ImageResponse } from 'next/og'
```
##### `metadata-to-viewport-export`
```bash filename="Terminal"
npx @next/codemod@latest metadata-to-viewport-export .
```
For example:
```js
export const metadata = {
title: 'My App',
themeColor: 'dark',
viewport: {
width: 1,
},
}
```
Transforms into:
```js
export const metadata = {
title: 'My App',
}
### 13.2
##### `built-in-next-font`
```bash filename="Terminal"
npx @next/codemod@latest built-in-next-font .
```
For example:
```js
import { Inter } from '@next/font/google'
```
Transforms into:
```js
import { Inter } from 'next/font/google'
```
### 13.0
##### `next-image-to-legacy-image`
```bash filename="Terminal"
npx @next/codemod@latest next-image-to-legacy-image .
```
Safely renames `next/image` imports in existing Next.js 10, 11, or 12
applications to `next/legacy/image` in Next.js 13. Also renames `next/future/
image` to `next/image`.
For example:
```jsx filename="pages/index.js"
import Image1 from 'next/image'
import Image2 from 'next/future/image'
Transforms into:
```jsx filename="pages/index.js"
// 'next/image' becomes 'next/legacy/image'
import Image1 from 'next/legacy/image'
// 'next/future/image' becomes 'next/image'
import Image2 from 'next/image'
##### `next-image-experimental`
```bash filename="Terminal"
npx @next/codemod@latest next-image-experimental .
```
Dangerously migrates from `next/legacy/image` to the new `next/image` by
adding inline styles and removing unused props.
##### `new-link`
```bash filename="Terminal"
npx @next/codemod@latest new-link .
```
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
For example:
```jsx
<Link href="/about">
<a>About</a>
</Link>
// transforms into
<Link href="/about">
About
</Link>
<Link href="/about">
<a onClick={() => console.log('clicked')}>About</a>
</Link>
// transforms into
<Link href="/about" onClick={() => console.log('clicked')}>
About
</Link>
```
```jsx
const Component = () => <a>About</a>
<Link href="/about">
<Component />
</Link>
// becomes
<Link href="/about" legacyBehavior>
<Component />
</Link>
```
### 11
##### `cra-to-next`
```bash filename="Terminal"
npx @next/codemod cra-to-next
```
Migrates a Create React App project to Next.js; creating a Pages Router and
necessary config to match behavior. Client-side only rendering is leveraged
initially to prevent breaking compatibility due to `window` usage during SSR
and can be enabled seamlessly to allow the gradual adoption of Next.js specific
features.
Please share any feedback related to this transform [in this discussion](https://
github.com/vercel/next.js/discussions/25858).
### 10
##### `add-missing-react-import`
```bash filename="Terminal"
npx @next/codemod add-missing-react-import
```
Transforms files that do not import `React` to include the import in order for
the new [React JSX transform](https://reactjs.org/blog/2020/09/22/introducing-
the-new-jsx-transform.html) to work.
For example:
```jsx filename="my-component.js"
export default class Home extends React.Component {
render() {
return <div>Hello World</div>
}
}
```
Transforms into:
```jsx filename="my-component.js"
import React from 'react'
export default class Home extends React.Component {
render() {
return <div>Hello World</div>
}
}
```
### 9
##### `name-default-component`
```bash filename="Terminal"
npx @next/codemod name-default-component
```
For example:
```jsx filename="my-component.js"
export default function () {
return <div>Hello World</div>
}
```
Transforms into:
```jsx filename="my-component.js"
export default function MyComponent() {
return <div>Hello World</div>
}
```
The component will have a camel-cased name based on the name of the file,
and it also works with arrow functions.
### 8
##### `withamp-to-config`
```bash filename="Terminal"
npx @next/codemod withamp-to-config
```
For example:
```js
// Before
import { withAmp } from 'next/amp'
function Home() {
return <h1>My AMP Page</h1>
}
```js
// After
export default function Home() {
return <h1>My AMP Page</h1>
}
### 6
##### `url-to-withrouter`
```bash filename="Terminal"
npx @next/codemod url-to-withrouter
```
For example:
```js filename="From"
import React from 'react'
export default class extends React.Component {
render() {
const { pathname } = this.props.url
return <div>Current pathname: {pathname}</div>
}
}
```
```js filename="To"
import React from 'react'
import { withRouter } from 'next/router'
export default withRouter(
class extends React.Component {
render() {
const { pathname } = this.props.router
return <div>Current pathname: {pathname}</div>
}
}
)
```
This is one case. All the cases that are transformed (and tested) can be found
in the [`__testfixtures__` directory](https://github.com/vercel/next.js/tree/
canary/packages/next-codemod/transforms/__testfixtures__/url-to-withrouter).
---
title: App Router Incremental Adoption Guide
nav_title: App Router Migration
description: Learn how to upgrade your existing Next.js application from the
Pages Router to the App Router.
---
## Upgrading
To update to Next.js version 13, run the following command using your
preferred package manager:
```bash filename="Terminal"
npm install next@latest react@latest react-dom@latest
```
```bash filename="Terminal"
npm install -D eslint-config-next@latest
```
> **Good to know**: You may need to restart the ESLint server in VS Code for
the ESLint changes to take effect. Open the Command Palette (`cmd+shift+p`
on Mac; `ctrl+shift+p` on Windows) and search for `ESLint: Restart ESLint
Server`.
## Next Steps
After you've updated, see the following sections for next steps:
Upgrading to Next.js 13 does **not** require using the new [App Router](/
docs/app/building-your-application/routing#the-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).
In version 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` codemod**](/docs/app/building-your-
application/upgrading/codemods#next-image-to-legacy-image): Safely and
automatically renames `next/image` imports to `next/legacy/image`. Existing
components will maintain the same behavior.
- [**`next-image-experimental` codemod**](/docs/app/building-your-
application/upgrading/codemods#next-image-experimental): Dangerously adds
inline styles and removes unused props. This will change the behavior of
existing components to match the new defaults. To use this codemod, you need
to run the `next-image-to-legacy-image` codemod first.
### `<Link>` Component
For example:
```jsx
import Link from 'next/link'
To upgrade your links to Next.js 13, you can use the [`new-link` codemod](/
docs/app/building-your-application/upgrading/codemods#new-link).
> ** Watch:** Learn how to incrementally adopt the App Router → [YouTube
(16 minutes)](https://www.youtube.com/watch?v=YQMSietiFm0).
Moving to the App Router may be the first time using React features that
Next.js builds on top of such as Server Components, Suspense, and more.
When combined with new Next.js features such as [special files](/docs/app/
building-your-application/routing#file-conventions) and [layouts](/docs/app/
building-your-application/routing/pages-and-layouts#layouts), migration means
new concepts, mental models, and behavioral changes to learn.
- The `app` directory supports nested routes _and_ layouts. [Learn more](/
docs/app/building-your-application/routing).
- Use nested folders to [define routes](/docs/app/building-your-application/
routing/defining-routes) and a special `page.js` file to make a route segment
publicly accessible. [Learn more](#step-4-migrating-pages).
- [Special file conventions](/docs/app/building-your-application/routing#file-
conventions) are used to create UI for each route segment. The most common
special files are `page.js` and `layout.js`.
- Use `page.js` to define UI unique to a route.
- Use `layout.js` to define UI that is shared across multiple routes.
- `.js`, `.jsx`, or `.tsx` file extensions can be used for special files.
- You can colocate other files inside the `app` directory such as components,
styles, tests, and more. [Learn more](/docs/app/building-your-application/
routing).
- Data fetching functions like `getServerSideProps` and `getStaticProps` have
been replaced with [a new API](/docs/app/building-your-application/data-
fetching) inside `app`. `getStaticPaths` has been replaced with
[`generateStaticParams`](/docs/app/api-reference/functions/generate-static-
params).
- `pages/_app.js` and `pages/_document.js` have been replaced with a single
`app/layout.js` root layout. [Learn more](/docs/app/building-your-application/
routing/pages-and-layouts#root-layout-required).
- `pages/_error.js` has been replaced with more granular `error.js` special files.
[Learn more](/docs/app/building-your-application/routing/error-handling).
- `pages/404.js` has been replaced with the [`not-found.js`](/docs/app/api-
reference/file-conventions/not-found) file.
- `pages/api/*` currently remain inside the `pages` directory.
```bash
npm install next@latest
```
Then, create a new `app` directory at the root of your project (or `src/`
directory).
Create a new `app/layout.tsx` file inside the `app` directory. This is a [root
layout](/docs/app/building-your-application/routing/pages-and-layouts#root-
layout-required) that will apply to all routes inside `app`.
To manage `<head>` HTML elements, you can use the [built-in SEO support](/
docs/app/building-your-application/optimizing/metadata):
If you have an existing `_app` or `_document` file, you can copy the contents
(e.g. global styles) to the root layout (`app/layout.tsx`). Styles in `app/
layout.tsx` will _not_ apply to `pages/*`. You should keep `_app`/`_document`
while migrating to prevent your `pages/*` routes from breaking. Once fully
migrated, you can then safely delete them.
If you are using any React Context providers, they will need to be moved to a
[Client Component](/docs/app/building-your-application/rendering/client-
components).
<details>
<summary>See before and after example</summary>
**Before**
```jsx filename="components/DashboardLayout.js"
export default function DashboardLayout({ children }) {
return (
<div>
<h2>My Dashboard</h2>
{children}
</div>
)
}
```
```jsx filename="pages/dashboard/index.js"
import DashboardLayout from '../components/DashboardLayout'
**After**
```jsx filename="app/dashboard/DashboardLayout.js"
'use client' // this directive should be at top of the file, before any imports.
- Import the `DashboardLayout` into a new `layout.js` file inside the `app`
directory.
```jsx filename="app/dashboard/layout.js"
import DashboardLayout from './DashboardLayout'
</details>
**Before:**
**After:**
We recommend breaking down the migration of a page into two main steps:
- Step 1: Move the default exported Page Component into a new Client
Component.
- Step 2: Import the new Client Component into a new `page.js` file inside the
`app` directory.
> **Good to know**: This is the easiest migration path because it has the most
comparable behavior to the `pages` directory.
- Create a new separate file inside the `app` directory (i.e. `app/home-
page.tsx` or similar) that exports a Client Component. To define Client
Components, add the `'use client'` directive to the top of the file (before any
imports).
- Move the default exported page component from `pages/index.js` to `app/
home-page.tsx`.
- Create a new `app/page.tsx` file inside the `app` directory. This is a Server
Component by default.
- Import the `home-page.tsx` Client Component into the page.
- If you were fetching data in `pages/index.js`, move the data fetching logic
directly into the Server Component using the new [data fetching APIs](/docs/
app/building-your-application/data-fetching/fetching-caching-and-
revalidating). See the [data fetching upgrade guide](#step-6-migrating-data-
fetching-methods) for more details.
- If your previous page used `useRouter`, you'll need to update to the new
routing hooks. [Learn more](/docs/app/api-reference/functions/use-router).
- Start your development server and visit [`http://localhost:3000`](http://
localhost:3000). You should see your existing index route, now served through
the app directory.
In `app`, you should use the three new hooks imported from `next/navigation`:
[`useRouter()`](/docs/app/api-reference/functions/use-router),
[`usePathname()`](/docs/app/api-reference/functions/use-pathname), and
[`useSearchParams()`](/docs/app/api-reference/functions/use-search-
params).
// ...
}
```
// ...
}
```
return <div>...</div>
}
```
return <div>...</div>
}
```
```jsx filename="pages/dashboard.js"
// `pages` directory
In the `app` directory, we can colocate our data fetching inside our React
components using [Server Components](/docs/app/building-your-application/
rendering/server-components). This allows us to send less JavaScript to the
client, while maintaining the rendered HTML from the server.
By setting the `cache` option to `no-store`, we can indicate that the fetched
data should [never be cached](/docs/app/building-your-application/data-
fetching/fetching-caching-and-revalidating). This is similar to
`getServerSideProps` in the `pages` directory.
return projects
}
return (
<ul>
{projects.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
)
}
```
```jsx filename="app/dashboard/page.js" switcher
// `app` directory
return projects
}
return (
<ul>
{projects.map((project) => (
<li key={project.id}>{project.name}</li>
))}
</ul>
)
}
```
In the `pages` directory, you can retrieve request-based data based on the
Node.js HTTP API.
For example, you can retrieve the `req` object from `getServerSideProps` and
use it to retrieve the request's cookies and headers.
```jsx filename="pages/index.js"
// `pages` directory
return '...'
}
return '...'
}
```jsx filename="pages/index.js"
// `pages` directory
```jsx filename="app/page.js"
// `app` directory
return projects
}
```jsx filename="pages/posts/[id].js"
// `pages` directory
import PostLayout from '@/components/post-layout'
[`generateStaticParams`](/docs/app/api-reference/functions/generate-static-
params) behaves similarly to `getStaticPaths`, but has a simplified API for
returning route parameters and can be used inside [layouts](/docs/app/
building-your-application/routing/pages-and-layouts). The return shape of
`generateStaticParams` is an array of segments instead of an array of nested
`param` objects or a string of resolved paths.
```jsx filename="app/posts/[id]/page.js"
// `app` directory
import PostLayout from '@/components/post-layout'
return post
}
---
```jsx filename="pages/posts/[id].js"
// `pages` directory
```jsx filename="app/posts/[id]/page.js"
// `app` directory
return ...
}
```
With [`dynamicParams`](/docs/app/api-reference/file-conventions/route-
segment-config#dynamicparams) set to `true` (the default), when a route
segment is requested that hasn't been generated, it will be server-rendered
and cached.
return {
props: { posts },
revalidate: 60,
}
}
```jsx filename="app/page.js"
// `app` directory
return data.posts
}
API Routes continue to work in the `pages/api` directory without any changes.
However, they have been replaced by [Route Handlers](/docs/app/building-
your-application/routing/route-handlers) in the `app` directory.
Route Handlers allow you to create custom request handlers for a given route
using the Web [Request](https://developer.mozilla.org/docs/Web/API/Request)
and [Response](https://developer.mozilla.org/docs/Web/API/Response) APIs.
> **Good to know**: If you previously used API routes to call an external API
from the client, you can now use [Server Components](/docs/app/building-
your-application/rendering/server-components) instead to securely fetch data.
Learn more about [data fetching](/docs/app/building-your-application/data-
fetching/fetching-caching-and-revalidating).
- [CSS Modules](/docs/app/building-your-application/styling/css-modules)
- [Tailwind CSS](/docs/app/building-your-application/styling/tailwind-css)
- [Global Styles](/docs/app/building-your-application/styling/css-
modules#global-styles)
- [CSS-in-JS](/docs/app/building-your-application/styling/css-in-js)
- [External Stylesheets](/docs/app/building-your-application/styling/css-
modules#external-stylesheets)
- [Sass](/docs/app/building-your-application/styling/sass)
If you're using Tailwind CSS, you'll need to add the `app` directory to your
`tailwind.config.js` file:
```js filename="tailwind.config.js"
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}', // <-- Add this line
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
}
```
You'll also need to import your global styles in your `app/layout.js` file:
```jsx filename="app/layout.js"
import '../styles/globals.css'
## Codemods
---
title: Version 14
description: Upgrade your Next.js Application from Version 13 to 14.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
## Upgrading from 13 to 14
To update to Next.js version 14, run the following command using your
preferred package manager:
```bash filename="Terminal"
npm i next@latest react@latest react-dom@latest eslint-config-next@latest
```
```bash filename="Terminal"
yarn add next@latest react@latest react-dom@latest eslint-config-next@latest
```
```bash filename="Terminal"
pnpm up next react react-dom eslint-config-next --latest
```
```bash filename="Terminal"
bun add next@latest react@latest react-dom@latest eslint-config-next@latest
```
> **Good to know:** If you are using TypeScript, ensure you also upgrade
`@types/react` and `@types/react-dom` to their latest versions.
- The minimum Node.js version has been bumped from 16.14 to 18.17, since 16.x
has reached end-of-life.
- The `next export` command is deprecated in favor of `output: 'export'`.
Please see the [docs](https://nextjs.org/docs/app/building-your-application/
deploying/static-exports) for more information.
- The `next/server` import for `ImageResponse` was renamed to `next/og`. A
[codemod is available](/docs/app/building-your-application/upgrading/
codemods#next-og-import) to safely and automatically rename your imports.
- The `@next/font` package has been fully removed in favor of the built-in
`next/font`. A [codemod is available](/docs/app/building-your-application/
upgrading/codemods#built-in-next-font) to safely and automatically rename
your imports.
- The WASM target for `next-swc` has been removed.
---
title: Migrating from Vite
description: Learn how to migrate your existing React application from Vite to
Next.js.
---
This guide will help you migrate an existing Vite application to Next.js.
## Why Switch?
There are several reasons why you might want to switch from Vite to Next.js:
1. **Slow initial page loading time**: If you have built your application with the
[default Vite
plugin for React](https://github.com/vitejs/vite-plugin-react/tree/main/
packages/plugin-react),
your application is a purely client-side application. Client-side only
applications, also known as
single-page applications (SPAs), often experience slow initial page loading
time. This
happens due to a couple of reasons:
1. The browser needs to wait for the React code and your entire application
bundle to download
and run before your code is able to send requests to load some data.
2. Your application code grows with every new feature and extra dependency
you add.
2. **No automatic code splitting**: The previous issue of slow loading times
can be somewhat managed with code splitting.
However, if you try to do code splitting manually, you'll often make
performance worse. It's easy
to inadvertently introduce network waterfalls when code-splitting manually.
Next.js provides
automatic code splitting built into its router.
3. **Network waterfalls**: A common cause of poor performance occurs
when applications make
sequential client-server requests to fetch data. One common pattern for data
fetching in an SPA
is to initially render a placeholder, and then fetch data after the component
has mounted.
Unfortunately, this means that a child component that fetches data can't start
fetching until
the parent component has finished loading its own data. On Next.js,
[this issue is resolved](https://github.com/reactjs/rfcs/blob/main/text/0188-
server-components.md#no-client-server-waterfalls)
by fetching data in Server Components.
4. **Fast and intentional loading states**: Thanks to built-in support for
[Streaming with Suspense](/docs/app/building-your-application/routing/
loading-ui-and-streaming#streaming-with-suspense),
with Next.js, you can be more intentional about which parts of your UI you
want to load first and
in what order without introducing network waterfalls. This enables you to
build pages that are
faster to load and also eliminate [layout shifts](https://web.dev/cls/).
5. **Choose the data fetching strategy**: Depending on your needs, Next.js
allows you to choose your
data fetching strategy on a page and component basis. You can decide to
fetch at build time, at
request time on the server, or on the client. For example, you can fetch data
from your CMS and
render your blog posts at build time, which can then be efficiently cached on
a CDN.
6. **Middleware**: [Next.js Middleware](/docs/app/building-your-application/
routing/middleware)
allows you to run code on the server before a request is completed. This is
especially useful to
avoid having a flash of unauthenticated content when the user visits an
authenticated-only page
by redirecting the user to a login page. The middleware is also useful for
experimentation and
internationalization.
7. **Built-in Optimizations**: Images, fonts, and third-party scripts often have
significant impact
on an application's performance. Next.js comes with built-in components that
automatically
optimize those for you.
## Migration Steps
Our goal with this migration is to get a working Next.js application as quickly as
possible, so that
you can then adopt Next.js features incrementally. To begin with, we'll keep it
as a purely
client-side application (SPA) without migrating your existing router. This helps
minimize the
chances of encountering issues during the migration process and reduces
merge conflicts.
```bash filename="Terminal"
npm install next@latest
```
Create a `next.config.mjs` at the root of your project. This file will hold your
[Next.js configuration options](/docs/app/api-reference/next-config-js).
```js filename="next.config.mjs"
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export', // Outputs a Single-Page Application (SPA).
distDir: './dist', // Changes the build output directory to `./dist/`.
}
> **Good to know:** You can use either `.js` or `.mjs` for your Next.js
configuration file.
If you're using TypeScript, you need to update your `tsconfig.json` file with the
following changes
to make it compatible with Next.js. If you're not using TypeScript, you can skip
this step.
```json filename="tsconfig.json"
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"esModuleInterop": true,
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"plugins": [{ "name": "next" }]
},
"include": ["./src", "./dist/types/**/*.ts", "./next-env.d.ts"],
"exclude": ["./node_modules"]
}
```
The closest equivalent to the root layout file in a Vite application is the
[`index.html` file](https://vitejs.dev/guide/#index-html-and-project-root), which
contains your
`<html>`, `<head>`, and `<body>` tags.
In this step, you'll convert your `index.html` file into a root layout file:
> **Good to know**: `.js`, `.jsx`, or `.tsx` extensions can be used for Layout
files.
3. Copy the content of your `index.html` file into the previously created
`<RootLayout>` component while
replacing the `body.div#root` and `body.script` tags with `<div
id="root">{children}</div>`:
6. Finally, Next.js can manage your last `<head>` tags with the
[Metadata API](/docs/app/building-your-application/optimizing/metadata).
Move your final metadata
info into an exported
[`metadata` object](/docs/app/api-reference/functions/generate-
metadata#metadata-object):
With the above changes, you shifted from declaring everything in your
`index.html` to using Next.js'
convention-based approach built into the framework
([Metadata API](/docs/app/building-your-application/optimizing/metadata)).
This approach enables you
to more easily improve your SEO and web shareability of your pages.
Since in this guide we're aiming first to set up our Next.js as an SPA (Single
Page Application),
you need your page entrypoint to catch all possible routes of your application.
For that, create a
new `[[...slug]]` directory in your `app` directory.
> **Good to know**: `.js`, `.jsx`, or `.tsx` extensions can be used for Page
files.
```tsx
const App = dynamic(() => import('../../App'), { ssr: false })
```
Next.js handles static image imports slightly different from Vite. With Vite,
importing an image
file will return its public URL as a string:
```tsx filename="App.tsx"
import image from './img.png' // `image` will be '/assets/img.2d8efhg.png' in
production
With Next.js, static image imports return an object. The object can then be
used directly with the
Next.js [`<Image>` component](/docs/app/api-reference/components/image),
or you can use the object's
`src` property with your existing `<img>` tag.
Keeping the `<img>` tag will reduce the amount of changes in your application
and prevent the above
issues. However, you'll still want to later migrate to the `<Image>` component
to take advantage of
the automatic optimizations.
1. **Convert absolute import paths for images imported from `/public` into
relative imports:**
```tsx
// Before
import logo from '/logo.png'
// After
import logo from '../public/logo.png'
```
2. **Pass the image `src` property instead of the whole image object to
your `<img>` tag:**
```tsx
// Before
<img src={logo} />
// After
<img src={logo.src} />
```
> **Warning:** If you're using TypeScript, you might encounter type errors
when accessing the `src`
> property. You can safely ignore those for now. They will be fixed by the end of
this guide.
- `import.meta.env.MODE` `process.env.NODE_ENV`
- `import.meta.env.PROD` `process.env.NODE_ENV === 'production'`
- `import.meta.env.DEV` `process.env.NODE_ENV !== 'production'`
- `import.meta.env.SSR` `typeof window !== 'undefined'`
```bash filename=".env"
# ...
NEXT_PUBLIC_BASE_PATH="/some-base-path"
```
2. **Set [`basePath`](/docs/app/api-reference/next-config-js/basePath) to
`process.env.NEXT_PUBLIC_BASE_PATH` in your `next.config.mjs` file:**
```js filename="next.config.mjs"
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export', // Outputs a Single-Page Application (SPA).
distDir: './dist', // Changes the build output directory to `./dist/`.
basePath: process.env.NEXT_PUBLIC_BASE_PATH, // Sets the base path to `/
some-base-path`.
}
You should now be able to run your application to test if you successfully
migrated to Next.js. But
before that, you need to update your `scripts` in your `package.json` with
Next.js related commands,
and add `.next` and `next-env.d.ts` to your `.gitignore`:
```json filename="package.json"
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}
```
```txt filename=".gitignore"
# ...
.next
next-env.d.ts
```
You can now clean up your codebase from Vite related artifacts:
- Delete `main.tsx`
- Delete `index.html`
- Delete `vite-env.d.ts`
- Delete `tsconfig.node.json`
- Delete `vite.config.ts`
- Uninstall Vite dependencies
## Next Steps
---
title: Upgrade Guide
nav_title: Upgrading
description: Learn how to upgrade to the latest versions of Next.js.
---
---
title: Building Your Application
description: Learn how to use Next.js features to build your application.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
The sections and pages are organized sequentially, from basic to advanced, so
you can follow them step-by-step when building your Next.js application.
However, you can read them in any order or skip to the pages that apply to your
use case.
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
---
title: <Script>
description: Optimize third-party scripts in your Next.js application using the
built-in `next/script` Component.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
This API reference will help you understand how to use [props](#props)
available for the Script Component. For features and usage, please see the
[Optimizing Scripts](/docs/app/building-your-application/optimizing/scripts)
page.
## Props
## Required Props
### `src`
A path string specifying the URL of an external script. This can be either an
absolute external URL or an internal path. The `src` property is required unless
an inline script is used.
## Optional Props
### `strategy`
The loading strategy of the script. There are four different strategies that can
be used:
- `beforeInteractive`: Load before any Next.js code and before any page
hydration occurs.
- `afterInteractive`: (**default**) Load early but after some hydration on the
page occurs.
- `lazyOnload`: Load during browser idle time.
- `worker`: (experimental) Load in a web worker.
### `beforeInteractive`
Scripts that load with the `beforeInteractive` strategy are injected into the
initial HTML from the server, downloaded before any Next.js module, and
executed in the order they are placed before _any_ hydration occurs on the
page.
Scripts denoted with this strategy are preloaded and fetched before any first-
party code, but their execution does not block page hydration from occurring.
**This strategy should only be used for critical scripts that need to be
fetched before any part of the page becomes interactive.**
<AppOnly>
</AppOnly>
<PagesOnly>
```jsx
import { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'
</PagesOnly>
- Bot detectors
- Cookie consent managers
### `afterInteractive`
Scripts that use the `afterInteractive` strategy are injected into the HTML
client-side and will load after some (or all) hydration occurs on the page. **This
is the default strategy** of the Script component and should be used for any
script that needs to load as soon as possible but not before any first-party
Next.js code.
`afterInteractive` scripts can be placed inside of any page or layout and will
only load and execute when that page (or group of pages) is opened in the
browser.
```jsx filename="app/page.js"
import Script from 'next/script'
- Tag managers
- Analytics
### `lazyOnload`
Scripts that use the `lazyOnload` strategy are injected into the HTML client-
side during browser idle time and will load after all resources on the page have
been fetched. This strategy should be used for any background or low priority
scripts that do not need to load early.
`lazyOnload` scripts can be placed inside of any page or layout and will only
load and execute when that page (or group of pages) is opened in the browser.
```jsx filename="app/page.js"
import Script from 'next/script'
Examples of scripts that do not need to load immediately and can be fetched
with `lazyOnload` include:
### `worker`
> **Warning:** The `worker` strategy is not yet stable and does not yet work
with the [`app`](/docs/app/building-your-application/routing/defining-routes)
directory. Use with caution.
Scripts that use the `worker` strategy are off-loaded to a web worker in order
to free up the main thread and ensure that only critical, first-party resources
are processed on it. While this strategy can be used for any script, it is an
advanced use case that is not guaranteed to support all third-party scripts.
```js filename="next.config.js"
module.exports = {
experimental: {
nextScriptWorkers: true,
},
}
```
### `onLoad`
> **Warning:** `onLoad` does not yet work with Server Components and can
only be used in Client Components. Further, `onLoad` can't be used with
`beforeInteractive` – consider using `onReady` instead.
Some third-party scripts require users to run JavaScript code once after the
script has finished loading in order to instantiate content or call a function. If
you are loading a script with either afterInteractive or lazyOnload as a loading
strategy, you can execute code after it has loaded using the onLoad property.
Here's an example of executing a lodash method only after the library has been
loaded.
### `onReady`
> **Warning:** `onReady` does not yet work with Server Components and can
only be used in Client Components.
Some third-party scripts require users to run JavaScript code after the script
has finished loading and every time the component is mounted (after a route
navigation for example). You can execute code after the script's load event
when it first loads and then after every subsequent component re-mount using
the onReady property.
<AppOnly>
return (
<>
<div ref={mapRef}></div>
<Script
id="google-maps"
src="https://maps.googleapis.com/maps/api/js"
onReady={() => {
new google.maps.Map(mapRef.current, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
})
}}
/>
</>
)
}
```
return (
<>
<div ref={mapRef}></div>
<Script
id="google-maps"
src="https://maps.googleapis.com/maps/api/js"
onReady={() => {
new google.maps.Map(mapRef.current, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
})
}}
/>
</>
)
}
```
</AppOnly>
<PagesOnly>
```jsx
import { useRef } from 'react';
import Script from 'next/script';
return (
<PagesOnly>
<div ref={mapRef}></div>
<Script
id="google-maps"
src="https://maps.googleapis.com/maps/api/js"
onReady={() => {
new google.maps.Map(mapRef.current, {
center: { lat: -34.397, lng: 150.644 },
zoom: 8,
});
}}
/>
</>
);
}
```
</PagesOnly>
### `onError`
> **Warning:** `onError` does not yet work with Server Components and can
only be used in Client Components. `onError` cannot be used with the
`beforeInteractive` loading strategy.
Sometimes it is helpful to catch when a script fails to load. These errors can be
handled with the onError property:
<AppOnly>
</AppOnly>
<PagesOnly>
```jsx
import Script from 'next/script'
</PagesOnly>
## Version History
| Version | Changes |
| --------- |
------------------------------------------------------------------------- |
| `v13.0.0` | `beforeInteractive` and `afterInteractive` is modified to support
`app`. |
| `v12.2.4` | `onReady` prop added. |
| `v12.2.2` | Allow `next/script` with `beforeInteractive` to be placed in
`_document`. |
| `v11.0.0` | `next/script` introduced. |
---
title: <Link>
description: Enable fast client-side navigation with the built-in `next/link`
component.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<PagesOnly>
<details>
<summary>Examples</summary>
- [Hello World](https://github.com/vercel/next.js/tree/canary/examples/hello-
world)
- [Active className on Link](https://github.com/vercel/next.js/tree/canary/
examples/active-class-name)
</details>
</PagesOnly>
<AppOnly>
</AppOnly>
<PagesOnly>
- `pages/index.js`
- `pages/about.js`
- `pages/blog/[slug].js`
```jsx
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/about">About Us</Link>
</li>
<li>
<Link href="/blog/hello-world">Blog Post</Link>
</li>
</ul>
)
}
</PagesOnly>
## Props
```jsx
<Link href="/dashboard">Dashboard</Link>
```
```jsx
// Navigate to /about?name=test
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About
</Link>
```
### `replace`
### `scroll`
### `prefetch`
<PagesOnly>
## Other Props
### `legacyBehavior`
> **Good to know**: when `legacyBehavior` is not set to `true`, all [`anchor`]
(https://developer.mozilla.org/docs/Web/HTML/Element/a) tag properties can
be passed to `next/link` as well such as, `className`, `onClick`, etc.
### `passHref`
Forces `Link` to send the `href` property to its child. Defaults to `false`
### `scroll`
### `shallow`
### `locale`
</PagesOnly>
## Examples
### Linking to Dynamic Routes
For dynamic routes, it can be handy to use template literals to create the link's
path.
<PagesOnly>
For example, you can generate a list of links to the dynamic route `pages/blog/
[slug].js`
```jsx filename="pages/blog/index.js"
import Link from 'next/link'
</PagesOnly>
<AppOnly>
For example, you can generate a list of links to the dynamic route `app/blog/
[slug]/page.js`:
```jsx filename="app/blog/page.js"
import Link from 'next/link'
</AppOnly>
<PagesOnly>
<AppOnly>
If the child of `Link` is a custom component that wraps an `<a>` tag, you must
add `passHref` to `Link`. This is necessary if you’re using libraries like [styled-
components](https://styled-components.com/). Without this, the `<a>` tag will
not have the `href` attribute, which hurts your site's accessibility and might
affect SEO. If you're using [ESLint](/docs/app/building-your-application/
configuring/eslint#eslint-plugin), there is a built-in rule `next/link-passhref` to
ensure correct usage of `passHref`.
</AppOnly>
<PagesOnly>
If the child of `Link` is a custom component that wraps an `<a>` tag, you must
add `passHref` to `Link`. This is necessary if you’re using libraries like [styled-
components](https://styled-components.com/). Without this, the `<a>` tag will
not have the `href` attribute, which hurts your site's accessibility and might
affect SEO. If you're using [ESLint](/docs/pages/building-your-application/
configuring/eslint#eslint-plugin), there is a built-in rule `next/link-passhref` to
ensure correct usage of `passHref`.
</PagesOnly>
```jsx
import Link from 'next/link'
import styled from 'styled-components'
```jsx
import Link from 'next/link'
function Home() {
return (
<Link href="/about" passHref legacyBehavior>
<MyButton />
</Link>
)
}
`Link` can also receive a URL object and it will automatically format it to create
the URL string. Here's how to do it:
```jsx
import Link from 'next/link'
function Home() {
return (
<ul>
<li>
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About us
</Link>
</li>
<li>
<Link
href={{
pathname: '/blog/[slug]',
query: { slug: 'my-post' },
}}
>
Blog Post
</Link>
</li>
</ul>
)
}
You can use every property as defined in the [Node.js URL module
documentation](https://nodejs.org/api/
url.html#url_url_strings_and_url_objects).
The default behavior of the `Link` component is to `push` a new URL into the
`history` stack. You can use the `replace` prop to prevent adding a new entry,
as in the following example:
```jsx
<Link href="/about" replace>
About us
</Link>
```
The default behavior of `Link` is to scroll to the top of the page. When there is
a hash defined it will scroll to the specific id, like a normal `<a>` tag. To prevent
scrolling to the top / hash `scroll={false}` can be added to `Link`:
```jsx
<Link href="/#hashid" scroll={false}>
Disables scrolling to the top
</Link>
```
</PagesOnly>
### Middleware
For example, if you want to serve a `/dashboard` route that has authenticated
and visitor views, you may add something similar to the following in your
Middleware to redirect the user to the correct page:
```js filename="middleware.js"
export function middleware(req) {
const nextUrl = req.nextUrl
if (nextUrl.pathname === '/dashboard') {
if (req.cookies.authToken) {
return NextResponse.rewrite(new URL('/auth/dashboard', req.url))
} else {
return NextResponse.rewrite(new URL('/public/dashboard', req.url))
}
}
}
```
In this case, you would want to use the following code in your `<Link />`
component:
```js
import Link from 'next/link'
import useIsAuthed from './hooks/useIsAuthed'
<PagesOnly>
</PagesOnly>
## Version History
| Version | Changes
|
| --------- |
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--------------------------------- |
| `v13.0.0` | No longer requires a child `<a>` tag. A [codemod](/docs/app/
building-your-application/upgrading/codemods#remove-a-tags-from-link-
components) is provided to automatically update your codebase. |
| `v10.0.0` | `href` props pointing to a dynamic route are automatically resolved
and no longer require an `as` prop.
|
| `v8.0.0` | Improved prefetching performance.
|
| `v1.0.0` | `next/link` introduced.
|
---
title: <Image>
description: Optimize Images in your Next.js Application using the built-in
`next/image` Component.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<details>
<summary>Examples</summary>
- [Image Component](https://github.com/vercel/next.js/tree/canary/examples/
image-component)
</details>
<PagesOnly>
> **Good to know**: If you are using a version of Next.js prior to 13, you'll want
to use the [next/legacy/image](/docs/pages/api-reference/components/image-
legacy) documentation since the component was renamed.
</PagesOnly>
This API reference will help you understand how to use [props](#props) and
[configuration options](#configuration-options) available for the Image
Component. For features and usage, please see the [Image Component](/docs/
app/building-your-application/optimizing/images) page.
```jsx filename="app/page.js"
import Image from 'next/image'
## Props
## Required Props
The Image Component requires the following properties: `src`, `width`,
`height`, and `alt`.
```jsx filename="app/page.js"
import Image from 'next/image'
### `src`
- A [statically imported](/docs/app/building-your-application/optimizing/
images#local-images) image file
- A path string. This can be either an absolute external URL, or an internal path
depending on the [loader](#loader) prop.
### `width`
The `width` property represents the _rendered_ width in pixels, so it will affect
how large the image appears.
### `height`
### `alt`
The `alt` property is used to describe the image for screen readers and search
engines. It is also the fallback text if images have been disabled or an error
occurs while loading the image.
It should contain text that could replace the image [without changing the
meaning of the page](https://html.spec.whatwg.org/multipage/
images.html#general-guidelines). It is not meant to supplement the image and
should not repeat information that is already provided in the captions above or
below the image.
[Learn more](https://html.spec.whatwg.org/multipage/images.html#alt)
## Optional Props
### `loader`
A `loader` is a function returning a URL string for the image, given the following
parameters:
- [`src`](#src)
- [`width`](#width)
- [`quality`](#quality)
```js
'use client'
import Image from 'next/image'
<AppOnly>
> **Good to know**: Using props like `loader`, which accept a function, require
using [Client Components](/docs/app/building-your-application/rendering/
client-components) to serialize the provided function.
</AppOnly>
### `fill`
```js
fill={true} // {true} | {false}
```
A boolean that causes the image to fill the parent element, which is useful when
the [`width`](#width) and [`height`](#height) are unknown.
Alternatively, `object-fit: "cover"` will cause the image to fill the entire
container and be cropped to preserve aspect ratio. For this to look correct, the
`overflow: "hidden"` style should be assigned to the parent element.
- [`position`](https://developer.mozilla.org/docs/Web/CSS/position)
- [`object-fit`](https://developer.mozilla.org/docs/Web/CSS/object-fit)
- [`object-position`](https://developer.mozilla.org/docs/Web/CSS/object-
position)
### `sizes`
A string, similar to a media query, that provides information about how wide the
image will be at different breakpoints. The value of `sizes` will greatly affect
performance for images using [`fill`](#fill) or which are [styled to have a
responsive size](#responsive-images).
- First, the value of `sizes` is used by the browser to determine which size of
the image to download, from `next/image`'s automatically generated `srcset`.
When the browser chooses, it does not yet know the size of the image on the
page, so it selects an image that is the same size or larger than the viewport.
The `sizes` property allows you to tell the browser that the image will actually
be smaller than full screen. If you don't specify a `sizes` value in an image with
the `fill` property, a default value of `100vw` (full screen width) is used.
- Second, the `sizes` property changes the behavior of the automatically
generated `srcset` value. If no `sizes` value is present, a small `srcset` is
generated, suitable for a fixed-size image (1x/2x/etc). If `sizes` is defined, a
large `srcset` is generated, suitable for a responsive image (640w/750w/etc). If
the `sizes` property includes sizes such as `50vw`, which represent a
percentage of the viewport width, then the `srcset` is trimmed to not include
any values which are too small to ever be necessary.
For example, if you know your styling will cause an image to be full-width on
mobile devices, in a 2-column layout on tablets, and a 3-column layout on
desktop displays, you should include a sizes property such as the following:
```jsx
import Image from 'next/image'
export default function Page() {
return (
<div className="grid-element">
<Image
fill
src="/example.png"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
)
}
```
- [web.dev](https://web.dev/learn/design/responsive-images/#sizes)
- [mdn](https://developer.mozilla.org/docs/Web/HTML/Element/img#attr-sizes)
### `quality`
```js
quality={75} // {number 1-100}
```
The quality of the optimized image, an integer between `1` and `100`, where
`100` is the best quality and therefore largest file size. Defaults to `75`.
### `priority`
```js
priority={false} // {false} | {true}
```
You should use the `priority` property on any image detected as the [Largest
Contentful Paint (LCP)](https://nextjs.org/learn/seo/web-performance/lcp)
element. It may be appropriate to have multiple priority images, as different
images may be the LCP element for different viewport sizes.
Should only be used when the image is visible above the fold. Defaults to
`false`.
### `placeholder`
```js
placeholder = 'empty' // "empty" | "blur" | "data:image/..."
```
A placeholder to use while the image is loading. Possible values are `blur`,
`empty`, or `data:image/...`. Defaults to `empty`.
When `empty`, there will be no placeholder while the image is loading, only
empty space.
Try it out:
## Advanced Props
In some cases, you may need more advanced usage. The `<Image />`
component optionally accepts the following advanced properties.
### `style`
Allows passing CSS styles to the underlying image element.
```jsx filename="components/ProfileImage.js"
const imageStyle = {
borderRadius: '50%',
border: '1px solid #fff',
}
Remember that the required width and height props can interact with your
styling. If you use styling to modify an image's width, you should also style its
height to `auto` to preserve its intrinsic aspect ratio, or your image will be
distorted.
### `onLoadingComplete`
```jsx
'use client'
A callback function that is invoked once the image is completely loaded and the
[placeholder](#placeholder) has been removed.
The callback function will be called with one argument, a reference to the
underlying `<img>` element.
<AppOnly>
</AppOnly>
### `onLoad`
```jsx
<Image onLoad={(e) => console.log(e.target.naturalWidth)} />
```
A callback function that is invoked once the image is completely loaded and the
[placeholder](#placeholder) has been removed.
The callback function will be called with one argument, the Event which has a
`target` that references the underlying `<img>` element.
<AppOnly>
> **Good to know**: Using props like `onLoad`, which accept a function,
require using [Client Components](/docs/app/building-your-application/
rendering/client-components) to serialize the provided function.
</AppOnly>
### `onError`
```jsx
<Image onError={(e) => console.error(e.target.id)} />
```
<AppOnly>
> **Good to know**: Using props like `onError`, which accept a function,
require using [Client Components](/docs/app/building-your-application/
rendering/client-components) to serialize the provided function.
</AppOnly>
### `loading`
> **Recommendation**: This property is only meant for advanced use cases.
Switching an image to load with `eager` will normally **hurt performance**. We
recommend using the [`priority`](#priority) property instead, which will eagerly
preload the image.
```js
loading = 'lazy' // {lazy} | {eager}
```
When `lazy`, defer loading the image until it reaches a calculated distance from
the viewport.
When `eager`, load the image immediately.
### `blurDataURL`
A [Data URL](https://developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/
Data_URIs) to
be used as a placeholder image before the `src` image successfully loads. Only
takes effect when combined
with [`placeholder="blur"`](#placeholder).
Try it out:
### `unoptimized`
```js
unoptimized = {false} // {false} | {true}
```
When true, the source image will be served as-is instead of changing quality,
size, or format. Defaults to `false`.
```js
import Image from 'next/image'
Since Next.js 12.3.0, this prop can be assigned to all images by updating
`next.config.js` with the following configuration:
```js filename="next.config.js"
module.exports = {
images: {
unoptimized: true,
},
}
```
## Configuration Options
### `remotePatterns`
```js filename="next.config.js"
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
port: '',
pathname: '/account123/**',
},
],
},
}
```
> **Good to know**: The example above will ensure the `src` property of `next/
image` must start with `https://example.com/account123/`. Any other protocol,
hostname, port, or unmatched path will respond with 400 Bad Request.
```js filename="next.config.js"
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '**.example.com',
},
],
},
}
```
> **Good to know**: The example above will ensure the `src` property of `next/
image` must start with `https://img1.example.com` or `https://
me.avatar.example.com` or any number of subdomains. Any other protocol or
unmatched hostname will respond with 400 Bad Request.
Wildcard patterns can be used for both `pathname` and `hostname` and have
the following syntax:
The `**` syntax does not work in the middle of the pattern.
### `domains`
```js filename="next.config.js"
module.exports = {
images: {
domains: ['assets.acme.com'],
},
}
```
### `loaderFile`
If you want to use a cloud provider to optimize images instead of using the
Next.js built-in Image Optimization API, you can configure the `loaderFile` in
your `next.config.js` like the following:
```js filename="next.config.js"
module.exports = {
images: {
loader: 'custom',
loaderFile: './my/image/loader.js',
},
}
```
This must point to a file relative to the root of your Next.js application. The file
must export a default function that returns a string, for example:
```js
'use client'
Examples:
<AppOnly>
> **Good to know**: Customizing the image loader file, which accepts a
function, require using [Client Components](/docs/app/building-your-
application/rendering/client-components) to serialize the provided function.
</AppOnly>
## Advanced
The following configuration is for advanced use cases and is usually not
necessary. If you choose to configure the properties below, you will override
any changes to the Next.js defaults in future updates.
### `deviceSizes`
If you know the expected device widths of your users, you can specify a list of
device width breakpoints using the `deviceSizes` property in `next.config.js`.
These widths are used when the `next/image` component uses [`sizes`]
(#sizes) prop to ensure the correct image is served for user's device.
```js filename="next.config.js"
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
}
```
### `imageSizes`
You can specify a list of image widths using the `images.imageSizes` property
in your `next.config.js` file. These widths are concatenated with the array of
[device sizes](#devicesizes) to form the full array of sizes used to generate
image [srcset](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/
srcset)s.
The reason there are two separate lists is that imageSizes is only used for
images which provide a [`sizes`](#sizes) prop, which indicates that the image
is less than the full width of the screen. **Therefore, the sizes in imageSizes
should all be smaller than the smallest size in deviceSizes.**
```js filename="next.config.js"
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
}
```
### `formats`
If the `Accept` head matches more than one of the configured formats, the first
match in the array is used. Therefore, the array order matters. If there is no
match (or the source image is [animated](#animated-images)), the Image
Optimization API will fallback to the original image's format.
```js filename="next.config.js"
module.exports = {
images: {
formats: ['image/webp'],
},
}
```
```js filename="next.config.js"
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
}
```
## Caching Behavior
The following describes the caching algorithm for the default [loader](#loader).
For all other loaders, please refer to your cloud provider's documentation.
Images are optimized dynamically upon request and stored in the `<distDir>/
cache/images` directory. The optimized image file will be served for
subsequent requests until the expiration is reached. When a request is made
that matches a cached but expired file, the expired image is served stale
immediately. Then the image is optimized again in the background (also called
revalidation) and saved to the cache with the new expiration date.
The cache status of an image can be determined by reading the value of the
`x-nextjs-cache` response header. The possible values are the following:
- `MISS` - the path is not in the cache (occurs at most once, on the first visit)
- `STALE` - the path is in the cache but exceeded the revalidate time so it will
be updated in the background
- `HIT` - the path is in the cache and has not exceeded the revalidate time
### `minimumCacheTTL`
You can configure the Time to Live (TTL) in seconds for cached optimized
images. In many cases, it's better to use a [Static Image Import](/docs/app/
building-your-application/optimizing/images#local-images) which will
automatically hash the file contents and cache the image forever with a
`Cache-Control` header of `immutable`.
```js filename="next.config.js"
module.exports = {
images: {
minimumCacheTTL: 60,
},
}
```
The expiration (or rather Max Age) of the optimized image is defined by either
the `minimumCacheTTL` or the upstream image `Cache-Control` header,
whichever is larger.
If you need to change the caching behavior per image, you can configure
[`headers`](/docs/app/api-reference/next-config-js/headers) to set the
`Cache-Control` header on the upstream image (e.g. `/some-asset.jpg`, not `/
_next/image` itself).
There is no mechanism to invalidate the cache at this time, so its best to keep
`minimumCacheTTL` low. Otherwise you may need to manually change the
[`src`](#src) prop or delete `<distDir>/cache/images`.
### `disableStaticImages`
The default behavior allows you to import static files such as `import icon from
'./icon.png'` and then pass that to the `src` property.
In some cases, you may wish to disable this feature if it conflicts with other
plugins that expect the import to behave differently.
```js filename="next.config.js"
module.exports = {
images: {
disableStaticImages: true,
},
}
```
### `dangerouslyAllowSVG`
The default [loader](#loader) does not optimize SVG images for a few reasons.
First, SVG is a vector format meaning it can be resized losslessly. Second, SVG
has many of the same features as HTML/CSS, which can lead to vulnerabilities
without a proper [Content Security Policy](/docs/app/building-your-application/
configuring/content-security-policy).
If you need to serve SVG images with the default Image Optimization API, you
can set `dangerouslyAllowSVG` inside your `next.config.js`:
```js filename="next.config.js"
module.exports = {
images: {
dangerouslyAllowSVG: true,
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
}
```
## Animated Images
Auto-detection for animated files is best-effort and supports GIF, APNG, and
WebP. If you want to explicitly bypass Image Optimization for a given animated
image, use the [unoptimized](#unoptimized) prop.
## Responsive Images
The default generated `srcset` contains `1x` and `2x` images in order to
support different device pixel ratios. However, you may wish to render a
responsive image that stretches with the viewport. In that case, you'll need to
set [`sizes`](#sizes) as well as `style` (or `className`).
You can render a responsive image using one of the following methods below.
If the source image is not dynamic, you can statically import to create a
responsive image:
```jsx filename="components/author.js"
import Image from 'next/image'
import me from '../photos/me.jpg'
Try it out:
If the source image is a dynamic or a remote url, you will also need to provide
`width` and `height` to set the correct aspect ratio of the responsive image:
```jsx filename="components/page.js"
import Image from 'next/image'
Try it out:
If you don't know the aspect ratio, you will need to set the [`fill`](#fill) prop and
set `position: relative` on the parent. Optionally, you can set `object-fit` style
depending on the desired stretch vs crop behavior:
```jsx filename="app/page.js"
import Image from 'next/image'
Try it out:
## Theme Detection
If you want to display a different image for light and dark mode, you can create
a new component that wraps two `<Image>` components and reveals the
correct one based on a CSS media query.
```css filename="components/theme-image.module.css"
.imgDark {
display: none;
}
return (
<>
<Image {...rest} src={srcLight} className={styles.imgLight} />
<Image {...rest} src={srcDark} className={styles.imgDark} />
</>
)
}
```
return (
<>
<Image {...rest} src={srcLight} className={styles.imgLight} />
<Image {...rest} src={srcDark} className={styles.imgDark} />
</>
)
}
```
> **Good to know**: The default behavior of `loading="lazy"` ensures that only
the correct image is loaded. You cannot use `priority` or `loading="eager"`
because that would cause both images to load. Instead, you can use
[`fetchPriority="high"`](https://developer.mozilla.org/docs/Web/API/
HTMLImageElement/fetchPriority).
Try it out:
## Version History
| Version | Changes
|
| ---------- |
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
------------------- |
| `v14.0.0` | `onLoadingComplete` prop and `domains` config deprecated.
|
| `v13.4.14` | `placeholder` prop support for `data:/image...`
|
| `v13.2.0` | `contentDispositionType` configuration added.
|
| `v13.0.6` | `ref` prop added.
|
| `v13.0.0` | 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/app/building-your-application/upgrading/codemods#next-
image-to-legacy-image) to safely and automatically rename your imports.
`<span>` wrapper removed. `layout`, `objectFit`, `objectPosition`,
`lazyBoundary`, `lazyRoot` props removed. `alt` is required.
`onLoadingComplete` receives reference to `img` element. Built-in loader
config removed. |
| `v12.3.0` | `remotePatterns` and `unoptimized` configuration is stable.
|
| `v12.2.0` | Experimental `remotePatterns` and experimental `unoptimized`
configuration added. `layout="raw"` removed.
|
| `v12.1.1` | `style` prop added. Experimental support for `layout="raw"`
added.
|
| `v12.1.0` | `dangerouslyAllowSVG` and `contentSecurityPolicy` configuration
added.
|
| `v12.0.9` | `lazyRoot` prop added.
|
| `v12.0.0` | `formats` configuration added.<br/>AVIF support added.<br/
>Wrapper `<div>` changed to `<span>`.
|
| `v11.1.0` | `onLoadingComplete` and `lazyBoundary` props added.
|
| `v11.0.0` | `src` prop support for static import.<br/>`placeholder` prop
added.<br/>`blurDataURL` prop added.
|
| `v10.0.5` | `loader` prop added.
|
| `v10.0.1` | `layout` prop added.
|
| `v10.0.0` | `next/image` introduced.
|
---
title: Font Module
nav_title: Font
description: Optimizing loading web fonts with the built-in `next/font` loaders.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
This API reference will help you understand how to use [`next/font/google`](/
docs/app/building-your-application/optimizing/fonts#google-fonts) and [`next/
font/local`](/docs/app/building-your-application/optimizing/fonts#local-fonts).
For features and usage, please see the [Optimizing Fonts](/docs/app/building-
your-application/optimizing/fonts) page.
### `src`
The path of the font file as a string or an array of objects (with type
`Array<{path: string, weight?: string, style?: string}>`) relative to the directory
where the font loader function is called.
Used in `next/font/local`
- Required
Examples:
### `weight`
- A string with possible values of the weights available for the specific font or a
range of values if it's a [variable](https://fonts.google.com/variablefonts) font
- An array of weight values if the font is not a [variable google font](https://
fonts.google.com/variablefonts). It applies to `next/font/google` only.
Examples:
- `weight: '400'`: A string for a single weight value - for the font [`Inter`]
(https://fonts.google.com/specimen/Inter?query=inter), the possible values are
`'100'`, `'200'`, `'300'`, `'400'`, `'500'`, `'600'`, `'700'`, `'800'`, `'900'` or
`'variable'` where `'variable'` is the default)
- `weight: '100 900'`: A string for the range between `100` and `900` for a
variable font
- `weight: ['100','400','900']`: An array of 3 possible values for a non variable
font
### `style`
- A string [value](https://developer.mozilla.org/docs/Web/CSS/font-
style#values) with default value of `'normal'`
- An array of style values if the font is not a [variable google font](https://
fonts.google.com/variablefonts). It applies to `next/font/google` only.
- Optional
Examples:
### `subsets`
Used in `next/font/google`
- Optional
Examples:
You can find a list of all subsets on the Google Fonts page for your font.
### `axes`
Some variable fonts have extra `axes` that can be included. By default, only the
font weight is included to keep the file size down. The possible values of `axes`
depend on the specific font.
Used in `next/font/google`
- Optional
Examples:
- `axes: ['slnt']`: An array with value `slnt` for the `Inter` variable font which
has `slnt` as additional `axes` as shown [here](https://fonts.google.com/
variablefonts?vfquery=inter#font-families). You can find the possible `axes`
values for your font by using the filter on the [Google variable fonts page]
(https://fonts.google.com/variablefonts#font-families) and looking for axes
other than `wght`
### `display`
- Optional
Examples:
### `preload`
- Optional
Examples:
- `preload: false`
### `fallback`
The fallback font to use if the font cannot be loaded. An array of strings of
fallback fonts with no default.
- Optional
Examples:
- `fallback: ['system-ui', 'arial']`: An array setting the fallback fonts to `system-
ui` or `arial`
### `adjustFontFallback`
- Optional
Examples:
### `variable`
A string value to define the CSS variable name to be used if the style is applied
with the [CSS variable method](#css-variables).
- Optional
Examples:
### `declarations`
Used in `next/font/local`
- Optional
Examples:
- `declarations: [{ prop: 'ascent-override', value: '90%' }]`
## Applying Styles
- [`className`](#classname)
- [`style`](#style-1)
- [CSS Variables](#css-variables)
### `className`
```tsx
<p className={inter.className}>Hello, Next.js!</p>
```
### `style`
Returns a read-only CSS `style` object for the loaded font to be passed to an
HTML element, including `style.fontFamily` to access the font family name and
fallback fonts.
```tsx
<p style={inter.style}>Hello World</p>
```
If you would like to set your styles in an external style sheet and specify
additional options there, use the CSS variable method.
In addition to importing the font, also import the CSS file where the CSS
variable is defined and set the variable option of the font loader object as
follows:
To use the font, set the `className` of the parent container of the text you
would like to style to the font loader's `variable` value and the `className` of
the text to the `styles` property from the external CSS file.
```css filename="styles/component.module.css"
.text {
font-family: var(--font-inter);
font-weight: 200;
font-style: italic;
}
```
In the example above, the text `Hello World` is styled using the `Inter` font and
the generated font fallback with `font-weight: 200` and `font-style: italic`.
Every time you call the `localFont` or Google font function, that font will be
hosted as one instance in your application. Therefore, if you need to use the
same font in multiple places, you should load it in one place and import the
related font object where you need it. This is done using a font definitions file.
For example, create a `fonts.ts` file in a `styles` folder at the root of your app
directory.
To make it easier to access the font definitions in your code, you can define a
path alias in your `tsconfig.json` or `jsconfig.json` files as follows:
```json filename="tsconfig.json"
{
"compilerOptions": {
"paths": {
"@/fonts": ["./styles/fonts"]
}
}
}
```
## Version Changes
| Version | Changes |
| --------- |
--------------------------------------------------------------------- |
| `v13.2.0` | `@next/font` renamed to `next/font`. Installation no longer
required. |
| `v13.0.0` | `@next/font` was added. |
---
title: Components
description: API Reference for Next.js built-in components.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
---
title: favicon, icon, and apple-icon
description: API Reference for the Favicon, Icon and Apple Icon file
conventions.
---
The `favicon`, `icon`, or `apple-icon` file conventions allow you to set icons
for your application.
They are useful for adding app icons that appear in places like web browser
tabs, phone home screens, and search engine results.
Use an image file to set an app icon by placing a `favicon`, `icon`, or `apple-
icon` image file within your `/app` directory.
The `favicon` image can only be located in the top level of `app/`.
Next.js will evaluate the file and automatically add the appropriate tags to your
app's `<head>` element.
### `favicon`
### `icon`
### `apple-icon`
// Image metadata
export const size = {
width: 32,
height: 32,
}
export const contentType = 'image/png'
// Image generation
export default function Icon() {
return new ImageResponse(
(
// ImageResponse JSX element
<div
style={{
fontSize: 24,
background: 'black',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
}}
>
A
</div>
),
// ImageResponse options
{
// For convenience, we can re-use the exported icons size metadata
// config to also set the ImageResponse's width and height.
...size,
}
)
}
```
// Image metadata
export const size = {
width: 32,
height: 32,
}
export const contentType = 'image/png'
// Image generation
export default function Icon() {
return new ImageResponse(
(
// ImageResponse JSX element
<div
style={{
fontSize: 24,
background: 'black',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
}}
>
A
</div>
),
// ImageResponse options
{
// For convenience, we can re-use the exported icons size metadata
// config to also set the ImageResponse's width and height.
...size,
}
)
}
```
### Props
### Returns
You can optionally configure the icon's metadata by exporting `size` and
`contentType` variables from the `icon` or `apple-icon` route.
| Option | Type
|
| ----------------------------- |
-------------------------------------------------------------------------------
-------------------------------- |
| [`size`](#size) | `{ width: number; height: number }`
|
| [`contentType`](#contenttype) | `string` - [image MIME type](https://
developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/
MIME_types#image_types) |
#### `size`
#### `contentType`
| Option | Type
| Default |
|
-------------------------------------------------------------------------------
------------------- | -------------------------------------------------------- |
---------- |
| [`dynamic`](/docs/app/api-reference/file-conventions/route-segment-
config#dynamic) | `'auto' \| 'force-dynamic' \| 'error' \| 'force-static'` |
`'auto'` |
| [`revalidate`](/docs/app/api-reference/file-conventions/route-segment-
config#revalidate) | `false \| 'force-cache' \| 0 \| number` |
`false` |
| [`runtime`](/docs/app/api-reference/file-conventions/route-segment-
config#runtime) | `'nodejs' \| 'edge'` | `'nodejs'`
|
| [`preferredRegion`](/docs/app/api-reference/file-conventions/route-segment-
config#preferredregion) | `'auto' \| 'global' \| 'home' \| string \| string[]` |
`'auto'` |
## Version History
| Version | Changes |
| --------- | -------------------------------------------- |
| `v13.3.0` | `favicon` `icon` and `apple-icon` introduced |
---
title: Metadata Files API Reference
nav_title: Metadata Files
description: API documentation for the metadata file conventions.
---
Each file convention can be defined using a static file (e.g. `opengraph-
image.jpg`), or a dynamic variant that uses code to generate the file (e.g.
`opengraph-image.js`).
Once a file is defined, Next.js will automatically serve the file (with hashes in
production for caching) and update the relevant head elements with the correct
metadata, such as the asset's URL, file type, and image size.
---
title: manifest.json
description: API Reference for manifest.json file.
---
The manifest object contains an extensive list of options that may be updated
due to new web standards. For information on all the current options, refer to
the `MetadataRoute.Manifest` type in your code editor if using [TypeScript]
(https://nextjs.org/docs/app/building-your-application/configuring/
typescript#typescript-plugin) or see the [MDN](https://developer.mozilla.org/
docs/Web/Manifest) docs.
---
title: opengraph-image and twitter-image
description: API Reference for the Open Graph Image and Twitter Image file
conventions.
---
They are useful for setting the images that appear on social networks and
messaging apps when a user shares a link to your site.
There are two ways to set Open Graph and Twitter images:
Next.js will evaluate the file and automatically add the appropriate tags to your
app's `<head>` element.
### `opengraph-image`
### `twitter-image`
### `opengraph-image.alt.txt`
### `twitter-image.alt.txt`
```txt filename="twitter-image.alt.txt"
About Acme
```
// Image metadata
export const alt = 'About Acme'
export const size = {
width: 1200,
height: 630,
}
// Image generation
export default async function Image() {
// Font
const interSemiBold = fetch(
new URL('./Inter-SemiBold.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
// Image metadata
export const alt = 'About Acme'
export const size = {
width: 1200,
height: 630,
}
// Image generation
export default async function Image() {
// Font
const interSemiBold = fetch(
new URL('./Inter-SemiBold.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
### Props
### Returns
You can optionally configure the image's metadata by exporting `alt`, `size`,
and `contentType` variables from `opengraph-image` or `twitter-image` route.
| Option | Type
|
| ----------------------------- |
-------------------------------------------------------------------------------
-------------------------------- |
| [`alt`](#alt) | `string`
|
| [`size`](#size) | `{ width: number; height: number }`
|
| [`contentType`](#contenttype) | `string` - [image MIME type](https://
developer.mozilla.org/docs/Web/HTTP/Basics_of_HTTP/
MIME_types#image_types) |
#### `alt`
#### `size`
#### `contentType`
| Option | Type
| Default |
|
-------------------------------------------------------------------------------
------------------- | -------------------------------------------------------- |
---------- |
| [`dynamic`](/docs/app/api-reference/file-conventions/route-segment-
config#dynamic) | `'auto' \| 'force-dynamic' \| 'error' \| 'force-static'` |
`'auto'` |
| [`revalidate`](/docs/app/api-reference/file-conventions/route-segment-
config#revalidate) | `false \| 'force-cache' \| 0 \| number` |
`false` |
| [`runtime`](/docs/app/api-reference/file-conventions/route-segment-
config#runtime) | `'nodejs' \| 'edge'` | `'nodejs'`
|
| [`preferredRegion`](/docs/app/api-reference/file-conventions/route-segment-
config#preferredregion) | `'auto' \| 'global' \| 'home' \| string \| string[]` |
`'auto'` |
### Examples
This example uses the `params` object and external data to generate the
image.
> **Good to know**:
> By default, this generated image will be [statically optimized](/docs/app/
building-your-application/rendering/server-components#static-rendering-
default). You can configure the individual `fetch` [`options`](/docs/app/api-
reference/functions/fetch) or route segments [options](/docs/app/api-
reference/file-conventions/route-segment-config#revalidate) to change this
behavior.
## Version History
| Version | Changes |
| --------- | ------------------------------------------------- |
| `v13.3.0` | `opengraph-image` and `twitter-image` introduced. |
---
title: robots.txt
description: API Reference for robots.txt file.
---
## Static `robots.txt`
```txt filename="app/robots.txt"
User-Agent: *
Allow: /
Disallow: /private/
Sitemap: https://acme.com/sitemap.xml
```
Output:
```txt
User-Agent: *
Allow: /
Disallow: /private/
Sitemap: https://acme.com/sitemap.xml
```
```tsx
type Robots = {
rules:
|{
userAgent?: string | string[]
allow?: string | string[]
disallow?: string | string[]
crawlDelay?: number
}
| Array<{
userAgent: string | string[]
allow?: string | string[]
disallow?: string | string[]
crawlDelay?: number
}>
sitemap?: string | string[]
host?: string
}
```
## Version History
| Version | Changes |
| --------- | -------------------- |
| `v13.3.0` | `robots` introduced. |
---
title: sitemap.xml
description: API Reference for the sitemap.xml file.
---
Add or generate a `sitemap.xml` file that matches the [Sitemaps XML format]
(https://www.sitemaps.org/protocol.html) in the **root** of `app` directory to
help search engine crawlers crawl your site more efficiently.
## Static `sitemap.xml`
```xml filename="app/sitemap.xml"
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://acme.com</loc>
<lastmod>2023-04-06T15:02:24.021Z</lastmod>
<changefreq>yearly</changefreq>
<priority>1</priority>
</url>
<url>
<loc>https://acme.com/about</loc>
<lastmod>2023-04-06T15:02:24.021Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://acme.com/blog</loc>
<lastmod>2023-04-06T15:02:24.021Z</lastmod>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
</urlset>
```
## Generate a Sitemap
Output:
```xml filename="acme.com/sitemap.xml"
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://acme.com</loc>
<lastmod>2023-04-06T15:02:24.021Z</lastmod>
<changefreq>yearly</changefreq>
<priority>1</priority>
</url>
<url>
<loc>https://acme.com/about</loc>
<lastmod>2023-04-06T15:02:24.021Z</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://acme.com/blog</loc>
<lastmod>2023-04-06T15:02:24.021Z</lastmod>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
</urlset>
```
```tsx
type Sitemap = Array<{
url: string
lastModified?: string | Date
changeFrequency?:
| 'always'
| 'hourly'
| 'daily'
| 'weekly'
| 'monthly'
| 'yearly'
| 'never'
priority?: number
}>
```
## Version History
| Version | Changes |
| --------- | ------------------------------------------------------------ |
| `v13.3.0` | `sitemap` introduced. |
| `v13.4.5` | Add `changeFrequency` and `priority` attributes to sitemaps. |
---
title: default.js
description: API Reference for the default.js file.
---
---
title: error.js
description: API reference for the error.js special file.
related:
title: Learn more about error handling
links:
- app/building-your-application/routing/error-handling
---
return (
<div>
<h2>Something went wrong!</h2>
<button
onClick={
// Attempt to recover by trying to re-render the segment
() => reset()
}
>
Try again
</button>
</div>
)
}
```
return (
<div>
<h2>Something went wrong!</h2>
<button
onClick={
// Attempt to recover by trying to re-render the segment
() => reset()
}
>
Try again
</button>
</div>
)
}
```
## Props
### `error`
An instance of an [`Error`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/Error) object forwarded to the `error.js` Client
Component.
#### `error.message`
#### `error.digest`
### `reset`
A function to reset the error boundary. When executed, the function will try to
re-render the Error boundary's contents. If successful, the fallback error
component is replaced with the result of the re-render.
Can be used to prompt the user to attempt to recover from the error.
## `global-error.js`
## not-found.js
The [`not-found`](https://nextjs.org/docs/app/api-reference/file-conventions/
not-found) file is used to render UI when the `notFound()` function is thrown
within a route segment.
## Version History
| Version | Changes |
| --------- | -------------------------- |
| `v13.1.0` | `global-error` introduced. |
| `v13.0.0` | `error` introduced. |
---
title: File Conventions
description: API Reference for Next.js Special Files.
---
---
title: layout.js
description: API reference for the layout.js file.
---
A **root layout** is the top-most layout in the root `app` directory. It is used
to define the `<html>` and `<body>` tags and other globally shared UI.
## Props
Layout components should accept and use a `children` prop. During rendering,
`children` will be populated with the route segments the layout is wrapping.
These will primarily be the component of a child [Layout](/docs/app/building-
your-application/routing/pages-and-layouts#pages) (if it exists) or [Page](/
docs/app/building-your-application/routing/pages-and-layouts#pages), but
could also be other special files like [Loading](/docs/app/building-your-
application/routing/loading-ui-and-streaming) or [Error](/docs/app/building-
your-application/routing/error-handling) when applicable.
For example:
## Good to know
When using client-side navigation, Next.js automatically only renders the part
of the page below the common layout between two routes.
<Image
alt="File structure showing a dashboard folder nesting a layout.tsx file, and
settings and analytics folders with their own pages"
srcLight="/docs/light/shared-dashboard-layout.png"
srcDark="/docs/dark/shared-dashboard-layout.png"
width="1600"
height="687"
/>
## Version History
| Version | Changes |
| --------- | -------------------- |
| `v13.0.0` | `layout` introduced. |
---
title: loading.js
description: API reference for the loading.js file.
---
## Version History
| Version | Changes |
| --------- | --------------------- |
| `v13.0.0` | `loading` introduced. |
---
title: not-found.js
description: API reference for the not-found.js file.
---
## Props
## Data Fetching
## Version History
| Version | Changes |
| --------- | --------------------------------------------------- |
| `v13.3.0` | Root `app/not-found` handles global unmatched URLs. |
| `v13.0.0` | `not-found` introduced. |
---
title: page.js
description: API reference for the page.js file.
---
## Props
| URL | `searchParams` |
| --------------- | -------------------- |
| `/shop?a=1` | `{ a: '1' }` |
| `/shop?a=1&b=2` | `{ a: '1', b: '2' }` |
| `/shop?a=1&a=2` | `{ a: ['1', '2'] }` |
| Version | Changes |
| --------- | ------------------ |
| `v13.0.0` | `page` introduced. |
---
title: Route Segment Config
description: Learn about how to configure options for Next.js route segments.
---
The Route Segment options allows you configure the behavior of a [Page](/
docs/app/building-your-application/routing/pages-and-layouts), [Layout](/
docs/app/building-your-application/routing/pages-and-layouts), or [Route
Handler](/docs/app/building-your-application/routing/route-handlers) by
directly exporting the following variables:
| Option | Type
| Default |
| ------------------------------------- |
-------------------------------------------------------------------------------
------------------------------------------ | -------------------------- |
| [`dynamic`](#dynamic) | `'auto' \| 'force-dynamic' \| 'error' \| 'force-
static'` | `'auto'` |
| [`dynamicParams`](#dynamicparams) | `boolean`
| `true` |
| [`revalidate`](#revalidate) | `false \| 'force-cache' \| 0 \| number`
| `false` |
| [`fetchCache`](#fetchcache) | `'auto' \| 'default-cache' \| 'only-cache' \|
'force-cache' \| 'force-no-store' \| 'default-no-store' \| 'only-no-store'` |
`'auto'` |
| [`runtime`](#runtime) | `'nodejs' \| 'edge'`
| `'nodejs'` |
| [`preferredRegion`](#preferredregion) | `'auto' \| 'global' \| 'home' \| string \|
string[]` | `'auto'` |
| [`maxDuration`](#maxduration) | `number`
| Set by deployment platform |
## Options
### `dynamic`
Change the dynamic behavior of a layout or page to fully static or fully dynamic.
> **Good to know**: The new model in the `app` directory favors granular
caching control at the `fetch` request level over the binary all-or-nothing
model of `getServerSideProps` and `getStaticProps` at the page-level in the
`pages` directory. The `dynamic` option is a way to opt back in to the previous
model as a convenience and provides a simpler migration path.
- **`'error'`**: Force static rendering and cache the data of a layout or page
by causing an error if any components use [dynamic functions](/docs/app/
building-your-application/rendering/server-components#server-rendering-
strategies#dynamic-functions) or uncached data. This option is equivalent to:
- `getStaticProps()` in the `pages` directory.
- Setting the option of every `fetch()` request in a layout or page to `{ cache:
'force-cache' }`.
- Setting the segment config to `fetchCache = 'only-cache', dynamicParams =
false`.
- `dynamic = 'error'` changes the default of `dynamicParams` from `true` to
`false`. You can opt back into dynamically rendering pages for dynamic params
not generated by `generateStaticParams` by manually setting `dynamicParams
= true`.
- **`'force-static'`**: Force static rendering and cache the data of a layout or
page by forcing [`cookies()`](/docs/app/api-reference/functions/cookies),
[`headers()`](/docs/app/api-reference/functions/headers) and
[`useSearchParams()`](/docs/app/api-reference/functions/use-search-params)
to return empty values.
### `dynamicParams`
Control what happens when a dynamic segment is visited that was not
generated with [generateStaticParams](/docs/app/api-reference/functions/
generate-static-params).
### `revalidate`
Set the default revalidation time for a layout or page. This option does not
override the `revalidate` value set by individual `fetch` requests.
- **`false`**: (default) The default heuristic to cache any `fetch` requests that
set their `cache` option to `'force-cache'` or are discovered before a [dynamic
function](/docs/app/building-your-application/rendering/server-
components#server-rendering-strategies#dynamic-functions) is used.
Semantically equivalent to `revalidate: Infinity` which effectively means the
resource should be cached indefinitely. It is still possible for individual `fetch`
requests to use `cache: 'no-store'` or `revalidate: 0` to avoid being cached
and make the route dynamically rendered. Or set `revalidate` to a positive
number lower than the route default to increase the revalidation frequency of a
route.
- **`0`**: Ensure a layout or page is always [dynamically rendered](/docs/app/
building-your-application/rendering/server-components#dynamic-rendering)
even if no dynamic functions or uncached data fetches are discovered. This
option changes the default of `fetch` requests that do not set a `cache` option
to `'no-store'` but leaves `fetch` requests that opt into `'force-cache'` or use
a positive `revalidate` as is.
- **`number`**: (in seconds) Set the default revalidation frequency of a layout
or page to `n` seconds.
> **Good to know**: The `revalidate` option is only available when using the
[Node.js Runtime](/docs/app/building-your-application/rendering/edge-and-
nodejs-runtimes#nodejs-runtime). This means using the `revalidate` option
with `runtime = 'edge'` will not work.
- The lowest `revalidate` across each layout and page of a single route will
determine the revalidation frequency of the _entire_ route. This ensures that
child pages are revalidated as frequently as their parent layouts.
- Individual `fetch` requests can set a lower `revalidate` than the route's
default `revalidate` to increase the revalidation frequency of the entire route.
This allows you to dynamically opt-in to more frequent revalidation for certain
routes based on some criteria.
### `fetchCache`
<details>
<summary>This is an advanced option that should only be used if you
specifically need to override the default behavior.</summary>
By default, Next.js **will cache** any `fetch()` requests that are reachable
**before** any [dynamic functions](/docs/app/building-your-application/
rendering/server-components#server-rendering-strategies#dynamic-
functions) are used and **will not cache** `fetch` requests that are discovered
**after** dynamic functions are used.
`fetchCache` allows you to override the default `cache` option of all `fetch`
requests in a layout or page.
- Any options set across each layout and page of a single route need to be
compatible with each other.
- If both the `'only-cache'` and `'force-cache'` are provided, then `'force-
cache'` wins. If both `'only-no-store'` and `'force-no-store'` are provided,
then `'force-no-store'` wins. The force option changes the behavior across the
route so a single segment with `'force-*'` would prevent any errors caused by
`'only-*'`.
- The intention of the `'only-*'` and `force-*'` options is to guarantee the
whole route is either fully static or fully dynamic. This means:
- A combination of `'only-cache'` and `'only-no-store'` in a single route is
not allowed.
- A combination of `'force-cache'` and `'force-no-store'` in a single route is
not allowed.
- A parent cannot provide `'default-no-store'` if a child provides `'auto'` or
`'*-cache'` since that could make the same fetch have different behavior.
- It is generally recommended to leave shared parent layouts as `'auto'` and
customize the options where child segments diverge.
</details>
### `runtime`
- **`nodejs`** (default)
- **`edge`**
### `preferredRegion`
### `maxDuration`
Based on your deployment platform, you may be able to use a higher default
execution time for your function.
This setting allows you to opt into a higher execution time within your plans
limit.
**Note**: This settings requires Next.js `13.4.10` or higher.
### `generateStaticParams`
---
title: route.js
description: API reference for the route.js special file.
---
Route Handlers allow you to create custom request handlers for a given route
using the Web [Request](https://developer.mozilla.org/docs/Web/API/Request)
and [Response](https://developer.mozilla.org/docs/Web/API/Response) APIs.
## HTTP Methods
A **route** file allows you to create custom request handlers for a given route.
The following [HTTP methods](https://developer.mozilla.org/docs/Web/HTTP/
Methods) are supported: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`,
and `OPTIONS`.
> **Good to know**: Route Handlers are only available inside the `app`
directory. You **do not** need to use API Routes (`pages`) and Route Handlers
(`app`) together, as Route Handlers should be able to handle all use cases.
## Parameters
```ts filename="app/dashboard/[team]/route.js"
export async function GET(request, context: { params }) {
const team = params.team // '1'
}
```
## NextResponse
## Version History
| Version | Changes |
| --------- | ------------------------------ |
| `v13.2.0` | Route handlers are introduced. |
---
title: template.js
description: API Reference for the template.js file.
---
<Image
alt="template.js special file"
srcLight="/docs/light/template-special-file.png"
srcDark="/docs/dark/template-special-file.png"
width="1600"
height="444"
/>
While less common, you might choose a template over a layout if you want:
- Features that rely on `useEffect` (e.g logging page views) and `useState`
(e.g a per-page feedback form).
- To change the default framework behavior. For example, Suspense
Boundaries inside layouts only show the fallback the first time the Layout is
loaded and not when switching pages. For templates, the fallback is shown on
each navigation.
## Props
```jsx filename="Output"
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>
```
## Version History
| Version | Changes |
| --------- | ---------------------- |
| `v13.0.0` | `template` introduced. |
---
title: cookies
description: API Reference for the cookies function.
related:
title: Next Steps
description: For more information on what to do next, we recommend the
following sections
links:
- app/building-your-application/data-fetching/forms-and-mutations
---
The `cookies` function allows you to read the HTTP incoming request cookies
from a [Server Component](/docs/app/building-your-application/rendering/
server-components) or write outgoing request cookies in a [Server Action](/
docs/app/building-your-application/data-fetching/forms-and-mutations) or
[Route Handler](/docs/app/building-your-application/routing/route-handlers).
## `cookies().get(name)`
A method that takes a cookie name and returns an object with name and value.
If a cookie with `name` isn't found, it returns `undefined`. If multiple cookies
match, it will only return the first match.
```jsx filename="app/page.js"
import { cookies } from 'next/headers'
## `cookies().getAll()`
A method that is similar to `get`, but returns a list of all the cookies with a
matching `name`. If `name` is unspecified, it returns all the available cookies.
```jsx filename="app/page.js"
import { cookies } from 'next/headers'
## `cookies().has(name)`
A method that takes a cookie name and returns a `boolean` based on if the
cookie exists (`true`) or not (`false`).
```jsx filename="app/page.js"
import { cookies } from 'next/headers'
A method that takes a cookie name, value, and options and sets the outgoing
request cookie.
> **Good to know**: HTTP does not allow setting cookies after streaming
starts, so you must use `.set()` in a [Server Action](/docs/app/building-your-
application/data-fetching/forms-and-mutations) or [Route Handler](/docs/app/
building-your-application/routing/route-handlers).
```js filename="app/actions.js"
'use server'
## Deleting cookies
> **Good to know**: You can only delete cookies in a [Server Action](/docs/
app/building-your-application/data-fetching/forms-and-mutations) or [Route
Handler](/docs/app/building-your-application/routing/route-handlers).
### `cookies().delete(name)`
```js filename="app/actions.js"
'use server'
Alternatively, you can set a new cookie with the same name and an empty
value.
```js filename="app/actions.js"
'use server'
```js filename="app/actions.js"
'use server'
Setting `expires` to any value in the past will immediately expire a cookie.
```js filename="app/actions.js"
'use server'
> **Good to know**: You can only delete cookies that belong to the same
domain from which `.set()` is called. Additionally, the code must be executed
on the same protocol (HTTP or HTTPS) as the cookie you want to delete.
## Version History
| Version | Changes |
| --------- | --------------------- |
| `v13.0.0` | `cookies` introduced. |
---
title: draftMode
description: API Reference for the draftMode function.
---
```jsx filename="app/page.js"
import { draftMode } from 'next/headers'
## Version History
| Version | Changes |
| --------- | ----------------------- |
| `v13.4.0` | `draftMode` introduced. |
---
title: fetch
description: API reference for the extended fetch function.
---
In the browser, the `cache` option indicates how a fetch request will interact
with the _browser's_ HTTP cache. With this extension, `cache` indicates how a
_server-side_ fetch request will interact with the framework's persistent HTTP
cache.
You can call `fetch` with `async` and `await` directly within Server
Components.
return <div>...</div>
}
```
return <div>...</div>
}
```
## `fetch(url, options)`
### `options.cache`
Configure how the request should interact with Next.js [Data Cache](/docs/app/
building-your-application/caching#data-cache).
```ts
fetch(`https://...`, { cache: 'force-cache' | 'no-store' })
```
- **`force-cache`** (default) - Next.js looks for a matching request in its Data
Cache.
- If there is a match and it is fresh, it will be returned from the cache.
- If there is no match or a stale match, Next.js will fetch the resource from the
remote server and update the cache with the downloaded resource.
- **`no-store`** - Next.js fetches the resource from the remote server on
every request without looking in the cache, and it will not update the cache with
the downloaded resource.
### `options.next.revalidate`
```ts
fetch(`https://...`, { next: { revalidate: false | 0 | number } })
```
### `options.next.tags`
```ts
fetch(`https://...`, { next: { tags: ['collection'] } })
```
Set the cache tags of a resource. Data can then be revalidated on-demand
using [`revalidateTag`](https://nextjs.org/docs/app/api-reference/functions/
revalidateTag). The max length for a custom tag is 256 characters.
## Version History
| Version | Changes |
| --------- | ------------------- |
| `v13.0.0` | `fetch` introduced. |
---
title: generateImageMetadata
description: Learn how to generate multiple images in a single Metadata API
special file.
related:
title: Next Steps
description: View all the Metadata API options.
links:
- app/api-reference/file-conventions/metadata
- app/building-your-application/optimizing/metadata
---
## Parameters
## Returns
### Examples
This example uses the `params` object and external data to generate multiple
[Open Graph images](/docs/app/api-reference/file-conventions/metadata/
opengraph-image) for a route segment.
## Version History
| Version | Changes |
| --------- | ----------------------------------- |
| `v13.3.0` | `generateImageMetadata` introduced. |
---
title: Metadata Object and generateMetadata Options
nav_title: generateMetadata
description: Learn how to add Metadata to your Next.js application for improved
search engine optimization (SEO) and web shareability.
related:
title: Next Steps
description: View all the Metadata API options.
links:
- app/api-reference/file-conventions/metadata
- app/api-reference/functions/generate-viewport
- app/building-your-application/optimizing/metadata
---
// or Dynamic metadata
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
```
// or Dynamic metadata
export async function generateMetadata({ params }) {
return {
title: '...',
}
}
```
## `generateMetadata` function
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
// fetch data
const product = await fetch(`https://.../${id}`).then((res) => res.json())
return {
title: product.title,
openGraph: {
images: ['/some-specific-page-image.jpg', ...previousImages],
},
}
}
### Parameters
| URL | `searchParams` |
| --------------- | -------------------- |
| `/shop?a=1` | `{ a: '1' }` |
| `/shop?a=1&b=2` | `{ a: '1', b: '2' }` |
| `/shop?a=1&a=2` | `{ a: ['1', '2'] }` |
- `parent` - A promise of the resolved metadata from parent route segments.
### Returns
## Metadata Fields
### `title`
The `title` attribute is used to set the title of the document. It can be defined as
a simple [string](#string) or an optional [template object](#template-object).
#### String
##### Default
```tsx filename="app/layout.tsx"
import type { Metadata } from 'next'
```tsx filename="app/about/page.tsx"
import type { Metadata } from 'next'
// Output: <title>Acme</title>
```
##### Template
##### Absolute
// Output: <title>About</title>
```
### `description`
### `metadataBase`
- When [`VERCEL_URL`](https://vercel.com/docs/concepts/projects/
environment-variables/system-environment-variables#:~:text=.-,VERCEL_URL,-
The%20domain%20name) is detected: `https://${process.env.VERCEL_URL}`
otherwise it falls back to `http://localhost:${process.env.PORT || 3000}`.
- When overriding the default, we recommend using environment variables to
compute the URL. This allows configuring a URL for local development, staging,
and production environments.
Any `metadata` fields that inherit the above `metadataBase` and set their own
value will be resolved as follows:
### `openGraph`
### `robots`
```tsx
import type { Metadata } from 'next'
> **Good to know**: The `msapplication-*` meta tags are no longer supported
in Chromium builds of Microsoft Edge, and thus no longer needed.
### `themeColor`
### `manifest`
### `twitter`
Learn more about the [Twitter Card markup reference](https://
developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup).
### `viewport`
### `verification`
### `appleWebApp`
### `alternates`
### `appLinks`
```jsx filename="layout.js | page.js"
export const metadata = {
appLinks: {
ios: {
url: 'https://nextjs.org/ios',
app_store_id: 'app_store_id',
},
android: {
package: 'com.example.android/package',
app_name: 'app_name_android',
},
web: {
url: 'https://nextjs.org/web',
should_fallback: true,
},
},
}
```
### `archives`
### `assets`
```jsx filename="layout.js | page.js"
export const metadata = {
assets: ['https://nextjs.org/assets'],
}
```
### `bookmarks`
### `category`
### `other`
All metadata options should be covered using the built-in support. However,
there may be custom metadata tags specific to your site, or brand new
metadata tags just released. You can use the `other` option to render any
custom metadata tag.
If you want to generate multiple same key meta tags you can use array value.
## Unsupported Metadata
The following metadata types do not currently have built-in support. However,
they can still be rendered in the layout or page itself.
| Metadata | Recommendation
|
| ----------------------------- |
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
----- |
| `<meta http-equiv="...">` | Use appropriate HTTP Headers via [`redirect()`]
(/docs/app/api-reference/functions/redirect), [Middleware](/docs/app/building-
your-application/routing/middleware#nextresponse), [Security Headers](/docs/
app/api-reference/next-config-js/headers) |
| `<base>` | Render the tag in the layout or page itself.
|
| `<noscript>` | Render the tag in the layout or page itself.
|
| `<style>` | Learn more about [styling in Next.js](/docs/app/
building-your-application/styling/css-modules).
|
| `<script>` | Learn more about [using scripts](/docs/app/building-
your-application/optimizing/scripts).
|
| `<link rel="stylesheet" />` | `import` stylesheets directly in the layout or
page itself.
|
| `<link rel="preload />` | Use [ReactDOM preload method](#link-relpreload)
|
| `<link rel="preconnect" />` | Use [ReactDOM preconnect method](#link-
relpreconnect)
|
| `<link rel="dns-prefetch" />` | Use [ReactDOM prefetchDNS method](#link-
reldns-prefetch)
|
The `<link>` element has a number of `rel` keywords that can be used to hint
to the browser that an external resource is likely to be needed. The browser
uses this information to apply preloading optimizations depending on the
keyword.
While the Metadata API doesn't directly support these hints, you can use new
[`ReactDOM` methods](https://github.com/facebook/react/pull/26237) to
safely insert them into the `<head>` of the document.
return null
}
```
Start loading a resource early in the page rendering (browser) lifecycle. [MDN
Docs](https://developer.mozilla.org/docs/Web/HTML/Attributes/rel/preload).
```tsx
ReactDOM.preload(href: string, options: { as: string })
```
```tsx
ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })
```
```tsx
ReactDOM.prefetchDNS(href: string)
```
## Types
You can add type safety to your metadata by using the `Metadata` type. If you
are using the [built-in TypeScript plugin](/docs/app/building-your-application/
configuring/typescript) in your IDE, you do not need to manually add the type,
but you can still explicitly add it if you want.
```tsx
import type { Metadata } from 'next'
```tsx
import type { Metadata } from 'next'
```tsx
import type { Metadata } from 'next'
```tsx
import type { Metadata } from 'next'
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
```tsx
import type { Metadata, ResolvingMetadata } from 'next'
For JavaScript projects, you can use JSDoc to add type safety.
```js
/** @type {import("next").Metadata} */
export const metadata = {
title: 'Next.js',
}
```
## Version History
| Version | Changes
|
| --------- |
-------------------------------------------------------------------------------
------------------------------------------------------------------------ |
| `v13.2.0` | `viewport`, `themeColor`, and `colorScheme` deprecated in favor
of the [`viewport` configuration](/docs/app/api-reference/functions/generate-
viewport). |
| `v13.2.0` | `metadata` and `generateMetadata` introduced.
|
---
title: generateStaticParams
description: API reference for the generateStaticParams function.
---
```jsx filename="app/blog/[slug]/page.js"
// Return a list of `params` to populate the [slug] dynamic segment
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
## Parameters
`options.params` (optional)
The `params` object contains the populated `params` from the parent
`generateStaticParams`, which can be used to [generate the `params` in a
child segment](#multiple-dynamic-segments-in-a-route).
## Returns
- Each property in the object is a dynamic segment to be filled in for the route.
- The properties name is the segment's name, and the properties value is what
that segment should be filled in with.
## Examples
You can generate params for dynamic segments above the current layout or
page, but **not below**. For example, given the `app/products/[category]/
[product]` route:
There are two approaches to generating params for a route with multiple
dynamic segments:
Generate the parent segments first and use the result to generate the child
segments.
The child `generateStaticParams` function can use the `params` returned from
the parent `generateStaticParams` function to dynamically generate its own
segments.
## Version History
| Version | Changes |
| --------- | ---------------------------------- |
| `v13.0.0` | `generateStaticParams` introduced. |
---
title: generateViewport
description: API Reference for the generateViewport function.
related:
title: Next Steps
description: View all the Metadata API options.
links:
- app/api-reference/file-conventions/metadata
- app/building-your-application/optimizing/metadata
---
You can customize the initial viewport of the page with the static `viewport`
object or the dynamic `generateViewport` function.
## `generateViewport` function
## Viewport Fields
### `themeColor`
> **Good to know**: The `viewport` meta tag is automatically set with the
following default values. Usually, manual configuration is unnecessary as the
default is sufficient. However, the information is provided for completeness.
```jsx filename="layout.js | page.js"
export const viewport = {
width: 'device-width',
initialScale: 1,
maximumScale: 1,
// Also supported by less commonly used
// interactiveWidget: 'resizes-visual',
}
```
### `colorScheme`
## Types
You can add type safety to your viewport object by using the `Viewport` type.
If you are using the [built-in TypeScript plugin](/docs/app/building-your-
application/configuring/typescript) in your IDE, you do not need to manually
add the type, but you can still explicitly add it if you want.
```tsx
import type { Viewport } from 'next'
export const viewport: Viewport = {
themeColor: 'black',
}
```
```tsx
import type { Viewport } from 'next'
```tsx
import type { Viewport } from 'next'
type Props = {
params: { id: string }
searchParams: { [key: string]: string | string[] | undefined }
}
For JavaScript projects, you can use JSDoc to add type safety.
```js
/** @type {import("next").Viewport} */
export const viewport = {
themeColor: 'black',
}
```
## Version History
| Version | Changes |
| --------- | --------------------------------------------- |
| `v14.0.0` | `viewport` and `generateViewport` introduced. |
---
title: headers
description: API reference for the headers function.
---
The `headers` function allows you to read the HTTP incoming request headers
from a [Server Component](/docs/app/building-your-application/rendering/
server-components).
## `headers()`
```tsx
const headersList = headers()
```
#### Parameters
#### Returns
- [`Headers.entries()`](https://developer.mozilla.org/docs/Web/API/Headers/
entries): Returns an [`iterator`](https://developer.mozilla.org/docs/Web/
JavaScript/Reference/Iteration_protocols) allowing to go through all key/value
pairs contained in this object.
- [`Headers.forEach()`](https://developer.mozilla.org/docs/Web/API/Headers/
forEach): Executes a provided function once for each key/value pair in this
`Headers` object.
- [`Headers.get()`](https://developer.mozilla.org/docs/Web/API/Headers/get):
Returns a [`String`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/String) sequence of all the values of a header within
a `Headers` object with a given name.
- [`Headers.has()`](https://developer.mozilla.org/docs/Web/API/Headers/has):
Returns a boolean stating whether a `Headers` object contains a certain
header.
- [`Headers.keys()`](https://developer.mozilla.org/docs/Web/API/Headers/
keys): Returns an [`iterator`](https://developer.mozilla.org/docs/Web/
JavaScript/Reference/Iteration_protocols) allowing you to go through all keys of
the key/value pairs contained in this object.
- [`Headers.values()`](https://developer.mozilla.org/docs/Web/API/Headers/
values): Returns an [`iterator`](https://developer.mozilla.org/docs/Web/
JavaScript/Reference/Iteration_protocols) allowing you to go through all values
of the key/value pairs contained in this object.
### Examples
#### Usage with Data Fetching
```jsx filename="app/page.js"
import { headers } from 'next/headers'
## Version History
| Version | Changes |
| --------- | --------------------- |
| `v13.0.0` | `headers` introduced. |
---
title: ImageResponse
description: API Reference for the ImageResponse constructor.
---
```jsx
import { ImageResponse } from 'next/og'
new ImageResponse(
element: ReactElement,
options: {
width?: number = 1200
height?: number = 630
emoji?: 'twemoji' | 'blobmoji' | 'noto' | 'openmoji' = 'twemoji',
fonts?: {
name: string,
data: ArrayBuffer,
weight: number,
style: 'normal' | 'italic'
}[]
debug?: boolean = false
## Version History
| Version | Changes |
| --------- | ----------------------------------------------------- |
| `v14.0.0` | `ImageResponse` moved from `next/server` to `next/og` |
| `v13.3.0` | `ImageResponse` can be imported from `next/server`. |
| `v13.0.0` | `ImageResponse` introduced via `@vercel/og` package. |
---
title: Functions
description: API Reference for Next.js Functions and Hooks.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
---
title: NextRequest
description: API Reference for NextRequest.
---
## `cookies`
Given a name, set a cookie with the given value on the request.
```ts
// Given incoming request /home
// Set a cookie to hide the banner
// request will have a `Set-Cookie:show-banner=false;path=/home` header
request.cookies.set('show-banner', 'false')
```
### `get(name)`
Given a cookie name, return the value of the cookie. If the cookie is not found,
`undefined` is returned. If multiple cookies are found, the first one is returned.
```ts
// Given incoming request /home
// { name: 'show-banner', value: 'false', Path: '/home' }
request.cookies.get('show-banner')
```
### `getAll()`
Given a cookie name, return the values of the cookie. If no name is given, return
all cookies on the request.
```ts
// Given incoming request /home
// [
// { name: 'experiments', value: 'new-pricing-page', Path: '/home' },
// { name: 'experiments', value: 'winter-launch', Path: '/home' },
// ]
request.cookies.getAll('experiments')
// Alternatively, get all cookies for the request
request.cookies.getAll()
```
### `delete(name)`
```ts
// Returns true for deleted, false is nothing is deleted
request.cookies.delete('experiments')
```
### `has(name)`
Given a cookie name, return `true` if the cookie exists on the request.
```ts
// Returns true if cookie exists, false if it does not
request.cookies.has('experiments')
```
### `clear()`
```ts
request.cookies.clear()
```
## `nextUrl`
```ts
// Given a request to /home, pathname is /home
request.nextUrl.pathname
// Given a request to /home?name=lee, searchParams is { 'name': 'lee' }
request.nextUrl.searchParams
```
## Version History
| Version | Changes |
| --------- | ----------------------------- |
| `v13.0.0` | `useSearchParams` introduced. |
---
title: NextResponse
description: API Reference for NextResponse.
---
## `cookies`
Given a name, set a cookie with the given value on the response.
```ts
// Given incoming request /home
let response = NextResponse.next()
// Set a cookie to hide the banner
response.cookies.set('show-banner', 'false')
// Response will have a `Set-Cookie:show-banner=false;path=/home` header
return response
```
### `get(name)`
Given a cookie name, return the value of the cookie. If the cookie is not found,
`undefined` is returned. If multiple cookies are found, the first one is returned.
```ts
// Given incoming request /home
let response = NextResponse.next()
// { name: 'show-banner', value: 'false', Path: '/home' }
response.cookies.get('show-banner')
```
### `getAll()`
Given a cookie name, return the values of the cookie. If no name is given, return
all cookies on the response.
```ts
// Given incoming request /home
let response = NextResponse.next()
// [
// { name: 'experiments', value: 'new-pricing-page', Path: '/home' },
// { name: 'experiments', value: 'winter-launch', Path: '/home' },
// ]
response.cookies.getAll('experiments')
// Alternatively, get all cookies for the response
response.cookies.getAll()
```
### `delete(name)`
```ts
// Given incoming request /home
let response = NextResponse.next()
// Returns true for deleted, false is nothing is deleted
response.cookies.delete('experiments')
```
## `json()`
## `redirect()`
```ts
import { NextResponse } from 'next/server'
```ts
import { NextResponse } from 'next/server'
## `rewrite()`
```ts
import { NextResponse } from 'next/server'
## `next()`
The `next()` method is useful for Middleware, as it allows you to return early
and continue routing.
```ts
import { NextResponse } from 'next/server'
return NextResponse.next()
```
```ts
import { NextResponse } from 'next/server'
---
title: notFound
description: API Reference for the notFound function.
---
## `notFound()`
```jsx filename="app/user/[id]/page.js"
import { notFound } from 'next/navigation'
if (!user) {
notFound()
}
// ...
}
```
> **Good to know**: `notFound()` does not require you to use `return
notFound()` due to using the TypeScript [`never`](https://
www.typescriptlang.org/docs/handbook/2/functions.html#never) type.
## Version History
| Version | Changes |
| --------- | ---------------------- |
| `v13.0.0` | `notFound` introduced. |
---
title: permanentRedirect
description: API Reference for the permanentRedirect function.
---
When used in a streaming context, this will insert a meta tag to emit the
redirect on the client side. When used in a server action, it will serve a 303
HTTP redirect response to the caller. Otherwise, it will serve a 308 (Permanent)
HTTP redirect response to the caller.
> **Good to know**: If you prefer to return a 307 (Temporary) HTTP redirect
instead of 308 (Permanent), you can use the [`redirect` function](/docs/app/
api-reference/functions/redirect) instead.
## Parameters
```js
permanentRedirect(path, type)
```
## Returns
## Example
```jsx filename="app/team/[id]/page.js"
import { permanentRedirect } from 'next/navigation'
// ...
}
```
> **Good to know**: `permanentRedirect` does not require you to use `return
permanentRedirect()` as it uses the TypeScript [`never`](https://
www.typescriptlang.org/docs/handbook/2/functions.html#never) type.
---
title: redirect
description: API Reference for the redirect function.
---
The `redirect` function allows you to redirect the user to another URL.
`redirect` can be used in Server Components, Client Components, [Route
Handlers](/docs/app/building-your-application/routing/route-handlers), and
[Server Actions](/docs/app/building-your-application/data-fetching/forms-and-
mutations).
> **Good to know**: If you prefer to return a 308 (Permanent) HTTP redirect
instead of 307 (Temporary), you can use the [`permanentRedirect` function](/
docs/app/api-reference/functions/permanentRedirect) instead.
## Parameters
```js
redirect(path, type)
```
By default, `redirect` will use `push` (adding a new entry to the browser
history stack) in [Server Actions](/docs/app/building-your-application/data-
fetching/forms-and-mutations) and `replace` (replacing the current URL in the
browser history stack) everywhere else. You can override this behavior by
specifying the `type` parameter.
## Example
> **Good to know**: If you need to programmatically redirect the user after a
certain event in a Client Component, you can use the [`useRouter`](/docs/app/
api-reference/functions/use-router) hook.
```jsx filename="app/team/[id]/page.js"
import { redirect } from 'next/navigation'
// ...
}
```
> **Good to know**: `redirect` does not require you to use `return redirect()`
as it uses the TypeScript [`never`](https://www.typescriptlang.org/docs/
handbook/2/functions.html#never) type.
| Version | Changes |
| --------- | ---------------------- |
| `v13.0.0` | `redirect` introduced. |
---
title: revalidatePath
description: API Reference for the revalidatePath function.
---
## Parameters
```tsx
revalidatePath(path: string, type?: 'page' | 'layout'): void;
```
- `path`: Either a string representing the filesystem path associated with the
data you want to revalidate (for example, `/product/[slug]/page`), or the literal
route segment (for example, `/product/123`). Must be less than 1024
characters.
- `type`: (optional) `'page'` or `'layout'` string to change the type of path to
revalidate.
## Returns
## Examples
```ts
import { revalidatePath } from 'next/cache'
revalidatePath('/blog/post-1')
```
This will revalidate one specific URL on the next page visit.
```ts
import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'page')
// or with route groups
revalidatePath('/(main)/post/[slug]', 'page')
```
This will revalidate any URL that matches the provided `page` file on the next
page visit. This will _not_ invalidate pages beneath the specific page. For
example, `/blog/[slug]` won't invalidate `/blog/[slug]/[author]`.
```ts
import { revalidatePath } from 'next/cache'
revalidatePath('/blog/[slug]', 'layout')
// or with route groups
revalidatePath('/(main)/post/[slug]', 'layout')
```
This will revalidate any URL that matches the provided `layout` file on the next
page visit. This will cause pages beneath with the same layout to revalidate on
the next visit. For example, in the above case, `/blog/[slug]/[another]` would
also revalidate on the next visit.
```ts
import { revalidatePath } from 'next/cache'
revalidatePath('/', 'layout')
```
This will purge the Client-side Router Cache, and revalidate the Data Cache on
the next page visit.
if (path) {
revalidatePath(path)
return Response.json({ revalidated: true, now: Date.now() })
}
return Response.json({
revalidated: false,
now: Date.now(),
message: 'Missing path to revalidate',
})
}
```
if (path) {
revalidatePath(path)
return Response.json({ revalidated: true, now: Date.now() })
}
return Response.json({
revalidated: false,
now: Date.now(),
message: 'Missing path to revalidate',
})
}
```
---
title: revalidateTag
description: API Reference for the revalidateTag function.
---
## Parameters
```tsx
revalidateTag(tag: string): void;
```
- `tag`: A string representing the cache tag associated with the data you want
to revalidate. Must be less than or equal to 256 characters.
```tsx
fetch(url, { next: { tags: [...] } });
```
## Returns
## Examples
---
title: Server Actions
nav_title: Server Actions
description: API Reference for Next.js Server Actions.
related:
title: Next Steps
description: For more information on what to do next, we recommend the
following sections
links:
- app/building-your-application/data-fetching/forms-and-mutations
---
{/* TODO: This page will need to link back to React docs mentioned at the
bottom */}
Next.js integrates with React Actions to provide a built-in solution for [server
mutations](/docs/app/building-your-application/data-fetching/forms-and-
mutations).
## Convention
#### Import
Create your Server Action in a separate file with the `"use server"` directive at
the top of the file. Then, import the Server Action into your Client Component:
> **Good to know**: When using a top-level `"use server"` directive, all
exports below will be considered Server Actions. You can have multiple Server
Actions in a single file.
#### Props
In some cases, you might want to pass down a Server Action to a Client
Component as a prop.
```jsx
<ClientComponent myAction={updateItem} />
```
```jsx filename="app/client-component.jsx"
'use client'
You can bind arguments to a Server Action using the `bind` method. This
allows you to create a new Server Action with some arguments already bound.
This is beneficial when you want to pass extra arguments to a Server Action.
return (
<form action={updateUserWithId}>
<input type="text" name="name" />
<button type="submit">Update User Name</button>
</form>
)
}
```
And then, the `updateUser` Server Action will always receive the `userId`
argument, in addition to the form data:
```js filename="app/actions.js"
'use server'
> **Good to know**: `.bind` of a Server Action works in both Server and Client
Components. It also supports [Progressive Enhancement](#progressive-
enhancement).
## Invocation
## Progressive Enhancement
React Actions (both server and client) support progressive enhancement, using
one of two strategies:
In both cases, the form is interactive before hydration occurs. Although Server
Actions have the additional benefit of not relying on client JavaScript, you can
still compose additional behavior with Client Actions where desired without
sacrificing interactivity.
## Size Limitation
By default, the maximum size of the request body sent to a Server Action is
1MB, to prevent the consumption of excessive server resources in parsing large
amounts of data.
```js filename="next.config.js"
module.exports = {
experimental: {
serverActions: {
bodySizeLimit: '2mb',
},
},
}
```
## Additional Resources
- [`"use server"`](https://react.dev/reference/react/use-server)
- [`useFormStatus`](https://react.dev/reference/react-dom/hooks/
useFormStatus)
- [`useFormState`](https://react.dev/reference/react-dom/hooks/
useFormState)
- [`useOptimistic`](https://react.dev/reference/react/useOptimistic)
- [`<form>`](https://react.dev/reference/react-dom/components/form)
---
title: unstable_cache
description: API Reference for the unstable_cache function.
---
```jsx
import { getUser } from './data';
import { unstable_cache } from 'next/cache';
> **Warning**: This API is unstable and may change in the future. We will
provide migration documentation and codemods, if needed, as this API
stabilizes.
## Parameters
```jsx
const data = unstable_cache(fetchData, keyParts, options)()
```
- `fetchData`: This is an asynchronous function that fetches the data you want
to cache. It must be a function that returns a `Promise`.
- `keyParts`: This is an array that identifies the cached key. It must contain
globally unique values that together identify the key of the data being cached.
The cache key also includes the arguments passed to the function.
- `options`: This is an object that controls how the cache behaves. It can
contain the following properties:
- `tags`: An array of tags that can be used to control cache invalidation.
- `revalidate`: The number of seconds after which the cache should be
revalidated.
## Returns
`unstable_cache` returns a function that when invoked, returns a Promise that
resolves to the cached data. If the data is not in the cache, the provided
function will be invoked, and its result will be cached and returned.
title: unstable_noStore
description: API Reference for the unstable_noStore function.
---
```jsx
import { unstable_noStore as noStore } from 'next/cache';
## Usage
If you prefer not to pass additional options to `fetch`, like `cache: 'no-store'`
or `next: { revalidate: 0 }`, you can use `noStore()` as a replacement for all of
these use cases.
```jsx
import { unstable_noStore as noStore } from 'next/cache';
## Version History
| Version | Changes |
| --------- | ------------------------------ |
| `v14.0.0` | `unstable_noStore` introduced. |
---
title: useParams
description: API Reference for the useParams hook.
---
return <></>
}
```
## Parameters
```tsx
const params = useParams()
```
## Returns
For example:
## Version History
| Version | Changes |
| --------- | ----------------------- |
| `v13.3.0` | `useParams` introduced. |
---
title: usePathname
description: API Reference for the usePathname hook.
---
`usePathname` is a **Client Component** hook that lets you read the current
URL's **pathname**.
## Parameters
```tsx
const pathname = usePathname()
```
## Returns
## Examples
function ExampleClientComponent() {
const pathname = usePathname()
const searchParams = useSearchParams()
useEffect(() => {
// Do something here...
}, [pathname, searchParams])
}
```
function ExampleClientComponent() {
const pathname = usePathname()
const searchParams = useSearchParams()
useEffect(() => {
// Do something here...
}, [pathname, searchParams])
}
```
| Version | Changes |
| --------- | ------------------------- |
| `v13.0.0` | `usePathname` introduced. |
---
title: useReportWebVitals
description: API Reference for the useReportWebVitals function.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<PagesOnly>
```jsx filename="pages/_app.js"
import { useReportWebVitals } from 'next/web-vitals'
</PagesOnly>
<AppOnly>
```jsx filename="app/_components/web-vitals.js"
'use client'
```jsx filename="app/layout.js"
import { WebVitals } from './_components/web-vitals'
> Since the `useReportWebVitals` hook requires the `"use client"` directive,
the most performant approach is to create a separate component that the root
layout imports. This confines the client boundary exclusively to the `WebVitals`
component.
</AppOnly>
## useReportWebVitals
- `id`: Unique identifier for the metric in the context of the current page load
- `name`: The name of the performance metric. Possible values include names
of [Web Vitals](#web-vitals) metrics (TTFB, FCP, LCP, FID, CLS) specific to a
web application.
- `delta`: The difference between the current value and the previous value of
the metric. The value is typically in milliseconds and represents the change in
the metric's value over time.
- `entries`: An array of [Performance Entries](https://developer.mozilla.org/
docs/Web/API/PerformanceEntry) associated with the metric. These entries
provide detailed information about the performance events related to the
metric.
- `navigationType`: Indicates the [type of navigation](https://
developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/type) that
triggered the metric collection. Possible values include `"navigate"`,
`"reload"`, `"back_forward"`, and `"prerender"`.
- `rating`: A qualitative rating of the metric value, providing an assessment of
the performance. Possible values are `"good"`, `"needs-improvement"`, and
`"poor"`. The rating is typically determined by comparing the metric value
against predefined thresholds that indicate acceptable or suboptimal
performance.
- `value`: The actual value or duration of the performance entry, typically in
milliseconds. The value provides a quantitative measure of the performance
aspect being tracked by the metric. The source of the value depends on the
specific metric being measured and can come from various [Performance API]
(https://developer.mozilla.org/docs/Web/API/Performance_API)s.
## Web Vitals
You can handle all the results of these metrics using the `name` property.
<PagesOnly>
```jsx filename="pages/_app.js"
import { useReportWebVitals } from 'next/web-vitals'
</PagesOnly>
<AppOnly>
</AppOnly>
<PagesOnly>
## Custom Metrics
In addition to the core metrics listed above, there are some additional custom
metrics that
measure the time it takes for the page to hydrate and render:
- `Next.js-hydration`: Length of time it takes for the page to start and finish
hydrating (in ms)
- `Next.js-route-change-to-render`: Length of time it takes for a page to start
rendering after a
route change (in ms)
- `Next.js-render`: Length of time it takes for a page to finish render after a
route change (in ms)
```js
export function reportWebVitals(metric) {
switch (metric.name) {
case 'Next.js-hydration':
// handle hydration results
break
case 'Next.js-route-change-to-render':
// handle route-change to render results
break
case 'Next.js-render':
// handle render results
break
default:
break
}
}
```
These metrics work in all browsers that support the [User Timing API](https://
caniuse.com/#feat=user-timing).
</PagesOnly>
## Usage on Vercel
[Vercel Speed Insights](https://vercel.com/docs/concepts/speed-insights) are
automatically configured on Vercel deployments, and don't require the use of
`useReportWebVitals`. This hook is useful in local development, or if you're
using a different analytics service.
```js
useReportWebVitals((metric) => {
const body = JSON.stringify(metric)
const url = 'https://example.com/analytics'
> ```js
> useReportWebVitals(metric => {
> // Use `window.gtag` if you initialized Google Analytics as this example:
> // https://github.com/vercel/next.js/blob/canary/examples/with-google-
analytics/pages/_app.js
> window.gtag('event', metric.name, {
> value: Math.round(metric.name === 'CLS' ? metric.value * 1000 :
metric.value), // values must be integers
> event_label: metric.id, // id unique to current page load
> non_interaction: true, // avoids affecting bounce rate.
> });
>}
> ```
>
> Read more about [sending results to Google Analytics](https://github.com/
GoogleChrome/web-vitals#send-the-results-to-google-analytics).
---
title: useRouter
description: API reference for the useRouter hook.
---
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
```
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
```
## `useRouter()`
- `router.push(href: string, { scroll: boolean })`: Perform a client-side navigation
to the provided route. Adds a new entry into the [browser’s history](https://
developer.mozilla.org/docs/Web/API/History_API) stack.
- `router.replace(href: string, { scroll: boolean })`: Perform a client-side
navigation to the provided route without adding a new entry into the [browser’s
history stack](https://developer.mozilla.org/docs/Web/API/History_API).
- `router.refresh()`: Refresh the current route. Making a new request to the
server, re-fetching data requests, and re-rendering Server Components. The
client will merge the updated React Server Component payload without losing
unaffected client-side React (e.g. `useState`) or browser state (e.g. scroll
position).
- `router.prefetch(href: string)`: [Prefetch](/docs/app/building-your-
application/routing/linking-and-navigating#1-prefetching) the provided route
for faster client-side transitions.
- `router.back()`: Navigate back to the previous route in the browser’s history
stack.
- `router.forward()`: Navigate forwards to the next page in the browser’s
history stack.
## Examples
You can listen for page changes by composing other Client Component hooks
like `usePathname` and `useSearchParams`.
```jsx filename="app/components/navigation-events.js"
'use client'
useEffect(() => {
const url = `${pathname}?${searchParams}`
console.log(url)
// You can now use the current URL
// ...
}, [pathname, searchParams])
return null
}
```
<Suspense fallback={null}>
<NavigationEvents />
</Suspense>
</body>
</html>
)
}
```
By default, Next.js will scroll to the top of the page when navigating to a new
route. You can disable this behavior by passing `scroll: false` to `router.push()`
or `router.replace()`.
return (
<button
type="button"
onClick={() => router.push('/dashboard', { scroll: false })}
>
Dashboard
</button>
)
}
```
return (
<button
type="button"
onClick={() => router.push('/dashboard', { scroll: false })}
>
Dashboard
</button>
)
}
```
## Version History
| Version | Changes |
| --------- | ---------------------------------------------- |
| `v13.0.0` | `useRouter` from `next/navigation` introduced. |
---
title: useSearchParams
description: API Reference for the useSearchParams hook.
---
## Parameters
```tsx
const searchParams = useSearchParams()
```
## Returns
- [`URLSearchParams.get()`](https://developer.mozilla.org/docs/Web/API/
URLSearchParams/get): Returns the first value associated with the search
parameter. For example:
| URL | `searchParams.get("a")`
|
| -------------------- |
-------------------------------------------------------------------------------
-------------------------------- |
| `/dashboard?a=1` | `'1'`
|
| `/dashboard?a=` | `''`
|
| `/dashboard?b=3` | `null`
|
| `/dashboard?a=1&a=2` | `'1'` _- use [`getAll()`](https://
developer.mozilla.org/docs/Web/API/URLSearchParams/getAll) to get all
values_ |
- [`URLSearchParams.has()`](https://developer.mozilla.org/docs/Web/API/
URLSearchParams/has): Returns a boolean value indicating if the given
parameter exists. For example:
| URL | `searchParams.has("a")` |
| ---------------- | ----------------------- |
| `/dashboard?a=1` | `true` |
| `/dashboard?b=3` | `false` |
- Learn more about other **read-only** methods of [`URLSearchParams`]
(https://developer.mozilla.org/docs/Web/API/URLSearchParams), including the
[`getAll()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/
getAll), [`keys()`](https://developer.mozilla.org/docs/Web/API/
URLSearchParams/keys), [`values()`](https://developer.mozilla.org/docs/Web/
API/URLSearchParams/values), [`entries()`](https://developer.mozilla.org/docs/
Web/API/URLSearchParams/entries), [`forEach()`](https://
developer.mozilla.org/docs/Web/API/URLSearchParams/forEach), and
[`toString()`](https://developer.mozilla.org/docs/Web/API/URLSearchParams/
toString).
## Behavior
This allows a part of the page to be statically rendered while the dynamic part
that uses `searchParams` is client-side rendered.
You can reduce the portion of the route that is client-side rendered by
wrapping the component that uses `useSearchParams` in a `Suspense`
boundary. For example:
// This will not be logged on the server when using static rendering
console.log(search)
// This will not be logged on the server when using static rendering
console.log(search)
> **Good to know**: Setting the [`dynamic` route segment config option](/
docs/app/api-reference/file-conventions/route-segment-config#dynamic) to
`force-dynamic` can be used to force dynamic rendering.
For example:
#### Pages
#### Layouts
## Examples
return params.toString()
},
[searchParams]
)
return (
<>
<p>Sort By</p>
return params.toString()
},
[searchParams]
)
return (
<>
<p>Sort By</p>
## Version History
| Version | Changes |
| --------- | ----------------------------- |
| `v13.0.0` | `useSearchParams` introduced. |
---
title: useSelectedLayoutSegment
description: API Reference for the useSelectedLayoutSegment hook.
---
It is useful for navigation UI, such as tabs inside a parent layout that change
style depending on the active child segment.
## Parameters
```tsx
const segment = useSelectedLayoutSegment(parallelRoutesKey?: string)
```
## Returns
For example, given the Layouts and URLs below, the returned segment would
be:
## Examples
return (
<Link
href={`/blog/${slug}`}
// Change style depending on whether the link is active
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</Link>
)
}
```
return (
<Link
href={`/blog/${slug}`}
// Change style depending on whether the link is active
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</Link>
)
}
```
## Version History
| Version | Changes |
| --------- | -------------------------------------- |
| `v13.0.0` | `useSelectedLayoutSegment` introduced. |
---
title: useSelectedLayoutSegments
description: API Reference for the useSelectedLayoutSegments hook.
---
It is useful for creating UI in parent Layouts that need knowledge of active child
segments such as breadcrumbs.
return (
<ul>
{segments.map((segment, index) => (
<li key={index}>{segment}</li>
))}
</ul>
)
}
```
## Parameters
```tsx
const segments = useSelectedLayoutSegments(parallelRoutesKey?: string)
```
## Returns
For example, given the Layouts and URLs below, the returned segments would
be:
## Version History
| Version | Changes |
| --------- | --------------------------------------- |
| `v13.0.0` | `useSelectedLayoutSegments` introduced. |
---
title: appDir
description: Enable the App Router to use layouts, streaming, and more.
---
> **Good to know**: This option is **no longer** needed as of Next.js 13.4.
The App Router is now stable.
Using the `app` directory will automatically enable [React Strict Mode](https://
react.dev/reference/react/StrictMode). Learn how to [incrementally adopt
`app`](/docs/app/building-your-application/upgrading/app-router-
migration#migrating-from-pages-to-app).
</AppOnly>
<PagesOnly>
</PagesOnly>
> **Good to know**: Next.js 9.5+ added support for a customizable [Base
Path](/docs/app/api-reference/next-config-js/basePath), which is better
> suited for hosting your application on a sub-path like `/docs`.
> We do not suggest you use a custom Asset Prefix for this use case.
```js filename="next.config.js"
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
// Use the CDN in production and localhost for development.
assetPrefix: isProd ? 'https://cdn.mydomain.com' : undefined,
}
```
Next.js will automatically use your asset prefix for the JavaScript and CSS files
it loads from the `/_next/` path (`.next/static/` folder). For example, with the
above configuration, the following request for a JS chunk:
```
/_next/static/chunks/
4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js
```
```
https://cdn.mydomain.com/_next/static/chunks/
4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js
```
The exact configuration for uploading your files to a given CDN will depend on
your CDN of choice. The only folder you need to host on your CDN is the
contents of `.next/static/`, which should be uploaded as `_next/static/` as the
above URL request indicates. **Do not upload the rest of your `.next/`
folder**, as you should not expose your server code and other configuration to
the public.
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
---
title: basePath
description: Use `basePath` to deploy a Next.js application under a sub-path of
a domain.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
To deploy a Next.js application under a sub-path of a domain you can use the
`basePath` config option.
`basePath` allows you to set a path prefix for the application. For example, to
use `/docs` instead of `''` (an empty string, the default), open `next.config.js`
and add the `basePath` config:
```js filename="next.config.js"
module.exports = {
basePath: '/docs',
}
```
> **Good to know**: This value must be set at build time and cannot be
changed without re-building as the value is inlined in the client-side bundles.
### Links
When linking to other pages using `next/link` and `next/router` the `basePath`
will be automatically applied.
For example, using `/about` will automatically become `/docs/about` when
`basePath` is set to `/docs`.
```js
export default function HomePage() {
return (
<>
<Link href="/about">About Page</Link>
</>
)
}
```
Output html:
```html
<a href="/docs/about">About Page</a>
```
This makes sure that you don't have to change all links in your application when
changing the `basePath` value.
### Images
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
For example, using `/docs/me.png` will properly serve your image when
`basePath` is set to `/docs`.
```jsx
import Image from 'next/image'
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image
src="/docs/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
<p>Welcome to my homepage!</p>
</>
)
}
---
title: compress
description: Next.js provides gzip compression to compress rendered content
and static files, it only works with the server target. Learn more about it here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
```js filename="next.config.js"
module.exports = {
compress: false,
}
```
---
title: devIndicators
description: Optimized pages include an indicator to let you know if it's being
statically optimized. You can opt-out of it here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
When you edit your code, and Next.js is compiling the application, a
compilation indicator appears in the bottom right corner of the page.
> **Good to know**: This indicator is only present in development mode and
will not appear when building and running the app in production mode.
In some cases this indicator can be misplaced on your page, for example, when
conflicting with a chat launcher. To change its position, open `next.config.js`
and set the `buildActivityPosition` in the `devIndicators` object to `bottom-
right` (default), `bottom-left`, `top-right` or `top-left`:
```js filename="next.config.js"
module.exports = {
devIndicators: {
buildActivityPosition: 'bottom-right',
},
}
```
In some cases this indicator might not be useful for you. To remove it, open
`next.config.js` and disable the `buildActivity` config in `devIndicators` object:
```js filename="next.config.js"
module.exports = {
devIndicators: {
buildActivity: false,
},
}
```
</AppOnly>
<PagesOnly>
> **Good to know**: This indicator was removed in Next.js version 10.0.1. We
recommend upgrading to the latest version of Next.js.
In some cases this indicator might not be useful, like when working on electron
applications. To remove it open `next.config.js` and disable the
`autoPrerender` config in `devIndicators`:
```js filename="next.config.js"
module.exports = {
devIndicators: {
autoPrerender: false,
},
}
```
</PagesOnly>
---
title: distDir
description: Set a custom build directory to use instead of the default .next
directory.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
You can specify a name to use for a custom build directory to use instead of
`.next`.
```js filename="next.config.js"
module.exports = {
distDir: 'build',
}
```
Now if you run `next build` Next.js will use `build` instead of the default `.next`
folder.
> `distDir` **should not** leave your project directory. For example, `../build`
is an **invalid** directory.
---
title: env
description: Learn to add and access environment variables in your Next.js
application at build time.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
<details>
<summary>Examples</summary>
- [With env](https://github.com/vercel/next.js/tree/canary/examples/with-env-
from-next-config-js)
</details>
<AppOnly>
> **Good to know**: environment variables specified in this way will **always**
be included in the JavaScript bundle, prefixing the environment variable name
with `NEXT_PUBLIC_` only has an effect when specifying them [through the
environment or .env files](/docs/app/building-your-application/configuring/
environment-variables).
</AppOnly>
<PagesOnly>
> **Good to know**: environment variables specified in this way will **always**
be included in the JavaScript bundle, prefixing the environment variable name
with `NEXT_PUBLIC_` only has an effect when specifying them [through the
environment or .env files](/docs/pages/building-your-application/configuring/
environment-variables).
</PagesOnly>
```js filename="next.config.js"
module.exports = {
env: {
customKey: 'my-value',
},
}
```
```jsx
function Page() {
return <h1>The value of customKey is: {process.env.customKey}</h1>
}
```jsx
return <h1>The value of customKey is: {process.env.customKey}</h1>
```
```jsx
return <h1>The value of customKey is: {'my-value'}</h1>
```
---
title: eslint
description: Next.js reports ESLint errors and warnings during builds by default.
Learn how to opt-out of this behavior here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
When ESLint is detected in your project, Next.js fails your **production build**
(`next build`) when errors are present.
If you'd like Next.js to produce production code even when your application has
ESLint errors, you can disable the built-in linting step completely. This is not
recommended unless you already have ESLint configured to run in a separate
part of your workflow (for example, in CI or a pre-commit hook).
```js filename="next.config.js"
module.exports = {
eslint: {
// Warning: This allows production builds to successfully complete even if
// your project has ESLint errors.
ignoreDuringBuilds: true,
},
}
```
---
title: exportPathMap (Deprecated)
nav_title: exportPathMap
description: Customize the pages that will be exported as HTML files when
using `next export`.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<details>
<summary>Examples</summary>
- [Static Export](https://github.com/vercel/next.js/tree/canary/examples/with-
static-export)
</details>
- `pages/index.js`
- `pages/about.js`
- `pages/post.js`
```js filename="next.config.js"
module.exports = {
exportPathMap: async function (
defaultPathMap,
{ dev, dir, outDir, distDir, buildId }
){
return {
'/': { page: '/' },
'/about': { page: '/about' },
'/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
'/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
'/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } },
}
},
}
```
> **Good to know**: the `query` field in `exportPathMap` cannot be used with
[automatically statically optimized pages](/docs/pages/building-your-
application/rendering/automatic-static-optimization) or [`getStaticProps`
pages](/docs/pages/building-your-application/data-fetching/get-static-props)
as they are rendered to HTML files at build-time and additional query
information cannot be provided during `next export`.
The pages will then be exported as HTML files, for example, `/about` will
become `/about.html`.
`exportPathMap` is an `async` function that receives 2 arguments: the first
one is `defaultPathMap`, which is the default map used by Next.js. The second
argument is an object with:
The returned object is a map of pages where the `key` is the `pathname` and
the `value` is an object that accepts the following fields:
To switch back and add a trailing slash, open `next.config.js` and enable the
`trailingSlash` config:
```js filename="next.config.js"
module.exports = {
trailingSlash: true,
}
```
<AppOnly>
[`next export`](/docs/app/building-your-application/deploying/static-exports)
will use `out` as the default output directory, you can customize this using the
`-o` argument, like so:
</AppOnly>
<PagesOnly>
[`next export`](/docs/pages/building-your-application/deploying/static-
exports) will use `out` as the default output directory, you can customize this
using the `-o` argument, like so:
</PagesOnly>
```bash filename="Terminal"
next export -o outdir
```
---
title: generateBuildId
description: Configure the build id, which is used to identify the current build in
which your application is being served.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
If you are rebuilding for each stage of your environment, you will need to
generate a consistent build ID to use between containers. Use the
`generateBuildId` command in `next.config.js`:
```jsx filename="next.config.js"
module.exports = {
generateBuildId: async () => {
// This could be anything, using the latest git hash
return process.env.GIT_HASH
},
}
```
---
title: generateEtags
description: Next.js will generate etags for every page by default. Learn more
about how to disable etag generation here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
```js filename="next.config.js"
module.exports = {
generateEtags: false,
}
```
---
title: headers
description: Add custom HTTP headers to your Next.js app.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Headers allow you to set custom HTTP headers on the response to an incoming
request on a given path.
To set custom HTTP headers you can use the `headers` key in `next.config.js`:
```js filename="next.config.js"
module.exports = {
async headers() {
return [
{
source: '/about',
headers: [
{
key: 'x-custom-header',
value: 'my custom header value',
},
{
key: 'x-another-custom-header',
value: 'my other custom header value',
},
],
},
]
},
}
```
Headers are checked before the filesystem which includes pages and `/public`
files.
If two headers match the same path and set the same header key, the last
header key will override the first. Using the below headers, the path `/hello` will
result in the header `x-hello` being `world` due to the last header value set
being `world`.
```js filename="next.config.js"
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'x-hello',
value: 'there',
},
],
},
{
source: '/hello',
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
]
},
}
```
## Path Matching
Path matches are allowed, for example `/blog/:slug` will match `/blog/hello-
world` (no nested paths):
```js filename="next.config.js"
module.exports = {
async headers() {
return [
{
source: '/blog/:slug',
headers: [
{
key: 'x-slug',
value: ':slug', // Matched parameters can be used in the value
},
{
key: 'x-slug-:slug', // Matched parameters can be used in the key
value: 'my other custom header value',
},
],
},
]
},
}
```
```js filename="next.config.js"
module.exports = {
async headers() {
return [
{
source: '/blog/:slug*',
headers: [
{
key: 'x-slug',
value: ':slug*', // Matched parameters can be used in the value
},
{
key: 'x-slug-:slug*', // Matched parameters can be used in the key
value: 'my other custom header value',
},
],
},
]
},
}
```
To match a regex path you can wrap the regex in parenthesis after a parameter,
for example `/blog/:slug(\\d{1,})` will match `/blog/123` but not `/blog/abc`:
```js filename="next.config.js"
module.exports = {
async headers() {
return [
{
source: '/blog/:post(\\d{1,})',
headers: [
{
key: 'x-post',
value: ':post',
},
],
},
]
},
}
```
The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for regex
path matching, so when used in the `source` as non-special values they must
be escaped by adding `\\` before them:
```js filename="next.config.js"
module.exports = {
async headers() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
headers: [
{
key: 'x-header',
value: 'value',
},
],
},
]
},
}
```
To only apply a header when header, cookie, or query values also match the
`has` field or don't match the `missing` field can be used. Both the `source`
and all `has` items must match and all `missing` items must not match for the
header to be applied.
```js filename="next.config.js"
module.exports = {
async headers() {
return [
// if the header `x-add-header` is present,
// the `x-another-header` header will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-add-header',
},
],
headers: [
{
key: 'x-another-header',
value: 'hello',
},
],
},
// if the header `x-no-header` is not present,
// the `x-another-header` header will be applied
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-no-header',
},
],
headers: [
{
key: 'x-another-header',
value: 'hello',
},
],
},
// if the source, query, and cookie are matched,
// the `x-authorized` header will be applied
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// the page value will not be available in the
// header key/values since value is provided and
// doesn't use a named capture group e.g. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
headers: [
{
key: 'x-authorized',
value: ':authorized',
},
],
},
// if the header `x-authorized` is present and
// contains a matching value, the `x-another-header` will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
headers: [
{
key: 'x-another-header',
value: ':authorized',
},
],
},
// if the host is `example.com`,
// this header will be applied
{
source: '/:path*',
has: [
{
type: 'host',
value: 'example.com',
},
],
headers: [
{
key: 'x-another-header',
value: ':authorized',
},
],
},
]
},
}
```
```js filename="next.config.js"
module.exports = {
basePath: '/docs',
async headers() {
return [
{
source: '/with-basePath', // becomes /docs/with-basePath
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
source: '/without-basePath', // is not modified since basePath: false is set
headers: [
{
key: 'x-hello',
value: 'world',
},
],
basePath: false,
},
]
},
}
```
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
```js filename="next.config.js"
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async headers() {
return [
{
source: '/with-locale', // automatically handles all locales
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
locale: false,
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
locale: false,
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
headers: [
{
key: 'x-hello',
value: 'world',
},
],
},
]
},
}
```
## Cache-Control
<AppOnly>
</AppOnly>
<PagesOnly>
If you need to revalidate the cache of a page that has been [statically
generated](/docs/pages/building-your-application/rendering/static-site-
generation), you can do so by setting the `revalidate` prop in the page's
[`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-
static-props) function.
type ResponseData = {
message: string
}
</PagesOnly>
## Options
### X-DNS-Prefetch-Control
[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-DNS-
Prefetch-Control) controls DNS prefetching, allowing browsers to proactively
perform domain name resolution on external links, images, CSS, JavaScript,
and more. This prefetching is performed in the background, so the [DNS]
(https://developer.mozilla.org/docs/Glossary/DNS) is more likely to be resolved
by the time the referenced items are needed. This reduces latency when the
user clicks a link.
```js
{
key: 'X-DNS-Prefetch-Control',
value: 'on'
}
```
### Strict-Transport-Security
[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-
Transport-Security) informs browsers it should only be accessed using HTTPS,
instead of using HTTP. Using the configuration below, all present and future
subdomains will use HTTPS for a `max-age` of 2 years. This blocks access to
pages or subdomains that can only be served over HTTP.
```js
{
key: 'Strict-Transport-Security',
value: 'max-age=63072000; includeSubDomains; preload'
}
```
### X-Frame-Options
[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-
Options) indicates whether the site should be allowed to be displayed within an
`iframe`. This can prevent against clickjacking attacks.
```js
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN'
}
```
### Permissions-Policy
[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/
Permissions-Policy) allows you to control which features and APIs can be used
in the browser. It was previously named `Feature-Policy`.
```js
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}
```
### X-Content-Type-Options
[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-
Content-Type-Options) prevents the browser from attempting to guess the
type of content if the `Content-Type` header is not explicitly set. This can
prevent XSS exploits for websites that allow users to upload and share files.
```js
{
key: 'X-Content-Type-Options',
value: 'nosniff'
}
```
### Referrer-Policy
[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-
Policy) controls how much information the browser includes when navigating
from the current website (origin) to another.
```js
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}
```
### Content-Security-Policy
## Version History
| Version | Changes |
| --------- | ---------------- |
| `v13.3.0` | `missing` added. |
| `v10.2.0` | `has` added. |
| `v9.5.0` | Headers added. |
---
title: httpAgentOptions
description: Next.js will automatically use HTTP Keep-Alive by default. Learn
more about how to disable HTTP Keep-Alive here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
To disable HTTP Keep-Alive for all `fetch()` calls on the server-side, open
`next.config.js` and add the `httpAgentOptions` config:
```js filename="next.config.js"
module.exports = {
httpAgentOptions: {
keepAlive: false,
},
}
```
---
title: images
description: Custom configuration for the next/image loader
---
{/* The content of this doc is shared between the app and pages router. 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. */}
If you want to use a cloud provider to optimize images instead of using the
Next.js built-in Image Optimization API, you can configure `next.config.js` with
the following:
```js filename="next.config.js"
module.exports = {
images: {
loader: 'custom',
loaderFile: './my/image/loader.js',
},
}
```
This `loaderFile` must point to a file relative to the root of your Next.js
application. The file must export a default function that returns a string, for
example:
```js
export default function myImageLoader({ src, width, quality }) {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
```
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
- [Akamai](#akamai)
- [Cloudinary](#cloudinary)
- [Cloudflare](#cloudflare)
- [Contentful](#contentful)
- [Fastly](#fastly)
- [Gumlet](#gumlet)
- [ImageEngine](#imageengine)
- [Imgix](#imgix)
- [Thumbor](#thumbor)
- [Sanity](#sanity)
- [Supabase](#supabase)
### Akamai
```js
// Docs: https://techdocs.akamai.com/ivm/reference/test-images-on-demand
export default function akamaiLoader({ src, width, quality }) {
return `https://example.com/${src}?imwidth=${width}`
}
```
### Cloudinary
```js
// Demo: https://res.cloudinary.com/demo/image/upload/w_300,c_limit,q_auto/
turtles.jpg
export default function cloudinaryLoader({ src, width, quality }) {
const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
return `https://example.com/${params.join(',')}${src}`
}
```
### Cloudflare
```js
// Docs: https://developers.cloudflare.com/images/url-format
export default function cloudflareLoader({ src, width, quality }) {
const params = [`width=${width}`, `quality=${quality || 75}`, 'format=auto']
return `https://example.com/cdn-cgi/image/${params.join(',')}/${src}`
}
```
### Contentful
```js
// Docs: https://www.contentful.com/developers/docs/references/images-api/
export default function contentfulLoader({ src, width, quality }) {
const url = new URL(`https://example.com${src}`)
url.searchParams.set('fm', 'webp')
url.searchParams.set('w', width.toString())
url.searchParams.set('q', (quality || 75).toString())
return url.href
}
```
### Fastly
```js
// Docs: https://developer.fastly.com/reference/io/
export default function fastlyLoader({ src, width, quality }) {
const url = new URL(`https://example.com${src}`)
url.searchParams.set('auto', 'webp')
url.searchParams.set('width', width.toString())
url.searchParams.set('quality', (quality || 75).toString())
return url.href
}
```
### Gumlet
```js
// Docs: https://docs.gumlet.com/reference/image-transform-size
export default function gumletLoader({ src, width, quality }) {
const url = new URL(`https://example.com${src}`)
url.searchParams.set('format', 'auto')
url.searchParams.set('w', width.toString())
url.searchParams.set('q', (quality || 75).toString())
return url.href
}
```
### ImageEngine
```js
// Docs: https://support.imageengine.io/hc/en-us/articles/360058880672-
Directives
export default function imageengineLoader({ src, width, quality }) {
const compression = 100 - (quality || 50)
const params = [`w_${width}`, `cmpr_${compression}`)]
return `https://example.com${src}?imgeng=/${params.join('/')`
}
```
### Imgix
```js
// Demo: https://static.imgix.net/daisy.png?format=auto&fit=max&w=300
export default function imgixLoader({ src, width, quality }) {
const url = new URL(`https://example.com${src}`)
const params = url.searchParams
params.set('auto', params.getAll('auto').join(',') || 'format')
params.set('fit', params.get('fit') || 'max')
params.set('w', params.get('w') || width.toString())
params.set('q', (quality || 50).toString())
return url.href
}
```
### Thumbor
```js
// Docs: https://thumbor.readthedocs.io/en/latest/
export default function thumborLoader({ src, width, quality }) {
const params = [`${width}x0`, `filters:quality(${quality || 75})`]
return `https://example.com${params.join('/')}${src}`
}
```
### Sanity
```js
// Docs: https://www.sanity.io/docs/image-urls
export default function sanityLoader({ src, width, quality }) {
const prj = 'zp7mbokg'
const dataset = 'production'
const url = new URL(`https://cdn.sanity.io/images/${prj}/${dataset}${src}`)
url.searchParams.set('auto', 'format')
url.searchParams.set('fit', 'max')
url.searchParams.set('w', width.toString())
if (quality) {
url.searchParams.set('q', quality.toString())
}
return url.href
}
```
### Supabase
```js
// Docs: https://supabase.com/docs/guides/storage/image-
transformations#nextjs-loader
export default function supabaseLoader({ src, width, quality }) {
const url = new URL(`https://example.com${src}`)
url.searchParams.set('width', width.toString())
url.searchParams.set('quality', (quality || 75).toString())
return url.href
}
```
---
title: incrementalCacheHandlerPath
description: Configure the Next.js cache used for storing and revalidating data.
---
```js filename="next.config.js"
module.exports = {
experimental: {
incrementalCacheHandlerPath: require.resolve('./cache-handler.js'),
},
}
```
```js filename="cache-handler.js"
const cache = new Map()
async get(key) {
return cache.get(key)
}
## API Reference
The cache handler can implement the following methods: `get`, `set`, and
`revalidateTag`.
### `get()`
Returns `Promise<void>`.
### `revalidateTag()`
---
title: next.config.js Options
description: Learn how to configure your application with next.config.js.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
/* config options here */
}
module.exports = nextConfig
```
`next.config.js` is a regular Node.js module, not a JSON file. It gets used by the
Next.js server and build phases, and it's not included in the browser build.
```js filename="next.config.mjs"
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
/* config options here */
}
```js filename="next.config.mjs"
export default (phase, { defaultConfig }) => {
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
/* config options here */
}
return nextConfig
}
```
```js filename="next.config.js"
module.exports = async (phase, { defaultConfig }) => {
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {
/* config options here */
}
return nextConfig
}
```
`phase` is the current context in which the configuration is loaded. You can see
the [available phases](https://github.com/vercel/next.js/blob/
5e6b008b561caf2710ab7be63320a3d549474a5b/packages/next/shared/lib/
constants.ts#L19-L23). Phases can be imported from `next/constants`:
```js
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')
return {
/* config options for all phases except development here */
}
}
```
The commented lines are the place where you can put the configs allowed by
`next.config.js`, which are [defined in this file](https://github.com/vercel/
next.js/blob/canary/packages/next/src/server/config-shared.ts).
However, none of the configs are required, and it's not necessary to understand
what each config does. Instead, search for the features you need to enable or
modify in this section and they will show you what to do.
> Avoid using new JavaScript features not available in your target Node.js
version. `next.config.js` will not be parsed by Webpack, Babel or TypeScript.
---
title: logging
description: Configure how data fetches are logged to the console when
running Next.js in development mode.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
You can configure the logging level and whether the full URL is logged to the
console when running Next.js in development mode.
Currently, `logging` only applies to data fetching using the `fetch` API. It does
not yet apply to other logs inside of Next.js.
```js filename="next.config.js"
module.exports = {
logging: {
fetches: {
fullUrl: true,
},
},
}
```
---
title: mdxRs
description: Use the new Rust compiler to compile MDX files in the App Router.
---
For use with `@next/mdx`. Compile MDX files using the new Rust compiler.
```js filename="next.config.js"
const withMDX = require('@next/mdx')()
module.exports = withMDX(nextConfig)
```
---
title: onDemandEntries
description: Configure how Next.js will dispose and keep in memory pages
created in development.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Next.js exposes some options that give you some control over how the server
will dispose or keep in memory built pages in development.
```js filename="next.config.js"
module.exports = {
onDemandEntries: {
// period (in ms) where the server will keep pages in the buffer
maxInactiveAge: 25 * 1000,
// number of pages that should be kept simultaneously without being
disposed
pagesBufferLength: 2,
},
}
```
---
title: optimizePackageImports
description: API Reference for optmizedPackageImports Next.js Config Option
---
{/* The content of this doc is shared between the app and pages router. 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. */}
```js filename="next.config.js"
module.exports = {
experimental: {
optimizePackageImports: ['package-name'],
},
}
```
---
title: output
description: Next.js automatically traces which files are needed by each page to
allow for easy deployment of your application. Learn how it works here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
During a 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.
This feature helps reduce the size of deployments drastically. Previously, when
deploying with Docker you would need to have all files from your package's
`dependencies` installed to run `next start`. Starting with Next.js 12, you can
leverage Output File Tracing in the `.next/` directory to only include the
necessary files.
Furthermore, this removes the need for the deprecated `serverless` target
which can cause various issues and also creates unnecessary duplication.
## How it Works
Next.js' production server is also traced for its needed files and output at
`.next/next-server.js.nft.json` which can be leveraged in production.
To leverage the `.nft.json` files emitted to the `.next` output directory, you can
read the list of files in each trace that are relative to the `.nft.json` file and then
copy them to your deployment location.
Next.js can automatically create a `standalone` folder that copies only the
necessary files for a production deployment including select files in
`node_modules`.
```js filename="next.config.js"
module.exports = {
output: 'standalone',
}
```
This will create a folder at `.next/standalone` which can then be deployed on its
own without installing `node_modules`.
Additionally, a minimal `server.js` file is also output which can be used instead
of `next start`. This minimal server does not copy the `public` or `.next/static`
folders by default as these should ideally be handled by a CDN instead,
although these folders can be copied to the `standalone/public` and
`standalone/.next/static` folders manually, after which `server.js` file will serve
these automatically.
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
```bash filename="Terminal"
npm i sharp
```
```bash filename="Terminal"
yarn add sharp
```
```bash filename="Terminal"
pnpm add sharp
```
```bash filename="Terminal"
bun add sharp
```
## Caveats
- While tracing in monorepo setups, the project directory is used for tracing by
default. For `next build packages/web-app`, `packages/web-app` would be the
tracing root and any files outside of that folder will not be included. To include
files outside of this folder you can set `experimental.outputFileTracingRoot` in
your `next.config.js`.
```js filename="packages/web-app/next.config.js"
module.exports = {
experimental: {
// this includes files from the monorepo base two directories up
outputFileTracingRoot: path.join(__dirname, '../../'),
},
}
```
- There are some cases in which Next.js might fail to include required files, or
might incorrectly include unused files. In those cases, you can leverage
`experimental.outputFileTracingExcludes` and
`experimental.outputFileTracingIncludes` respectively in `next.config.js`. Each
config accepts an object with [minimatch globs](https://www.npmjs.com/
package/minimatch) for the key to match specific pages and a value of an array
with globs relative to the project's root to either include or exclude in the trace.
```js filename="next.config.js"
module.exports = {
experimental: {
outputFileTracingExcludes: {
'/api/hello': ['./un-necessary-folder/**/*'],
},
outputFileTracingIncludes: {
'/api/another': ['./necessary-folder/**/*'],
},
},
}
```
- Currently, Next.js does not do anything with the emitted `.nft.json` files. The
files must be read by your deployment platform, for example [Vercel](https://
vercel.com), to create a minimal deployment. In a future release, a new
command is planned to utilize these `.nft.json` files.
## Experimental `turbotrace`
To enable it, you can add the following configuration to your `next.config.js`:
```js filename="next.config.js"
module.exports = {
experimental: {
turbotrace: {
// control the log level of the turbotrace, default is `error`
logLevel?:
| 'bug'
| 'fatal'
| 'error'
| 'warning'
| 'hint'
| 'note'
| 'suggestions'
| 'info',
// control if the log of turbotrace should contain the details of the analysis,
default is `false`
logDetail?: boolean
// show all log messages without limit
// turbotrace only show 1 log message for each categories by default
logAll?: boolean
// control the context directory of the turbotrace
// files outside of the context directory will not be traced
// set the `experimental.outputFileTracingRoot` has the same effect
// if the `experimental.outputFileTracingRoot` and this option are both set,
the `experimental.turbotrace.contextDirectory` will be used
contextDirectory?: string
// if there is `process.cwd()` expression in your code, you can set this
option to tell `turbotrace` the value of `process.cwd()` while tracing.
// for example the require(process.cwd() + '/package.json') will be traced as
require('/path/to/cwd/package.json')
processCwd?: string
// control the maximum memory usage of the `turbotrace`, in `MB`, default
is `6000`.
memoryLimit?: number
},
},
}
```
---
title: pageExtensions
description: Extend the default page extensions used by Next.js when resolving
pages in the Pages Router.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
By default, Next.js accepts files with the following extensions: `.tsx`, `.ts`,
`.jsx`, `.js`. This can be modified to allow other extensions like markdown
(`.md`, `.mdx`).
```js filename="next.config.js"
const withMDX = require('@next/mdx')()
module.exports = withMDX(nextConfig)
```
</AppOnly>
<PagesOnly>
You can extend the default Page extensions (`.tsx`, `.ts`, `.jsx`, `.js`) used by
Next.js. Inside `next.config.js`, add the `pageExtensions` config:
```js filename="next.config.js"
module.exports = {
pageExtensions: ['mdx', 'md', 'jsx', 'js', 'tsx', 'ts'],
}
```
Changing these values affects _all_ Next.js pages, including the following:
- [`middleware.js`](/docs/pages/building-your-application/routing/middleware)
- [`instrumentation.js`](/docs/pages/building-your-application/optimizing/
instrumentation)
- `pages/_document.js`
- `pages/_app.js`
- `pages/api/`
For example, if you reconfigure `.ts` page extensions to `.page.ts`, you would
need to rename pages like `middleware.page.ts`, `instrumentation.page.ts`,
`_app.page.ts`.
You can colocate test files or other files used by components in the `pages`
directory. Inside `next.config.js`, add the `pageExtensions` config:
```js filename="next.config.js"
module.exports = {
pageExtensions: ['page.tsx', 'page.ts', 'page.jsx', 'page.js'],
}
```
Then, rename your pages to have a file extension that includes `.page` (e.g.
rename `MyPage.tsx` to `MyPage.page.tsx`). Ensure you rename _all_ Next.js
pages, including the files mentioned above.
</PagesOnly>
---
title: Partial Prerendering (experimental)
description: Learn how to enable Partial Prerendering (experimental) in Next.js
14.
---
You can enable Partial Prerendering by setting the experimental `ppr` flag:
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
ppr: true,
},
}
module.exports = nextConfig
```
---
title: poweredByHeader
description: Next.js will add the `x-powered-by` header by default. Learn to
opt-out of it here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
By default Next.js will add the `x-powered-by` header. To opt-out of it, open
`next.config.js` and disable the `poweredByHeader` config:
```js filename="next.config.js"
module.exports = {
poweredByHeader: false,
}
```
---
title: productionBrowserSourceMaps
description: Enables browser source map generation during the production
build.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Next.js provides a configuration flag you can use to enable browser source map
generation during the production build:
```js filename="next.config.js"
module.exports = {
productionBrowserSourceMaps: true,
}
```
---
title: reactStrictMode
description: The complete Next.js runtime is now Strict Mode-compliant, learn
how to opt-in
---
{/* The content of this doc is shared between the app and pages router. 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. */}
> **Good to know**: Since Next.js 13.4, Strict Mode is `true` by default with
`app` router, so the above configuration is only necessary for `pages`. You can
still disable Strict Mode by setting `reactStrictMode: false`.
> **Suggested**: We strongly suggest you enable Strict Mode in your Next.js
application to better prepare your application for the future of React.
```js filename="next.config.js"
module.exports = {
reactStrictMode: true,
}
```
If you or your team are not ready to use Strict Mode in your entire application,
that's OK! You can incrementally migrate on a page-by-page basis using
`<React.StrictMode>`.
---
title: redirects
description: Add redirects to your Next.js app.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
```js filename="next.config.js"
module.exports = {
async redirects() {
return [
{
source: '/about',
destination: '/',
permanent: true,
},
]
},
}
```
> **Why does Next.js use 307 and 308?** Traditionally a 302 was used for a
temporary redirect, and a 301 for a permanent redirect, but many browsers
changed the request method of the redirect to `GET`, regardless of the original
method. For example, if the browser made a request to `POST /v1/users` which
returned status code `302` with location `/v2/users`, the subsequent request
might be `GET /v2/users` instead of the expected `POST /v2/users`. Next.js
uses the 307 temporary redirect, and 308 permanent redirect status codes to
explicitly preserve the request method used.
Redirects are checked before the filesystem which includes pages and `/
public` files.
When a redirect is applied, any query values provided in the request will be
passed through to the redirect destination. For example, see the following
redirect configuration:
```js
{
source: '/old-blog/:path*',
destination: '/blog/:path*',
permanent: false
}
```
## Path Matching
Path matches are allowed, for example `/old-blog/:slug` will match `/old-blog/
hello-world` (no nested paths):
```js filename="next.config.js"
module.exports = {
async redirects() {
return [
{
source: '/old-blog/:slug',
destination: '/news/:slug', // Matched parameters can be used in the
destination
permanent: true,
},
]
},
}
```
To match a wildcard path you can use `*` after a parameter, for example `/
blog/:slug*` will match `/blog/a/b/c/d/hello-world`:
```js filename="next.config.js"
module.exports = {
async redirects() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the
destination
permanent: true,
},
]
},
}
```
```js filename="next.config.js"
module.exports = {
async redirects() {
return [
{
source: '/post/:slug(\\d{1,})',
destination: '/news/:slug', // Matched parameters can be used in the
destination
permanent: false,
},
]
},
}
```
The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for regex
path matching, so when used in the `source` as non-special values they must
be escaped by adding `\\` before them:
```js filename="next.config.js"
module.exports = {
async redirects() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},
}
```
To only match a redirect when header, cookie, or query values also match the
`has` field or don't match the `missing` field can be used. Both the `source`
and all `has` items must match and all `missing` items must not match for the
redirect to be applied.
```js filename="next.config.js"
module.exports = {
async redirects() {
return [
// if the header `x-redirect-me` is present,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'header',
key: 'x-redirect-me',
},
],
permanent: false,
destination: '/another-page',
},
// if the header `x-dont-redirect` is present,
// this redirect will NOT be applied
{
source: '/:path((?!another-page$).*)',
missing: [
{
type: 'header',
key: 'x-do-not-redirect',
},
],
permanent: false,
destination: '/another-page',
},
// if the source, query, and cookie are matched,
// this redirect will be applied
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
permanent: false,
destination: '/another/:path*',
},
// if the header `x-authorized` is present and
// contains a matching value, this redirect will be applied
{
source: '/',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
permanent: false,
destination: '/home?authorized=:authorized',
},
// if the host is `example.com`,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'host',
value: 'example.com',
},
],
permanent: false,
destination: '/another-page',
},
]
},
}
```
```js filename="next.config.js"
module.exports = {
basePath: '/docs',
async redirects() {
return [
{
source: '/with-basePath', // automatically becomes /docs/with-basePath
destination: '/another', // automatically becomes /docs/another
permanent: false,
},
{
// does not add /docs since basePath: false is set
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
permanent: false,
},
]
},
}
```
<AppOnly>
</AppOnly>
<PagesOnly>
```js filename="next.config.js"
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async redirects() {
return [
{
source: '/with-locale', // automatically handles all locales
destination: '/another', // automatically passes the locale on
permanent: false,
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
destination: '/nl/another',
locale: false,
permanent: false,
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
destination: '/en/another',
locale: false,
permanent: false,
},
// it's possible to match all locales even when locale: false is set
{
source: '/:locale/page',
destination: '/en/newpage',
permanent: false,
locale: false,
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
destination: '/another',
permanent: false,
},
]
},
}
```
In some rare cases, you might need to assign a custom status code for older
HTTP Clients to properly redirect. In these cases, you can use the
`statusCode` property instead of the `permanent` property, but not both. To to
ensure IE11 compatibility, a `Refresh` header is automatically added for the 308
status code.
## Other Redirects
## Version History
| Version | Changes |
| --------- | ------------------ |
| `v13.3.0` | `missing` added. |
| `v10.2.0` | `has` added. |
| `v9.5.0` | `redirects` added. |
---
title: rewrites
description: Add rewrites to your Next.js app.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
<AppOnly>
Rewrites act as a URL proxy and mask the destination path, making it appear
the user hasn't changed their location on the site. In contrast, [redirects](/docs/
app/api-reference/next-config-js/redirects) will reroute to a new page and show
the URL changes.
</AppOnly>
<PagesOnly>
Rewrites act as a URL proxy and mask the destination path, making it appear
the user hasn't changed their location on the site. In contrast, [redirects](/docs/
pages/api-reference/next-config-js/redirects) will reroute to a new page and
show the URL changes.
</PagesOnly>
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/about',
destination: '/',
},
]
},
}
```
When the `rewrites` function returns an array, rewrites are applied after
checking the filesystem (pages and `/public` files) and before dynamic routes.
When the `rewrites` function returns an object of arrays with a specific shape,
this behavior can be changed and more finely controlled, as of `v10.1` of
Next.js:
```js filename="next.config.js"
module.exports = {
async rewrites() {
return {
beforeFiles: [
// These rewrites are checked after headers/redirects
// and before all files including _next/public files which
// allows overriding page files
{
source: '/some-page',
destination: '/somewhere-else',
has: [{ type: 'query', key: 'overrideMe' }],
},
],
afterFiles: [
// These rewrites are checked after pages/public files
// are checked but before dynamic routes
{
source: '/non-existent',
destination: '/somewhere-else',
},
],
fallback: [
// These rewrites are checked after both pages/public files
// and dynamic routes are checked
{
source: '/:path*',
destination: `https://my-old-site.com/:path*`,
},
],
}
},
}
```
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
## Rewrite parameters
When using parameters in a rewrite the parameters will be passed in the query
by default when none of the parameters are used in the `destination`.
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/old-about/:path*',
destination: '/about', // The :path parameter isn't used here so will be
automatically passed in the query
},
]
},
}
```
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/docs/:path*',
destination: '/:path*', // The :path parameter is used here so will not be
automatically passed in the query
},
]
},
}
```
You can still pass the parameters manually in the query if one is already used in
the destination by specifying the query in the `destination`.
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/:first/:second',
destination: '/:first?second=:second',
// Since the :first parameter is used in the destination the :second
parameter
// will not automatically be added in the query although we can manually
add it
// as shown above
},
]
},
}
```
## Path Matching
Path matches are allowed, for example `/blog/:slug` will match `/blog/hello-
world` (no nested paths):
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug',
destination: '/news/:slug', // Matched parameters can be used in the
destination
},
]
},
}
```
To match a wildcard path you can use `*` after a parameter, for example `/
blog/:slug*` will match `/blog/a/b/c/d/hello-world`:
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the
destination
},
]
},
}
```
To match a regex path you can wrap the regex in parenthesis after a parameter,
for example `/blog/:slug(\\d{1,})` will match `/blog/123` but not `/blog/abc`:
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/old-blog/:post(\\d{1,})',
destination: '/blog/:post', // Matched parameters can be used in the
destination
},
]
},
}
```
The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used for regex
path matching, so when used in the `source` as non-special values they must
be escaped by adding `\\` before them:
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
},
]
},
}
```
To only match a rewrite when header, cookie, or query values also match the
`has` field or don't match the `missing` field can be used. Both the `source`
and all `has` items must match and all `missing` items must not match for the
rewrite to be applied.
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
// if the header `x-rewrite-me` is present,
// this rewrite will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// if the header `x-rewrite-me` is not present,
// this rewrite will be applied
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// if the source, query, and cookie are matched,
// this rewrite will be applied
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
destination: '/:path*/home',
},
// if the header `x-authorized` is present and
// contains a matching value, this rewrite will be applied
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
destination: '/home?authorized=:authorized',
},
// if the host is `example.com`,
// this rewrite will be applied
{
source: '/:path*',
has: [
{
type: 'host',
value: 'example.com',
},
],
destination: '/another-page',
},
]
},
}
```
<details>
<summary>Examples</summary>
</details>
Rewrites allow you to rewrite to an external url. This is especially useful for
incrementally adopting Next.js. The following is an example rewrite for
redirecting the `/blog` route of your main app to an external site.
```js filename="next.config.js"
module.exports = {
async rewrites() {
return [
{
source: '/blog',
destination: 'https://example.com/blog',
},
{
source: '/blog/:slug',
destination: 'https://example.com/blog/:slug', // Matched parameters can
be used in the destination
},
]
},
}
```
If you're using `trailingSlash: true`, you also need to insert a trailing slash in the
`source` parameter. If the destination server is also expecting a trailing slash it
should be included in the `destination` parameter as well.
```js filename="next.config.js"
module.exports = {
trailingSlash: true,
async rewrites() {
return [
{
source: '/blog/',
destination: 'https://example.com/blog/',
},
{
source: '/blog/:path*/',
destination: 'https://example.com/blog/:path*/',
},
]
},
}
```
You can also have Next.js fall back to proxying to an existing website after
checking all Next.js routes.
This way you don't have to change the rewrites configuration when migrating
more pages to Next.js
```js filename="next.config.js"
module.exports = {
async rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: `https://custom-routes-proxying-
endpoint.vercel.app/:path*`,
},
],
}
},
}
```
```js filename="next.config.js"
module.exports = {
basePath: '/docs',
async rewrites() {
return [
{
source: '/with-basePath', // automatically becomes /docs/with-basePath
destination: '/another', // automatically becomes /docs/another
},
{
// does not add /docs to /without-basePath since basePath: false is set
// Note: this can not be used for internal rewrites e.g. `destination: '/
another'`
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
},
]
},
}
```
<AppOnly>
</AppOnly>
<PagesOnly>
</PagesOnly>
```js filename="next.config.js"
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async rewrites() {
return [
{
source: '/with-locale', // automatically handles all locales
destination: '/another', // automatically passes the locale on
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
destination: '/nl/another',
locale: false,
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
destination: '/en/another',
locale: false,
},
{
// it's possible to match all locales even when locale: false is set
source: '/:locale/api-alias/:path*',
destination: '/api/:path*',
locale: false,
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
destination: '/another',
},
]
},
}
```
## Version History
| Version | Changes |
| --------- | ---------------- |
| `v13.3.0` | `missing` added. |
| `v10.2.0` | `has` added. |
| `v9.5.0` | Headers added. |
---
title: serverComponentsExternalPackages
description: Opt-out specific dependencies from the Server Components
bundling and use native Node.js `require`.
---
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
serverComponentsExternalPackages: ['@acme/ui'],
},
}
module.exports = nextConfig
```
- `@aws-sdk/client-s3`
- `@aws-sdk/s3-presigned-post`
- `@blockfrost/blockfrost-js`
- `@libsql/client`
- `@jpg-store/lucid-cardano`
- `@mikro-orm/core`
- `@mikro-orm/knex`
- `@prisma/client`
- `@sentry/nextjs`
- `@sentry/node`
- `@swc/core`
- `argon2`
- `autoprefixer`
- `aws-crt`
- `bcrypt`
- `better-sqlite3`
- `canvas`
- `cpu-features`
- `cypress`
- `eslint`
- `express`
- `firebase-admin`
- `jest`
- `jsdom`
- `libsql`
- `lodash`
- `mdx-bundler`
- `mongodb`
- `mongoose`
- `next-mdx-remote`
- `next-seo`
- `payload`
- `pg`
- `playwright`
- `postcss`
- `prettier`
- `prisma`
- `puppeteer`
- `rimraf`
- `sharp`
- `shiki`
- `sqlite3`
- `tailwindcss`
- `ts-node`
- `typescript`
- `vscode-oniguruma`
- `webpack`
---
title: trailingSlash
description: Configure Next.js pages to resolve with or without a trailing slash.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
By default Next.js will redirect urls with trailing slashes to their counterpart
without a trailing slash. For example `/about/` will redirect to `/about`. You can
configure this behavior to act the opposite way, where urls without trailing
slashes are redirected to their counterparts with trailing slashes.
```js filename="next.config.js"
module.exports = {
trailingSlash: true,
}
```
With this option set, urls like `/about` will redirect to `/about/`.
## Version History
| Version | Changes |
| -------- | ---------------------- |
| `v9.5.0` | `trailingSlash` added. |
---
title: transpilePackages
description: Automatically transpile and bundle dependencies from local
packages (like monorepos) or from external dependencies (`node_modules`).
---
{/* The content of this doc is shared between the app and pages router. 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. */}
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['@acme/ui', 'lodash-es'],
}
module.exports = nextConfig
```
## Version History
| Version | Changes |
| --------- | -------------------------- |
| `v13.0.0` | `transpilePackages` added. |
---
title: turbo (Experimental)
nav_title: turbo
description: Configure Next.js with Turbopack-specific options
---
{/* The content of this doc is shared between the app and pages router. 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. */}
> **Warning**: These features are experimental and will only work with `next
--turbo`.
## webpack loaders
To configure loaders, add the names of the loaders you've installed and any
options in `next.config.js`, mapping file extensions to a list of loaders:
```js filename="next.config.js"
module.exports = {
experimental: {
turbo: {
rules: {
// Option format
'*.md': [
{
loader: '@mdx-js/loader',
options: {
format: 'md',
},
},
],
// Option-less format
'*.mdx': ['@mdx-js/loader'],
},
},
},
}
```
Then, given the above configuration, you can use transformed code from your
app:
```js
import MyDoc from './my-doc.mdx'
## Resolve Alias
```js filename="next.config.js"
module.exports = {
experimental: {
turbo: {
resolveAlias: {
underscore: 'lodash',
mocha: { browser: 'mocha/browser-entry.js' },
},
},
},
}
```
For more information and guidance for how to migrate your app to Turbopack
from webpack, see [Turbopack's documentation on webpack compatibility]
(https://turbo.build/pack/docs/migrating-from-webpack).
---
title: typedRoutes (experimental)
nav_title: typedRoutes
description: Enable experimental support for statically typed links.
---
```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
experimental: {
typedRoutes: true,
},
}
module.exports = nextConfig
```
---
title: typescript
description: Next.js reports TypeScript errors by default. Learn to opt-out of
this behavior here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Next.js fails your **production build** (`next build`) when TypeScript errors
are present in your project.
If you'd like Next.js to dangerously produce production code even when your
application has errors, you can disable the built-in type checking step.
If disabled, be sure you are running type checks as part of your build or deploy
process, otherwise this can be very dangerous.
```js filename="next.config.js"
module.exports = {
typescript: {
// !! WARN !!
// Dangerously allow production builds to successfully complete even if
// your project has type errors.
// !! WARN !!
ignoreBuildErrors: true,
},
}
```
---
title: urlImports
description: Configure Next.js to allow importing modules from external URLs
(experimental).
---
{/* The content of this doc is shared between the app and pages router. 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. */}
URL imports are an experimental feature that allows you to import modules
directly from external servers (instead of from the local disk).
> **Warning**: This feature is experimental. Only use domains that you trust to
download and execute on your machine. Please exercise
> discretion, and caution until the feature is flagged as stable.
```js filename="next.config.js"
module.exports = {
experimental: {
urlImports: ['https://example.com/assets/', 'https://cdn.skypack.dev'],
},
}
```
```js
import { a, b, c } from 'https://example.com/assets/some/module.js'
```
URL Imports can be used everywhere normal package imports can be used.
## Security Model
This feature is being designed with **security as the top priority**. To start,
we added an experimental flag forcing you to explicitly allow the domains you
accept URL imports from. We're working to take this further by limiting URL
imports to execute in the browser sandbox using the [Edge Runtime](/docs/
app/api-reference/edge).
## Lockfile
When using URL imports, Next.js will create a `next.lock` directory containing a
lockfile and fetched assets.
This directory **must be committed to Git**, not ignored by `.gitignore`.
- When running `next dev`, Next.js will download and add all newly discovered
URL Imports to your lockfile
- When running `next build`, Next.js will use only the lockfile to build the
application for production
Typically, no network requests are needed and any outdated lockfile will cause
the build to fail.
One exception is resources that respond with `Cache-Control: no-cache`.
These resources will have a `no-cache` entry in the lockfile and will always be
fetched from the network on each build.
## Examples
### Skypack
```js
import confetti from 'https://cdn.skypack.dev/canvas-confetti'
import { useEffect } from 'react'
```js
import Image from 'next/image'
import logo from 'https://example.com/assets/logo.png'
```css
.className {
background: url('https://example.com/assets/hero.jpg');
}
```
```js
const logo = new URL('https://example.com/assets/file.txt', import.meta.url)
console.log(logo.pathname)
// prints "/_next/static/media/file.a9727b5d.txt"
```
---
title: Custom Webpack Config
nav_title: webpack
description: Learn how to customize the webpack config used by Next.js
---
{/* The content of this doc is shared between the app and pages router. 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. */}
> **Good to know**: changes to webpack config are not covered by semver so
proceed at your own risk
<AppOnly>
- [CSS imports](/docs/app/building-your-application/styling)
- [CSS modules](/docs/app/building-your-application/styling/css-modules)
- [Sass/SCSS imports](/docs/app/building-your-application/styling/sass)
- [Sass/SCSS modules](/docs/app/building-your-application/styling/sass)
- [preact](https://github.com/vercel/next.js/tree/canary/examples/using-preact)
</AppOnly>
<PagesOnly>
- [CSS imports](/docs/pages/building-your-application/styling)
- [CSS modules](/docs/pages/building-your-application/styling/css-modules)
- [Sass/SCSS imports](/docs/pages/building-your-application/styling/sass)
- [Sass/SCSS modules](/docs/pages/building-your-application/styling/sass)
- [preact](https://github.com/vercel/next.js/tree/canary/examples/using-preact)
- [Customizing babel configuration](/docs/pages/building-your-application/
configuring/babel)
</PagesOnly>
- [@next/mdx](https://github.com/vercel/next.js/tree/canary/packages/next-
mdx)
- [@next/bundle-analyzer](https://github.com/vercel/next.js/tree/canary/
packages/next-bundle-analyzer)
In order to extend our usage of `webpack`, you can define a function that
extends its config inside `next.config.js`, like so:
```js filename="next.config.js"
module.exports = {
webpack: (
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
) => {
// Important: return the modified config
return config
},
}
```
> The `webpack` function is executed three times, twice for the server
(nodejs / edge runtime) and once for the client. This allows you to distinguish
between client and server configuration using the `isServer` property.
The second argument to the `webpack` function is an object with the following
properties:
- `buildId`: `String` - The build id, used as a unique identifier between builds
- `dev`: `Boolean` - Indicates if the compilation will be done in development
- `isServer`: `Boolean` - It's `true` for server-side compilation, and `false` for
client-side compilation
- `nextRuntime`: `String | undefined` - The target runtime for server-side
compilation; either `"edge"` or `"nodejs"`, it's `undefined` for client-side
compilation.
- `defaultLoaders`: `Object` - Default loaders used internally by Next.js:
- `babel`: `Object` - Default `babel-loader` configuration
```js
// Example config for adding a loader that depends on babel-loader
// This source was taken from the @next/mdx plugin source:
// https://github.com/vercel/next.js/tree/canary/packages/next-mdx
module.exports = {
webpack: (config, options) => {
config.module.rules.push({
test: /\.mdx/,
use: [
options.defaultLoaders.babel,
{
loader: '@mdx-js/loader',
options: pluginOptions.options,
},
],
})
return config
},
}
```
#### `nextRuntime`
---
title: webVitalsAttribution
description: Learn how to use the webVitalsAttribution option to pinpoint the
source of Web Vitals issues.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
Pinpointing the biggest contributor to the Web Vitals score, aka [attribution]
(https://github.com/GoogleChrome/web-vitals/blob/
4ca38ae64b8d1e899028c692f94d4c56acfc996c/README.md#attribution),
allows us to obtain more in-depth information like entries for
[PerformanceEventTiming](https://developer.mozilla.org/docs/Web/API/
PerformanceEventTiming), [PerformanceNavigationTiming](https://
developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming) and
[PerformanceResourceTiming](https://developer.mozilla.org/docs/Web/API/
PerformanceResourceTiming).
---
title: create-next-app
description: Create Next.js apps in one command with create-next-app.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
The easiest way to get started with Next.js is by using `create-next-app`. This
CLI tool enables you to quickly start building a new Next.js application, with
everything set up for you.
You can create a new app using the default Next.js template, or by using one of
the [official Next.js examples](https://github.com/vercel/next.js/tree/canary/
examples).
### Interactive
```bash filename="Terminal"
npx create-next-app@latest
```
```bash filename="Terminal"
yarn create next-app
```
```bash filename="Terminal"
pnpm create next-app
```
```bash filename="Terminal"
bunx create-next-app
```
```txt filename="Terminal"
What is your project named? my-app
Would you like to use TypeScript? No / Yes
Would you like to use ESLint? No / Yes
Would you like to use Tailwind CSS? No / Yes
Would you like to use `src/` directory? No / Yes
Would you like to use App Router? (recommended) No / Yes
Would you like to customize the default import alias (@/*)? No / Yes
```
Once you've answered the prompts, a new project will be created with the
correct configuration depending on your answers.
### Non-interactive
You can also pass command line arguments to set up a new project non-
interactively.
Further, you can negate default options by prefixing them with `--no-` (e.g. `--
no-eslint`).
```bash filename="Terminal"
Usage: create-next-app <project-directory> [options]
Options:
-V, --version output the version number
--ts, --typescript
--js, --javascript
--tailwind
--eslint
Initialize with ESLint config.
--app
--src-dir
--import-alias <alias-to-configure>
--use-npm
--use-pnpm
--use-yarn
--use-bun
An example to bootstrap the app with. You can use an example name
from the official Next.js repo or a public GitHub URL. The URL can use
any branch and/or subdirectory
--example-path <path-to-example>
In a rare case, your GitHub URL might contain a branch name with
a slash (e.g. bug/fix-1) and the path to the example (e.g. foo/bar).
In this case, you must specify the path to the example separately:
--example-path foo/bar
--reset-preferences
---
title: Edge Runtime
description: API Reference for the Edge Runtime.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
The Next.js Edge Runtime is based on standard Web APIs, it supports the
following APIs:
## Network APIs
| API | Description |
|
-------------------------------------------------------------------------------
| --------------------------------- |
| [`Blob`](https://developer.mozilla.org/docs/Web/API/Blob) |
Represents a blob |
| [`fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API) |
Fetches a resource |
| [`FetchEvent`](https://developer.mozilla.org/docs/Web/API/FetchEvent) |
Represents a fetch event |
| [`File`](https://developer.mozilla.org/docs/Web/API/File) |
Represents a file |
| [`FormData`](https://developer.mozilla.org/docs/Web/API/FormData) |
Represents form data |
| [`Headers`](https://developer.mozilla.org/docs/Web/API/Headers) |
Represents HTTP headers |
| [`Request`](https://developer.mozilla.org/docs/Web/API/Request) |
Represents an HTTP request |
| [`Response`](https://developer.mozilla.org/docs/Web/API/Response) |
Represents an HTTP response |
| [`URLSearchParams`](https://developer.mozilla.org/docs/Web/API/
URLSearchParams) | Represents URL search parameters |
| [`WebSocket`](https://developer.mozilla.org/docs/Web/API/WebSocket)
| Represents a websocket connection |
## Encoding APIs
| API | Description
|
|
-------------------------------------------------------------------------------
---- | ---------------------------------- |
| [`atob`](https://developer.mozilla.org/docs/Web/API/
WindowOrWorkerGlobalScope/atob) | Decodes a base-64 encoded string |
| [`btoa`](https://developer.mozilla.org/docs/Web/API/
WindowOrWorkerGlobalScope/btoa) | Encodes a string in base-64 |
| [`TextDecoder`](https://developer.mozilla.org/docs/Web/API/TextDecoder)
| Decodes a Uint8Array into a string |
| [`TextDecoderStream`](https://developer.mozilla.org/docs/Web/API/
TextDecoderStream) | Chainable decoder for streams |
| [`TextEncoder`](https://developer.mozilla.org/docs/Web/API/TextEncoder)
| Encodes a string into a Uint8Array |
| [`TextEncoderStream`](https://developer.mozilla.org/docs/Web/API/
TextEncoderStream) | Chainable encoder for streams |
## Stream APIs
| API | Description
|
|
-------------------------------------------------------------------------------
------------------------ | --------------------------------------- |
| [`ReadableStream`](https://developer.mozilla.org/docs/Web/API/
ReadableStream) | Represents a readable stream |
| [`ReadableStreamBYOBReader`](https://developer.mozilla.org/docs/Web/API/
ReadableStreamBYOBReader) | Represents a reader of a ReadableStream |
| [`ReadableStreamDefaultReader`](https://developer.mozilla.org/docs/Web/
API/ReadableStreamDefaultReader) | Represents a reader of a ReadableStream
|
| [`TransformStream`](https://developer.mozilla.org/docs/Web/API/
TransformStream) | Represents a transform stream |
| [`WritableStream`](https://developer.mozilla.org/docs/Web/API/
WritableStream) | Represents a writable stream |
| [`WritableStreamDefaultWriter`](https://developer.mozilla.org/docs/Web/API/
WritableStreamDefaultWriter) | Represents a writer of a WritableStream |
## Crypto APIs
| API | Description
|
| ------------------------------------------------------------------------- |
-------------------------------------------------------------------------------
-------------------- |
| [`crypto`](https://developer.mozilla.org/docs/Web/API/Window/crypto) |
Provides access to the cryptographic functionality of the platform
|
| [`CryptoKey`](https://developer.mozilla.org/docs/Web/API/CryptoKey) |
Represents a cryptographic key |
| [`SubtleCrypto`](https://developer.mozilla.org/docs/Web/API/SubtleCrypto) |
Provides access to common cryptographic primitives, like hashing, signing,
encryption or decryption |
| API |
Description
|
|
-------------------------------------------------------------------------------
-------------------------------------- |
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------- |
| [`AbortController`](https://developer.mozilla.org/docs/Web/API/
AbortController) | Allows you to abort one or more DOM
requests as and when desired
|
| [`Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Array) | Represents an array of values
|
| [`ArrayBuffer`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/ArrayBuffer) | Represents a generic, fixed-length raw
binary data buffer
|
| [`Atomics`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Atomics) | Provides atomic operations as static
methods
|
| [`BigInt`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/BigInt) | Represents a whole number with
arbitrary precision
|
| [`BigInt64Array`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/BigInt64Array) | Represents a typed array of
64-bit signed integers
|
| [`BigUint64Array`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/BigUint64Array) | Represents a typed array of
64-bit unsigned integers
|
| [`Boolean`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Boolean) | Represents a logical entity and can
have two values: `true` and `false`
|
| [`clearInterval`](https://developer.mozilla.org/docs/Web/API/
WindowOrWorkerGlobalScope/clearInterval) | Cancels a timed,
repeating action which was previously established by a call to `setInterval()`
|
| [`clearTimeout`](https://developer.mozilla.org/docs/Web/API/
WindowOrWorkerGlobalScope/clearTimeout) | Cancels a timed,
repeating action which was previously established by a call to `setTimeout()`
|
| [`console`](https://developer.mozilla.org/docs/Web/API/Console)
| Provides access to the browser's debugging console
|
| [`DataView`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/DataView) | Represents a generic view of an
`ArrayBuffer`
|
| [`Date`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Date) | Represents a single moment in time in a
platform-independent format
|
| [`decodeURI`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/decodeURI) | Decodes a Uniform Resource Identifier
(URI) previously created by `encodeURI` or by a similar routine
|
| [`decodeURIComponent`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/decodeURIComponent) | Decodes a Uniform
Resource Identifier (URI) component previously created by
`encodeURIComponent` or by a similar routine
|
| [`DOMException`](https://developer.mozilla.org/docs/Web/API/
DOMException) | Represents an error that occurs in
the DOM
|
| [`encodeURI`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/encodeURI) | Encodes a Uniform Resource Identifier
(URI) by replacing each instance of certain characters by one, two, three, or
four escape sequences representing the UTF-8 encoding of the character
|
| [`encodeURIComponent`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/encodeURIComponent) | Encodes a Uniform
Resource Identifier (URI) component by replacing each instance of certain
characters by one, two, three, or four escape sequences representing the
UTF-8 encoding of the character |
| [`Error`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Error) | Represents an error when trying to
execute a statement or accessing a property
|
| [`EvalError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/EvalError) | Represents an error that occurs
regarding the global function `eval()`
|
| [`Float32Array`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/Float32Array) | Represents a typed array of
32-bit floating point numbers
|
| [`Float64Array`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/Float64Array) | Represents a typed array of
64-bit floating point numbers
|
| [`Function`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Function) | Represents a function
|
| [`Infinity`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Infinity) | Represents the mathematical Infinity value
|
| [`Int8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Int8Array) | Represents a typed array of 8-bit signed
integers
|
| [`Int16Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Int16Array) | Represents a typed array of 16-bit
signed integers
|
| [`Int32Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Int32Array) | Represents a typed array of 32-bit
signed integers
|
| [`Intl`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Intl) | Provides access to internationalization
and localization functionality
|
| [`isFinite`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/isFinite) | Determines whether a value is a finite
number
|
| [`isNaN`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/isNaN) | Determines whether a value is `NaN` or
not
|
| [`JSON`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/JSON) | Provides functionality to convert
JavaScript values to and from the JSON format
|
| [`Map`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Map) | Represents a collection of values,
where each value may occur only once
|
| [`Math`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Math) | Provides access to mathematical
functions and constants
|
| [`Number`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Number) | Represents a numeric value
|
| [`Object`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Object) | Represents the object that is the base
of all JavaScript objects
|
| [`parseFloat`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/parseFloat) | Parses a string argument and returns a
floating point number
|
| [`parseInt`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/parseInt) | Parses a string argument and returns an
integer of the specified radix
|
| [`Promise`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Promise) | Represents the eventual completion (or
failure) of an asynchronous operation, and its resulting value
|
| [`Proxy`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Proxy) | Represents an object that is used to
define custom behavior for fundamental operations (e.g. property lookup,
assignment, enumeration, function invocation, etc) |
| [`queueMicrotask`](https://developer.mozilla.org/docs/Web/API/
queueMicrotask) | Queues a microtask to be executed
|
| [`RangeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/RangeError) | Represents an error when a value is not
in the set or range of allowed values
|
| [`ReferenceError`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/ReferenceError) | Represents an error when a
non-existent variable is referenced
|
| [`Reflect`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Reflect) | Provides methods for interceptable
JavaScript operations
|
| [`RegExp`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/RegExp) | Represents a regular expression,
allowing you to match combinations of characters
|
| [`Set`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Set) | Represents a collection of values,
where each value may occur only once
|
| [`setInterval`](https://developer.mozilla.org/docs/Web/API/setInterval)
| Repeatedly calls a function, with a fixed time delay between each call
|
| [`setTimeout`](https://developer.mozilla.org/docs/Web/API/setTimeout)
| Calls a function or evaluates an expression after a specified number of
milliseconds
|
| [`SharedArrayBuffer`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/SharedArrayBuffer) | Represents a generic, fixed-
length raw binary data buffer
|
| [`String`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/String) | Represents a sequence of characters
|
| [`structuredClone`](https://developer.mozilla.org/docs/Web/API/
Web_Workers_API/Structured_clone_algorithm) | Creates a deep copy of
a value
|
| [`Symbol`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Symbol) | Represents a unique and immutable
data type that is used as the key of an object property
|
| [`SyntaxError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/SyntaxError) | Represents an error when trying to
interpret syntactically invalid code
|
| [`TypeError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/TypeError) | Represents an error when a value is not
of the expected type
|
| [`Uint8Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Uint8Array) | Represents a typed array of 8-bit
unsigned integers
|
| [`Uint8ClampedArray`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/Uint8ClampedArray) | Represents a typed array of
8-bit unsigned integers clamped to 0-255
|
| [`Uint32Array`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/Uint32Array) | Represents a typed array of 32-bit
unsigned integers
|
| [`URIError`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/URIError) | Represents an error when a global URI
handling function was used in a wrong way
|
| [`URL`](https://developer.mozilla.org/docs/Web/API/URL)
| Represents an object providing static methods used for creating object URLs
|
| [`URLPattern`](https://developer.mozilla.org/docs/Web/API/URLPattern)
| Represents a URL pattern
|
| [`URLSearchParams`](https://developer.mozilla.org/docs/Web/API/
URLSearchParams) | Represents a collection of key/value
pairs
|
| [`WeakMap`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/WeakMap) | Represents a collection of key/value
pairs in which the keys are weakly referenced
|
| [`WeakSet`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/WeakSet) | Represents a collection of objects in
which each object may occur only once
|
| [`WebAssembly`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/WebAssembly) | Provides access to
WebAssembly
|
- [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-
asynclocalstorage)
## Environment Variables
## Unsupported APIs
- Native Node.js APIs **are not supported**. For example, you can't read or
write to the filesystem.
- `node_modules` _can_ be used, as long as they implement ES Modules and
do not use native Node.js APIs.
- Calling `require` directly is **not allowed**. Use ES Modules instead.
The following JavaScript language features are disabled, and **will not work:**
| API |
Description |
|
-------------------------------------------------------------------------------
------------------------------------------------ |
------------------------------------------------------------------- |
| [`eval`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/
Global_Objects/eval) | Evaluates JavaScript code
represented as a string |
| [`new Function(evalString)`](https://developer.mozilla.org/docs/Web/
JavaScript/Reference/Global_Objects/Function) | Creates a new
function with the code provided as an argument |
| [`WebAssembly.compile`](https://developer.mozilla.org/docs/Web/JavaScript/
Reference/Global_Objects/WebAssembly/compile) | Compiles a
WebAssembly module from a buffer source |
| [`WebAssembly.instantiate`](https://developer.mozilla.org/docs/Web/
JavaScript/Reference/Global_Objects/WebAssembly/instantiate) | Compiles and
instantiates a WebAssembly module from a buffer source |
In rare cases, your code could contain (or import) some dynamic code
evaluation statements which _can not be reached at runtime_ and which can
not be removed by treeshaking.
You can relax the check to allow specific files with your Middleware or Edge API
Route exported configuration:
```javascript
export const config = {
runtime: 'edge', // for Edge API Routes only
unstable_allowDynamic: [
// allows a single file
'/lib/utilities.js',
// use a glob to allow anything in the function-bind 3rd party module
'/node_modules/function-bind/**',
],
}
```
`unstable_allowDynamic` is a [glob](https://github.com/micromatch/
micromatch#matching-features), or an array of globs, ignoring dynamic code
evaluation for specific files. The globs are relative to your application root
folder.
Be warned that if these statements are executed on the Edge, _they will throw
and cause a runtime error_.
---
title: Next.js CLI
description: The Next.js CLI allows you to start, build, and export your
application. Learn more about it here.
---
{/* The content of this doc is shared between the app and pages router. 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. */}
The Next.js CLI allows you to start, build, and export your application.
To get a list of the available CLI commands, run the following command inside
your project directory:
```bash filename="Terminal"
npx next -h
```
_([npx](https://medium.com/@maybekatz/introducing-npx-an-npm-package-
runner-55f7d4bd282b) comes with npm 5.2+ and higher)_
Available commands
build, start, export, dev, lint, telemetry, info
Options
--version, -v Version number
--help, -h Displays this message
```bash filename="Terminal"
NODE_OPTIONS='--throw-deprecation' next
NODE_OPTIONS='-r esm' next
NODE_OPTIONS='--inspect' next
```
## Build
Both of these values are **compressed with gzip**. The first load is indicated
by green, yellow, or red. Aim for green for performant applications.
You can enable production profiling for React with the `--profile` flag in `next
build`. This requires [Next.js 9.5](https://nextjs.org/blog/next-9-5):
```bash filename="Terminal"
next build --profile
```
After that, you can use the profiler in the same way as you would in
development.
You can enable more verbose build output with the `--debug` flag in `next
build`. This requires Next.js 9.5.3:
```bash filename="Terminal"
next build --debug
```
With this flag enabled additional build output like rewrites, redirects, and
headers will be shown.
## Development
`next dev` starts the application in development mode with hot-code reloading,
error reporting, and more:
```bash filename="Terminal"
npx next dev -p 4000
```
```bash filename="Terminal"
PORT=4000 npx next dev
```
> **Good to know**: `PORT` cannot be set in `.env` as booting up the HTTP
server happens before any other code is initialized.
You can also set the hostname to be different from the default of `0.0.0.0`, this
can be useful for making the application available for other devices on the
network. The default hostname can be changed with `-H`, like so:
```bash filename="Terminal"
npx next dev -H 192.168.1.2
```
## Production
`next start` starts the application in production mode. The application should
be compiled with [`next build`](#build) first.
The application will start at `http://localhost:3000` by default. The default port
can be changed with `-p`, like so:
```bash filename="Terminal"
npx next start -p 4000
```
```bash filename="Terminal"
PORT=4000 npx next start
```
To configure the timeout values for the production Next.js server, pass `--
keepAliveTimeout` (in milliseconds) to `next start`, like so:
```bash filename="Terminal"
npx next start --keepAliveTimeout 70000
```
## Lint
`next lint` runs ESLint for all files in the `pages/`, `app/`, `components/`, `lib/
`, and `src/` directories. It also
provides a guided setup to install any required dependencies if ESLint is not
already configured in
your application.
If you have other directories that you would like to lint, you can specify them
using the `--dir`
flag:
```bash filename="Terminal"
next lint --dir utils
```
## Telemetry
## Next Info
`next info` prints relevant details about the current system which can be used
to report Next.js bugs.
This information includes Operating System platform/arch/version, Binaries
(Node.js, npm, Yarn, pnpm) and npm package versions (`next`, `react`, `react-
dom`).
```bash filename="Terminal"
next info
```
```bash filename="Terminal"
Operating System:
Platform: linux
Arch: x64
Version: #22-Ubuntu SMP Fri Nov 5 13:21:36 UTC 2021
Binaries:
Node: 16.13.0
npm: 8.1.0
Yarn: 1.22.17
pnpm: 6.24.2
Relevant packages:
next: 12.0.8
react: 17.0.2
react-dom: 17.0.2
```
In order to diagnose installation issues, you can run `next info --verbose` to
print additional information about system and the installation of next-related
packages.
---
title: API Reference
description: Next.js API Reference for the App Router.
---