function HomePage() {
  return
Hello World

}

export default HomePage
Note that dynamic lookups will not be inlined, such as:
 // This will NOT be inlined, because it uses a variable
const varName = 'NEXT_PUBLIC_ANALYTICS_ID'
setupAnalyticsService(process.env[varName])

// This will NOT be inlined, because it uses a variable
const env = process.env
setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID)
Default Environment Variables
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.
Next.js allows you to set defaults in .env (all environments), .env.development (development environment), and .env.production (production environment).
.env.local always overrides the defaults set.


.env.local always overrides the defaults set.
Good to know: .env, .env.development, and .env.production files should be included in your repository as they define defaults. .env*.local should be added to .gitignore, as those files are intended to be ignored. .env.local is where secrets can be stored.
Environment Variables on Vercel
When deploying your Next.js application to Vercel, Environment Variables can be configured in the Project Settings.
All types of Environment Variables should be configured there. Even Environment Variables used in Development – which can be downloaded onto your local device afterwards.
If you've configured Development Environment Variables you can pull them into a .env.local for usage on your local machine using the following command:
Terminal vercel env pull .env.local
Test Environment Variables


Terminal vercel env pull .env.local
Test Environment Variables
Apart from development and production environments, there is a 3rd option available: test. In the same way you can set defaults for development or production environments, you can do the same with a .env.test file for the testing environment (though this one is not as common as the previous two). Next.js will not load environment variables from .env.development or .env.production in the testing environment.
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.


There is a small difference between test environment, and both development and production that you need to bear in mind: .env.local won't be loaded, as you expect tests to produce the same results for everyone. This way every test execution will use the same env defaults across different executions by ignoring your .env.local (which is intended to override the default set).
Good to know: similar to Default Environment Variables, .env.test file should be included in your repository, but .env.test.local shouldn't, as .env*.local are intended to be ignored through .gitignore.
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.
 // The below can be used in a Jest global setup file or similar for your testing set-up
import { loadEnvConfig } from '@next/env'

export default async () => {


export default async () => {
  const projectDir = process.cwd()
  loadEnvConfig(projectDir)
}
Environment Variable Load Order
Environment variables are looked up in the following places, in order, stopping once the variable is found.
process.env
.env.$(NODE_ENV).local
.env.local (Not checked when NODE_ENV is test.)
.env.$(NODE_ENV)
.env
For example, if NODE_ENV is development and you define a variable in both .env.development.local and .env, the value in .env.development.local will be used.
Good to know: The allowed values for NODE_ENV are production, development and test.
Good to know
If you are using a /src directory, .env.* files should remain in the root of your project.
If the environment variable NODE_ENV is unassigned, Next.js automatically assigns development when running the next dev command, or production for all other commands.


Absolute Imports and Module Path Aliases
Examples
Absolute Imports and Aliases
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:
 // before
import { Button } from '../../../components/button'

// after
import { Button } from '@/components/button'
Good to know: create-next-app will prompt to configure these options for you.
Absolute Imports
The baseUrl configuration option allows you to import directly from the root of the project.
An example of this configuration:
tsconfig.json or jsconfig.json {
  "compilerOptions": {
    "baseUrl": "."
  }
}
components/button.tsx export default function Button() {
  return <button>Click me</button>
}
app/page.tsx import Button from 'components/button'


}
app/page.tsx import Button from 'components/button'

export default function HomePage() {
  return (
    <>

Hello World

      <Button />
    </>
  )
}
Module Aliases
In addition to configuring the baseUrl path, you can use the "paths" option to "alias" module paths.
For example, the following configuration maps @/components/* to components/*:
tsconfig.json or jsconfig.json {
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/components/*": ["components/*"]
    }
  }
}
components/button.tsx export default function Button() {
  return <button>Click me</button>
}
app/page.tsx import Button from '@/components/button'

export default function HomePage() {
  return (
    <>


export default function HomePage() {
  return (
    <>

Hello World

      <Button />
    </>
  )
}
Each of the "paths" are relative to the baseUrl location. For example:
 // tsconfig.json or jsconfig.json
{
  "compilerOptions": {
    "baseUrl": "src/",
    "paths": {
      "@/styles/*": ["styles/*"],
      "@/components/*": ["components/*"]
    }
  }
}
 // pages/index.js
import Button from '@/components/button'
import '@/styles/styles.css'
import Helper from 'utils/helper'

export default function HomePage() {
  return (
    <Helper>

Hello World

      <Button />
    </Helper>
  )
}


MDX
Markdown 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...
 I **love** using [Next.js](https://nextjs.org/)
Output:

I love using Next.js

MDX is a superset of markdown that lets you write JSX directly in your markdown files. It is a powerful way to add dynamic interactivity and embed React components within your content.
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 (default in app).
@next/mdx


@next/mdx
The @next/mdx package is configured in the next.config.js file at your projects root. It sources data from local files, allowing you to create pages with a .mdx extension, directly in your /pages or /app directory.
Getting Started
Install the @next/mdx package:Terminal npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdxCreate mdx-components.tsx in the root of your application (the parent folder of app/ or src/):mdx-components.tsx import type { MDXComponents } from 'mdx/types'

// This file allows you to provide custom React components
// to be used in MDX files. You can import and use any
// React component you want, including components from
// other libraries.

// This file is required to use MDX in `app` directory.


// This file is required to use MDX in `app` directory.
export function useMDXComponents(components: MDXComponents): MDXComponents {
  return {
    // Allows customizing built-in components, e.g. to add styling.
    // h1: ({ children }) =>
{children}
,
    ...components,
  }
}Update next.config.js to use mdxRs:next.config.js /** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    mdxRs: true,
  },
}

const withMDX = require('@next/mdx')()
module.exports = withMDX(nextConfig)Add a new file with MDX content to your app directory:app/hello.mdx Hello, Next.js!


You can import and use React components in MDX files.Import the MDX file inside a page to display the content:app/page.tsx import HelloWorld from './hello.mdx'

export default function Page() {
  return <HelloWorld />
}
Remote MDX
If your Markdown or MDX files do not live inside your application, you can fetch them dynamically on the server. This is useful for fetching content from a CMS or other data source.
There are two popular community packages for fetching MDX content: next-mdx-remote and contentlayer. For example, the following example uses next-mdx-remote:
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).


app/page.tsx import { MDXRemote } from 'next-mdx-remote/rsc'

export default async function Home() {
  const res = await fetch('https://...')
  const markdown = await res.text()
  return <MDXRemote source={markdown} />
}
Layouts
To share a layout around MDX content, you can use the built-in layouts support with the App Router.
Remark and Rehype Plugins
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.
next.config.mjs import remarkGfm from 'remark-gfm'
import createMDX from '@next/mdx'


import createMDX from '@next/mdx'

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
}

const withMDX = createMDX({
  options: {
    extension: /\.mdx?$/,
    remarkPlugins: [remarkGfm],
    rehypePlugins: [],
    // If you use `MDXProvider`, uncomment the following line.
    // providerImportSource: "@mdx-js/react",
  },
})
export default withMDX(nextConfig)
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 gray-matter.


To access page metadata with @next/mdx, you can export a meta object from within the .mdx file:
 export const meta = {
  author: 'Rich Haines',
}

# My MDX page
Custom Elements
One of the pleasant aspects of using markdown, is that it maps to native HTML elements, making writing fast, and intuitive:
 This is a list in markdown:

- One
- Two
- Three
The above generates the following HTML:

This is a list in markdown:

One

Two

Three


Three

When you want to style your own elements to give a custom feel to your website or application, you can pass in shortcodes. These are your own custom components that map to HTML elements. To do this you use the MDXProvider and pass a components object as a prop. Each object key in the components object maps to a HTML element name.
To enable you need to specify providerImportSource: "@mdx-js/react" in next.config.js.
next.config.js const withMDX = require('@next/mdx')({
  // ...
  options: {
    providerImportSource: '@mdx-js/react',
  },
})
Then setup the provider in your page
pages/index.js import { MDXProvider } from '@mdx-js/react'
import Image from 'next/image'
import { Heading, InlineCode, Pre, Table, Text } from 'my-components'


import { Heading, InlineCode, Pre, Table, Text } from 'my-components'

const ResponsiveImage = (props) => (
  <Image
    alt={props.alt}
    sizes="100vw"
    style={{ width: '100%', height: 'auto' }}
    {...props}
  />
)

const components = {
  img: ResponsiveImage,
  h1: Heading.H1,
  h2: Heading.H2,
  p: Text,
  pre: Pre,
  code: InlineCode,
}

export default function Post(props) {
  return (
    <MDXProvider components={components}>
      <main {...props} />
    </MDXProvider>
  )
}


<main {...props} />
    </MDXProvider>
  )
}
If you use it across the site you may want to add the provider to _app.js so all MDX pages pick up the custom element config.
Deep Dive: How do you transform markdown into HTML?
React does not natively understand Markdown. The markdown plaintext needs to first be transformed into HTML. This can be accomplished with remark and rehype.
remark is an ecosystem of tools around markdown. rehype is the same, but for HTML. For example, the following code snippet transforms markdown into HTML:
 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()

async function main() {


main()

async function main() {
  const file = await unified()
    .use(remarkParse) // Convert into markdown AST
    .use(remarkRehype) // Transform to HTML AST
    .use(rehypeSanitize) // Sanitize HTML input
    .use(rehypeStringify) // Convert AST into serialized HTML
    .process('Hello, Next.js!')

  console.log(String(file)) //
Hello, Next.js!

}
The remark and rehype ecosystem contains plugins for syntax highlighting, linking headings, generating a table of contents, and more.
When using @next/mdx as shown below, you do not need to use remark or rehype directly, as it is handled for you.
Using the Rust-based MDX compiler (Experimental)


Using the Rust-based MDX compiler (Experimental)
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:
next.config.js module.exports = withMDX({
  experimental: {
    mdxRs: true,
  },
})
Helpful Links
MDX
@next/mdx
remark
rehype


src Directory
As an alternative to having the special Next.js app or pages directories in the root of your project, Next.js also supports the common pattern of placing application code under the src directory.
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.
Good to know
The /public directory should remain in the root of your project.
Config files like package.json, next.config.js and tsconfig.json should remain in the root of your project.
.env.* files should remain in the root of your project.
src/app or src/pages will be ignored if app or pages are present in the root directory.
If you're using src, you'll probably also move other application folders such as /components or /lib.


If you're using Tailwind CSS, you'll need to add the /src prefix to the tailwind.config.js file in the content section.


Draft ModeStatic 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 only for this specific case.
Next.js has a feature called Draft Mode which solves this problem. Here are instructions on how to use it.
Step 1: Create and access the Route Handler
First, create a Route Handler. It can have any name - e.g. app/api/draft/route.ts
Then, import draftMode from next/headers and call the enable() method.
app/api/draft/route.ts // route handler enabling draft mode
import { draftMode } from 'next/headers'


import { draftMode } from 'next/headers'

export async function GET(request: Request) {
  draftMode().enable()
  return new Response('Draft mode is enabled')
}
This will set a cookie to enable draft mode. Subsequent requests containing this cookie will trigger Draft Mode changing the behavior for statically generated pages (more on this later).
You can test this manually by visiting /api/draft and looking at your browser’s developer tools. Notice the Set-Cookie response header with a cookie named __prerender_bypass.
Securely accessing it from your Headless CMS
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
Terminal https://<your-site>/api/draft?secret=<token>&slug=<path>
<your-site> should be your deployment domain.
<token> should be replaced with the secret token you generated.


<token> should be replaced with the secret token you generated.
<path> should be the path for the page that you want to view. If you want to view /posts/foo, then you should use &slug=/posts/foo.
Your headless CMS might allow you to include a variable in the draft URL so that <path> can be set dynamically based on the 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.
app/api/draft/route.ts // route handler with secret and slug
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'

export async function GET(request: Request) {
  // Parse query string parameters


export async function GET(request: Request) {
  // Parse query string parameters
  const { searchParams } = new URL(request.url)
  const secret = searchParams.get('secret')
  const slug = searchParams.get('slug')

  // Check the secret and next parameters
  // This secret should only be known to this route handler and the CMS
  if (secret !== 'MY_SECRET_TOKEN' || !slug) {
    return new Response('Invalid token', { status: 401 })
  }

  // Fetch the headless CMS to check if the provided `slug` exists
  // getPostBySlug would implement the required fetching logic to the headless CMS
  const post = await getPostBySlug(slug)

  // If the slug doesn't exist prevent draft mode from being enabled
  if (!post) {


if (!post) {
    return new Response('Invalid slug', { status: 401 })
  }

  // Enable Draft Mode by setting the cookie
  draftMode().enable()

  // Redirect to the path from the fetched post
  // We don't redirect to searchParams.slug as that might lead to open redirect vulnerabilities
  redirect(post.slug)
}
If it succeeds, then the browser will be redirected to the path you want to view with the draft mode cookie.
Step 2: Update page
The next step is to update your page to check the value of draftMode().isEnabled.
If you request a page which has the cookie set, then data will be fetched at request time (instead of at build time).
Furthermore, the value of isEnabled will be true.
app/page.tsx // page that fetches data
import { draftMode } from 'next/headers'


import { draftMode } from 'next/headers'

async function getData() {
  const { isEnabled } = draftMode()

  const url = isEnabled
    ? 'https://draft.example.com'
    : 'https://production.example.com'

  const res = await fetch(url)

  return res.json()
}

export default async function Page() {
  const { title, desc } = await getData()

  return (

{title}

{desc}

  )
}
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.
Terminal https://<your-site>/api/draft?secret=<token>&slug=<path>
More Details
Clear the Draft Mode cookie
By default, the Draft Mode session ends when the browser is closed.
To clear the Draft Mode cookie manually, create a Route Handler that calls draftMode().disable():
app/api/disable-draft/route.ts import { draftMode } from 'next/headers'

export async function GET(request: Request) {
  draftMode().disable()
  return new Response('Draft mode is disabled')
}
Then, send a request to /api/disable-draft to invoke the Route Handler. If calling this route using next/link, you must pass prefetch={false} to prevent accidentally deleting the cookie on prefetch.
Unique per next build


Unique per next build
A new bypass cookie value will be generated each time you run next build.
This ensures that the bypass cookie can’t be guessed.
Good to know: To test Draft Mode locally over HTTP, your browser will need to allow third-party cookies and local storage access.


Static Exports
Next.js enables starting as a static site or Single-Page Application (SPA), then later optionally upgrading to use features that require a server.
When running next build, Next.js generates an HTML file per route. By breaking a strict SPA into individual HTML files, Next.js can avoid loading unnecessary JavaScript code on the client-side, reducing the bundle size and enabling faster page loads.
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.
Configuration
To enable a static export, change the output mode inside next.config.js:
next.config.js /**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  output: 'export',
  // Optional: Add a trailing slash to all paths `/about` -> `/about/`
  // trailingSlash: true,


// trailingSlash: true,
  // Optional: Change the output directory `out` -> `dist`
  // distDir: 'dist',
}

module.exports = nextConfig
After running next build, Next.js will produce an out folder which contains the HTML/CSS/JS assets for your application.
Supported Features
The core of Next.js has been designed to support static exports.Server Components
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.app/page.tsx export default async function Page() {
  // This fetch will run on the server during `next build`


// This fetch will run on the server during `next build`
  const res = await fetch('https://api.example.com/...')
  const data = await res.json()

  return <main>...</main>
}Client Components
If you want to perform data fetching on the client, you can use a Client Component with SWR to deduplicate requests.app/other/page.tsx 'use client'

import useSWR from 'swr'

const fetcher = (url: string) => fetch(url).then((r) => r.json())

export default function Page() {
  const { data, error } = useSWR(
    `https://jsonplaceholder.typicode.com/posts/1`,
    fetcher
  )
  if (error) return 'Failed to load'
  if (!data) return 'Loading...'

  return data.title


if (!data) return 'Loading...'

  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:app/page.tsx import Link from 'next/link'

export default function Page() {
  return (
    <>

Index Page

          <Link href="/post/1">Post 1</Link>

          <Link href="/post/2">Post 2</Link>

    </>
  )
}
Image Optimization


</ul>
    </>
  )
}
Image Optimization
Image Optimization 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:
next.config.js /** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  images: {
    loader: 'custom',
    loaderFile: './app/image.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:
app/image.ts export default function cloudinaryLoader({
  src,
  width,
  quality,
}: {
  src: string
  width: number
  quality?: number
}) {


src: string
  width: number
  quality?: number
}) {
  const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
  return `https://res.cloudinary.com/demo/image/upload/${params.join(
    ','
  )}${src}`
}
You can then use next/image in your application, defining relative paths to the image in Cloudinary:
app/page.tsx import Image from 'next/image'

export default function Page() {
  return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />
}
Route Handlers


}
Route Handlers
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 dynamic or static data. For example:app/data.json/route.ts import { NextResponse } from 'next/server'

export async function GET() {
  return NextResponse.json({ name: 'Lee' })
}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
Client Components are pre-rendered to HTML during next build. Because Web APIs like window, localStorage, and navigator are not available on the server, you need to safely access these APIs only when running in the browser. For example: 'use client';


import { useEffect } from 'react';

export default function ClientComponent() {
  useEffect(() => {
    // You now have access to `window`
    console.log(window.innerHeight);
  }, [])

  return ...;
}
Unsupported Features
After enabling the static export output mode, all routes inside app are opted-into the following Route Segment Config: export const dynamic = 'error'With this configuration, your application will produce an error if you try to use server functions like headers or cookies, since there is no runtime server. This ensures local development matches the same behavior as a static export. If you need to use server functions, you cannot use a static export.The following additional dynamic features are not supported with a static export:
rewrites in next.config.js
redirects in next.config.js
headers in next.config.js
Middleware
Incremental Static Regeneration
Deploying


headers in next.config.js
Middleware
Incremental Static Regeneration
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. Using next export is no longer needed. 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.conf server {
  listen 80;
  server_name acme.com;

  root /var/www;

  location / {
      try_files /out/index.html =404;


location / {
      try_files /out/index.html =404;
  }

  location /blog/ {
      rewrite ^/blog/(.*)$ /out/blog/$1.html break;
  }

  error_page 404 /out/404.html;
  location = /404.html {
      internal;
  }
}
Version History
VersionChangesv13.4.0App Router (Stable) adds enhanced static export support, including using React Server Components and Route Handlers.v13.3.0next export is deprecated and replaced with "output": "export"


CodemodsCodemods are transformations that run on your codebase programmatically. This allows a large number of changes to be programmatically applied without having to manually go through every file.
Next.js provides Codemod transformations to help upgrade your Next.js codebase when an API is updated or deprecated.
Usage
In your terminal, navigate (cd) into your project's folder, then run:
Terminal npx @next/codemod <transform> <path>
Replacing <transform> and <path> with appropriate values.
transform - name of transform
path - files or directory to transform
--dry Do a dry-run, no code will be edited
--print Prints the changed output for comparison
Next.js Codemods
13.2
Use Built-in Font
built-in-next-font
Terminal npx @next/codemod@latest built-in-next-font .


Terminal npx @next/codemod@latest built-in-next-font .
This codemod uninstalls the @next/font package and transforms @next/font imports into the built-in next/font.
For example:
 import { Inter } from '@next/font/google'
Transforms into:
 import { Inter } from 'next/font/google'
13.0
Rename Next Image Imports
next-image-to-legacy-image
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:
pages/index.js import Image1 from 'next/image'
import Image2 from 'next/future/image'

export default function Home() {
  return (
    <div>


export default function Home() {
  return (

      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />

  )
}
Transforms into:
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'

export default function Home() {
  return (

      <Image1 src="/test.jpg" width="200" height="300" />
      <Image2 src="/test.png" width="500" height="400" />

  )
}
Migrate to the New Image Component
next-image-experimental


)
}
Migrate to the New Image Component
next-image-experimental
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.
Removes layout prop and adds style.
Removes objectFit prop and adds style.
Removes objectPosition prop and adds style.
Removes lazyBoundary prop.
Removes lazyRoot prop.
Remove  Tags From Link Components
new-link
Terminal npx @next/codemod@latest new-link .
Remove  tags inside Link Components, or add a legacyBehavior prop to Links that cannot be auto-fixed.
For example:
 <Link href="/about">
  About
</Link>
// transforms into
<Link href="/about">
  About
</Link>

<Link href="/about">


About
</Link>

<Link href="/about">
   console.log('clicked')}>About
</Link>
// transforms into
<Link href="/about" onClick={() => console.log('clicked')}>
  About
</Link>
In cases where auto-fixing can't be applied, the legacyBehavior prop is added. This allows your app to keep functioning using the old behavior for that particular link.
 const Component = () => About

<Link href="/about">
  <Component />
</Link>
// becomes
<Link href="/about" legacyBehavior>
  <Component />
</Link>
11
Migrate from CRA
cra-to-next
Terminal npx @next/codemod cra-to-next


cra-to-next
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.
10
Add React imports
add-missing-react-import
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 to work.
For example:
my-component.js export default class Home extends React.Component {
  render() {
    return
Hello World

  }
}
Transforms into:
my-component.js import React from 'react'
export default class Home extends React.Component {


my-component.js import React from 'react'
export default class Home extends React.Component {
  render() {
    return
Hello World

  }
}
9
Transform Anonymous Components into Named Components
name-default-component
Terminal npx @next/codemod name-default-component
Versions 9 and above.
Transforms anonymous components into named components to make sure they work with Fast Refresh.
For example:
my-component.js export default function () {
  return
Hello World

}
Transforms into:
my-component.js export default function MyComponent() {
  return
Hello World

}
The component will have a camel-cased name based on the name of the file, and it also works with arrow functions.
8
Transform AMP HOC into page config
withamp-to-config
Terminal npx @next/codemod withamp-to-config


withamp-to-config
Terminal npx @next/codemod withamp-to-config
Transforms the withAmp HOC into Next.js 9 page configuration.
For example:
 // Before
import { withAmp } from 'next/amp'

function Home() {
  return
My AMP Page

}

export default withAmp(Home)
 // After
export default function Home() {
  return
My AMP Page

}

export const config = {
  amp: true,
}
6
Use withRouter
url-to-withrouter
Terminal npx @next/codemod url-to-withrouter
Transforms the deprecated automatically injected url property on top level pages to using withRouter and the router property it injects. Read more here: https://nextjs.org/docs/messages/url-deprecated
For example:


For example:
From import React from 'react'
export default class extends React.Component {
  render() {
    const { pathname } = this.props.url
    return
Current pathname: {pathname}

  }
}
To import React from 'react'
import { withRouter } from 'next/router'
export default withRouter(
  class extends React.Component {
    render() {
      const { pathname } = this.props.router
      return
Current pathname: {pathname}

    }
  }
)
This is one case. All the cases that are transformed (and tested) can be found in the __testfixtures__ directory.


App Router Incremental Adoption GuideThis guide will help you:
Update your Next.js application from version 12 to version 13
Upgrade features that work in both the pages and the app directories
Incrementally migrate your existing application from pages to app
Upgrading
Node.js Version
The minimum Node.js version is now v16.8. See the Node.js documentation for more information.
Next.js Version
To update to Next.js version 13, run the following command using your preferred package manager:
Terminal npm install next@latest react@latest react-dom@latest
ESLint Version
If you're using ESLint, you need to upgrade your ESLint version:
Terminal npm install -D eslint-config-next@latest


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:
Upgrade new features: A guide to help you upgrade to new features such as the improved Image and Link Components.
Migrate from the pages to app directory: A step-by-step guide to help you incrementally migrate from the pages to the app directory.
Upgrading New Features
Next.js 13 introduced the new App Router with new features and conventions. The new Router is available in the app directory and co-exists with the pages directory.


Upgrading to Next.js 13 does not require using the new App Router. You can continue using pages with new features that work in both directories, such as the updated Image component, Link component, Script component, and Font optimization.
<Image/> Component
Next.js 12 introduced new improvements to the Image Component with a temporary import: next/future/image. These improvements included less client-side JavaScript, easier ways to extend and style images, better accessibility, and native browser lazy loading.
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: Safely and automatically renames next/image imports to next/legacy/image. Existing components will maintain the same behavior.


next-image-experimental codemod: 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
The <Link> Component no longer requires manually adding an  tag as a child. This behavior was added as an experimental option in version 12.2 and is now the default. In Next.js 13, <Link> always renders  and allows you to forward props to the underlying tag.
For example:
 import Link from 'next/link'

// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
  About
</Link>

// Next.js 13: `<Link>` always renders `<a>` under the hood


// Next.js 13: `<Link>` always renders `<a>` under the hood
<Link href="/about">
  About
</Link>
To upgrade your links to Next.js 13, you can use the new-link codemod.
<Script> Component
The behavior of next/script has been updated to support both pages and app, but some changes need to be made to ensure a smooth migration:
Move any beforeInteractive scripts you previously included in _document.js to the root layout file (app/layout.tsx).
The experimental worker strategy does not yet work in app and scripts denoted with this strategy will either have to be removed or modified to use a different strategy (e.g. lazyOnload).
onLoad, onReady, and onError handlers will not work in Server Components so make sure to move them to a Client Component or remove them altogether.
Font Optimization


Font Optimization
Previously, Next.js helped you optimize fonts by inlining font CSS. Version 13 introduces the new next/font module which gives you the ability to customize your font loading experience while still ensuring great performance and privacy. next/font is supported in both the pages and app directories.
While inlining CSS still works in pages, it does not work in app. You should use next/font instead.
See the Font Optimization page to learn how to use next/font.
Migrating from pages to app
🎥 Watch: Learn how to incrementally adopt the App Router → YouTube (16 minutes).
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 and layouts, migration means new concepts, mental models, and behavioral changes to learn.


We recommend reducing the combined complexity of these updates by breaking down your migration into smaller steps. The app directory is intentionally designed to work simultaneously with the pages directory to allow for incremental page-by-page migration.
The app directory supports nested routes and layouts. Learn more.
Use nested folders to define routes and a special page.js file to make a route segment publicly accessible. Learn more.
Special 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.


Data fetching functions like getServerSideProps and getStaticProps have been replaced with a new API inside app. getStaticPaths has been replaced with generateStaticParams.
pages/_app.js and pages/_document.js have been replaced with a single app/layout.js root layout. Learn more.
pages/_error.js has been replaced with more granular error.js special files. Learn more.
pages/404.js has been replaced with the not-found.js file.
pages/api/* currently remain inside the pages directory.
Step 1: Creating the app directory
Update to the latest Next.js version (requires 13.4 or greater):
 npm install next@latest
Then, create a new app directory at the root of your project (or src/ directory).
Step 2: Creating a Root Layout
Create a new app/layout.tsx file inside the app directory. This is a root layout that will apply to all routes inside app.


app/layout.tsx export default function RootLayout({
  // Layouts must accept a children prop.
  // This will be populated with nested layouts or pages
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
The app directory must include a root layout.
The root layout must define <html>, and <body> tags since Next.js does not automatically create them
The root layout replaces the pages/_app.tsx and pages/_document.tsx files.
.js, .jsx, or .tsx extensions can be used for layout files.
To manage <head> HTML elements, you can use the built-in SEO support:
app/layout.tsx import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Home',


export const metadata: Metadata = {
  title: 'Home',
  description: 'Welcome to Next.js',
}
Migrating _document.js and _app.js
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.
Migrating the getLayout() pattern to Layouts (Optional)
Next.js recommended adding a property to Page components to achieve per-page layouts in the pages directory. This pattern can be replaced with native support for nested layouts in the app directory.


See before and after exampleBeforecomponents/DashboardLayout.js export default function DashboardLayout({ children }) {
  return (

My Dashboard

      {children}

  )
}pages/dashboard/index.js import DashboardLayout from '../components/DashboardLayout'

export default function Page() {
  return
My Page

}

Page.getLayout = function getLayout(page) {
  return <DashboardLayout>{page}</DashboardLayout>
}After
Remove the Page.getLayout property from pages/dashboard/index.js and follow the steps for migrating pages to the app directory.
app/dashboard/page.js export default function Page() {
  return
My Page

}
Move the contents of DashboardLayout into a new Client Component to retain pages directory behavior.


}
Move the contents of DashboardLayout into a new Client Component to retain pages directory behavior.
app/dashboard/DashboardLayout.js 'use client' // this directive should be at top of the file, before any imports.

// This is a Client Component
export default function DashboardLayout({ children }) {
  return (

My Dashboard

      {children}

  )
}
Import the DashboardLayout into a new layout.js file inside the app directory.
app/dashboard/layout.js import DashboardLayout from './DashboardLayout'

// This is a Server Component
export default function Layout({ children }) {
  return <DashboardLayout>{children}</DashboardLayout>
}
You can incrementally move non-interactive parts of DashboardLayout.js (Client Component) into layout.js (Server Component) to reduce the amount of component JavaScript you send to the client.


Step 3: Migrating next/head
In the pages directory, the next/head React component is used to manage <head> HTML elements such as title and meta . In the app directory, next/head is replaced with the new built-in SEO support.
Before:
pages/index.tsx import Head from 'next/head'

export default function Page() {
  return (
    <>
      <Head>
        <title>My page title</title>
      </Head>
    </>
  )
}
After:
app/page.tsx import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'My Page Title',
}

export default function Page() {
  return '...'
}
See all metadata options.
Step 4: Migrating Pages


}
See all metadata options.
Step 4: Migrating Pages
Pages in the app directory are Server Components by default. This is different from the pages directory where pages are Client Components.
Data fetching has changed in app. getServerSideProps, getStaticProps and getInitialProps have been replaced for a simpler API.
The app directory uses nested folders to define routes and a special page.js file to make a route segment publicly accessible.
pages Directoryapp DirectoryRouteindex.jspage.js/about.jsabout/page.js/aboutblog/[slug].jsblog/[slug]/page.js/blog/post-1
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.
Step 1: Create a new Client Component
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.
app/home-page.tsx 'use client'

// This is a Client Component. It receives data as props and
// has access to state and effects just like Page components
// in the `pages` directory.
export default function HomePage({ recentPosts }) {
  return (

      {recentPosts.map((post) => (

{post.title}

      ))}


{post.title}

      ))}

  )
}
Step 2: Create a new page
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. See the data fetching upgrade guide for more details.
app/page.tsx // Import your Client Component
import HomePage from './home-page'

async function getPosts() {
  const res = await fetch('https://...')
  const posts = await res.json()
  return posts
}

export default async function Page() {
  // Fetch data directly in a Server Component
  const recentPosts = await getPosts()


// Fetch data directly in a Server Component
  const recentPosts = await getPosts()
  // Forward fetched data to your Client Component
  return <HomePage recentPosts={recentPosts} />
}
If your previous page used useRouter, you'll need to update to the new routing hooks. Learn more.
Start your development server and visit http://localhost:3000. You should see your existing index route, now served through the app directory.
Step 5: Migrating Routing Hooks
A new router has been added to support the new behavior in the app directory.
In app, you should use the three new hooks imported from next/navigation: useRouter(), usePathname(), and useSearchParams().
The new useRouter hook is imported from next/navigation and has different behavior to the useRouter hook in pages which is imported from next/router.


The useRouter hook imported from next/router is not supported in the app directory but can continue to be used in the pages directory.
The new useRouter does not return the pathname string. Use the separate usePathname hook instead.
The new useRouter does not return the query object. Use the separate useSearchParams hook instead.
You can use useSearchParams and usePathname together to listen to page changes. See the Router Events section for more details.
These new hooks are only supported in Client Components. They cannot be used in Server Components.
app/example-client-component.tsx 'use client'

import { useRouter, usePathname, useSearchParams } from 'next/navigation'

export default function ExampleClientComponent() {
  const router = useRouter()
  const pathname = usePathname()
  const searchParams = useSearchParams()

  // ...
}
In addition, the new useRouter hook has the following changes:


// ...
}
In addition, the new useRouter hook has the following changes:
isFallback has been removed because fallback has been replaced.
The locale, locales, defaultLocales, domainLocales values have been removed because built-in i18n Next.js features are no longer necessary in the app directory. Learn more about i18n.
basePath has been removed. The alternative will not be part of useRouter. It has not yet been implemented.
asPath has been removed because the concept of as has been removed from the new router.
isReady has been removed because it is no longer necessary. During static rendering, any component that uses the useSearchParams() hook will skip the prerendering step and instead be rendered on the client at runtime.
View the useRouter() API reference.
Step 6: Migrating Data Fetching Methods


View the useRouter() API reference.
Step 6: Migrating Data Fetching Methods
The pages directory uses getServerSideProps and getStaticProps to fetch data for pages. Inside the app directory, these previous data fetching functions are replaced with a simpler API built on top of fetch() and async React Server Components.
app/page.tsx export default async function Page() {
  // This request should be cached until manually invalidated.
  // Similar to `getStaticProps`.
  // `force-cache` is the default and can be omitted.
  const staticData = await fetch(`https://...`, { cache: 'force-cache' })

  // This request should be refetched on every request.
  // Similar to `getServerSideProps`.
  const dynamicData = await fetch(`https://...`, { cache: 'no-store' })


// This request should be cached with a lifetime of 10 seconds.
  // Similar to `getStaticProps` with the `revalidate` option.
  const revalidatedData = await fetch(`https://...`, {
    next: { revalidate: 10 },
  })

  return <div>...</div>
}
Server-side Rendering (getServerSideProps)
In the pages directory, getServerSideProps is used to fetch data on the server and forward props to the default exported React component in the file. The initial HTML for the page is prerendered from the server, followed by "hydrating" the page in the browser (making it interactive).
pages/dashboard.js // `pages` directory

export async function getServerSideProps() {
  const res = await fetch(`https://...`)
  const projects = await res.json()


const projects = await res.json()

  return { props: { projects } }
}

export default function Dashboard({ projects }) {
  return (

      {projects.map((project) => (

{project.name}

      ))}

  )
}
In the app directory, we can colocate our data fetching inside our React components using 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. This is similar to getServerSideProps in the pages directory.
app/dashboard/page.tsx // `app` directory

// This function can be named anything
async function getProjects() {


// This function can be named anything
async function getProjects() {
  const res = await fetch(`https://...`, { cache: 'no-store' })
  const projects = await res.json()

  return projects
}

export default async function Dashboard() {
  const projects = await getProjects()

  return (

      {projects.map((project) => (

{project.name}

      ))}

  )
}
Accessing Request Object
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.
pages/index.js // `pages` directory

export async function getServerSideProps({ req, query }) {


export async function getServerSideProps({ req, query }) {
  const authHeader = req.getHeaders()['authorization'];
  const theme = req.cookies['theme'];

  return { props: { ... }}
}

export default function Page(props) {
  return ...
}
The app directory exposes new read-only functions to retrieve request data:
headers(): Based on the Web Headers API, and can be used inside Server Components to retrieve request headers.
cookies(): Based on the Web Cookies API, and can be used inside Server Components to retrieve cookies.
app/page.tsx // `app` directory
import { cookies, headers } from 'next/headers'

async function getData() {
  const authHeader = headers().get('authorization')

  return '...'
}

export default async function Page() {


return '...'
}

export default async function Page() {
  // You can use `cookies()` or `headers()` inside Server Components
  // directly or in your data fetching function
  const theme = cookies().get('theme')
  const data = await getData()
  return '...'
}
Static Site Generation (getStaticProps)
In the pages directory, the getStaticProps function is used to pre-render a page at build time. This function can be used to fetch data from an external API or directly from a database, and pass this data down to the entire page as it's being generated during the build.
pages/index.js // `pages` directory

export async function getStaticProps() {
  const res = await fetch(`https://...`)
  const projects = await res.json()

  return { props: { projects } }
}


return { props: { projects } }
}

export default function Index({ projects }) {
  return projects.map((project) =>
{project.name}
)
}
In the app directory, data fetching with fetch() will default to cache: 'force-cache', which will cache the request data until manually invalidated. This is similar to getStaticProps in the pages directory.
app/page.js // `app` directory

// This function can be named anything
async function getProjects() {
  const res = await fetch(`https://...`)
  const projects = await res.json()

  return projects
}

export default async function Index() {
  const projects = await getProjects()

  return projects.map((project) =>
{project.name}
)
}
Dynamic paths (getStaticPaths)


}
Dynamic paths (getStaticPaths)
In the pages directory, the getStaticPaths function is used to define the dynamic paths that should be pre-rendered at build time.
pages/posts/[id].js // `pages` directory
import PostLayout from '@/components/post-layout'

export async function getStaticPaths() {
  return {
    paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
  }
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  return { props: { post } }
}

export default function Post({ post }) {
  return <PostLayout post={post} />
}


return <PostLayout post={post} />
}
In the app directory, getStaticPaths is replaced with generateStaticParams.
generateStaticParams behaves similarly to getStaticPaths, but has a simplified API for returning route parameters and can be used inside 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.
app/posts/[id]/page.js // `app` directory
import PostLayout from '@/components/post-layout'

export async function generateStaticParams() {
  return [{ id: '1' }, { id: '2' }]
}

async function getPost(params) {
  const res = await fetch(`https://.../posts/${params.id}`)
  const post = await res.json()

  return post
}

export default async function Post({ params }) {


return post
}

export default async function Post({ params }) {
  const post = await getPost(params)

  return <PostLayout post={post} />
}
Using the name generateStaticParams is more appropriate than getStaticPaths for the new model in the app directory. The get prefix is replaced with a more descriptive generate, which sits better alone now that getStaticProps and getServerSideProps are no longer necessary. The Paths suffix is replaced by Params, which is more appropriate for nested routing with multiple dynamic segments.
Replacing fallback
In the pages directory, the fallback property returned from getStaticPaths is used to define the behavior of a page that isn't pre-rendered at build time. This property can be set to true to show a fallback page while the page is being generated, false to show a 404 page, or blocking to generate the page at request time.


pages/posts/[id].js // `pages` directory

export async function getStaticPaths() {
  return {
    paths: [],
    fallback: 'blocking'
  };
}

export async function getStaticProps({ params }) {
  ...
}

export default function Post({ post }) {
  return ...
}
In the app directory the config.dynamicParams property controls how params outside of generateStaticParams are handled:
true: (default) Dynamic segments not included in generateStaticParams are generated on demand.
false: Dynamic segments not included in generateStaticParams will return a 404.
This replaces the fallback: true | false | 'blocking' option of getStaticPaths in the pages directory. The fallback: 'blocking' option is not included in dynamicParams because the difference between 'blocking' and true is negligible with streaming.
app/posts/[id]/page.js // `app` directory


app/posts/[id]/page.js // `app` directory

export const dynamicParams = true;

export async function generateStaticParams() {
  return [...]
}

async function getPost(params) {
  ...
}

export default async function Post({ params }) {
  const post = await getPost(params);

  return ...
}
With dynamicParams set to true (the default), when a route segment is requested that hasn't been generated, it will be server-rendered and cached as static data on success.
Incremental Static Regeneration (getStaticProps with revalidate)
In the pages directory, the getStaticProps function allows you to add a revalidate field to automatically regenerate a page after a certain amount of time. This is called Incremental Static Regeneration (ISR) and helps you update static content without redeploying.
pages/index.js // `pages` directory


pages/index.js // `pages` directory

export async function getStaticProps() {
  const res = await fetch(`https://.../posts`)
  const posts = await res.json()

  return {
    props: { posts },
    revalidate: 60,
  }
}

export default function Index({ posts }) {
  return (
    <Layout>
      <PostList posts={posts} />
    </Layout>
  )
}
In the app directory, data fetching with fetch() can use revalidate, which will cache the request for the specified amount of seconds.
app/page.js // `app` directory

async function getPosts() {
  const res = await fetch(`https://.../posts`, { next: { revalidate: 60 } })
  const data = await res.json()

  return data.posts
}


const data = await res.json()

  return data.posts
}

export default async function PostList() {
  const posts = await getPosts()

  return posts.map((post) => <div>{post.name}</div>)
}
API Routes
API Routes continue to work in the pages/api directory without any changes. However, they have been replaced by Route Handlers in the app directory.
Route Handlers allow you to create custom request handlers for a given route using the Web Request and Response APIs.
app/api/route.ts export async function GET(request: Request) {}
Good to know: If you previously used API routes to call an external API from the client, you can now use Server Components instead to securely fetch data. Learn more about data fetching.
Step 7: Styling


Step 7: Styling
In the pages directory, global stylesheets are restricted to only pages/_app.js. With the app directory, this restriction has been lifted. Global styles can be added to any layout, page, or component.
CSS Modules
Tailwind CSS
Global Styles
CSS-in-JS
External Stylesheets
Sass
Tailwind CSS
If you're using Tailwind CSS, you'll need to add the app directory to your tailwind.config.js file:
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:


}
You'll also need to import your global styles in your app/layout.js file:
app/layout.js import '../styles/globals.css'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
Learn more about styling with Tailwind CSS
Codemods
Next.js provides Codemod transformations to help upgrade your codebase when a feature is deprecated. See Codemods for more information.


create-next-app
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.
Interactive
You can create a new project interactively by running:
Terminal npx create-next-app@latest
Terminal yarn create next-app
Terminal pnpm create next-app
You will then be asked the following prompts:
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 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).
See create-next-app --help:
Terminal Usage: create-next-app <project-directory> [options]

Options:
  -V, --version                        output the version number
  --ts, --typescript

    Initialize as a TypeScript project. (default)

  --js, --javascript

    Initialize as a JavaScript project.

  --tailwind

    Initialize with Tailwind CSS config. (default)


--tailwind

    Initialize with Tailwind CSS config. (default)

  --eslint

    Initialize with ESLint config.

  --app

    Initialize as an App Router project.

  --src-dir

    Initialize inside a `src/` directory.

  --import-alias <alias-to-configure>

    Specify import alias to use (default "@/*").

  --use-npm

    Explicitly tell the CLI to bootstrap the app using npm

  --use-pnpm

    Explicitly tell the CLI to bootstrap the app using pnpm

  --use-yarn

    Explicitly tell the CLI to bootstrap the app using Yarn

  -e, --example [name]|[github-url]


-e, --example [name]|[github-url]

    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

    Explicitly tell the CLI to reset any stored preferences

  -h, --help                           output usage information
Why use Create Next App?


-h, --help                           output usage information
Why use Create Next App?
create-next-app allows you to create a new Next.js app within seconds. It is officially maintained by the creators of Next.js, and includes a number of benefits:
Interactive Experience: Running npx create-next-app@latest (with no arguments) launches an interactive experience that guides you through setting up a project.
Zero Dependencies: Initializing a project is as quick as one second. Create Next App has zero dependencies.
Offline Support: Create Next App will automatically detect if you're offline and bootstrap your project using your local package cache.
Support for Examples: Create Next App can bootstrap your application using an example from the Next.js examples collection (e.g. npx create-next-app --example api-routes) or any public GitHub repository.


Tested: The package is part of the Next.js monorepo and tested using the same integration test suite as Next.js itself, ensuring it works as expected with every release.


Edge Runtime
The Next.js Edge Runtime is based on standard Web APIs, it supports the following APIs:
Network APIs
APIDescriptionBlobRepresents a blobfetchFetches a resourceFetchEventRepresents a fetch eventFileRepresents a fileFormDataRepresents form dataHeadersRepresents HTTP headersRequestRepresents an HTTP requestResponseRepresents an HTTP responseURLSearchParamsRepresents URL search parametersWebSocketRepresents a websocket connection
Encoding APIs
APIDescriptionatobDecodes a base-64 encoded stringbtoaEncodes a string in base-64TextDecoderDecodes a Uint8Array into a stringTextDecoderStreamChainable decoder for streamsTextEncoderEncodes a string into a Uint8ArrayTextEncoderStreamChainable encoder for streams
Stream APIs


Stream APIs
APIDescriptionReadableStreamRepresents a readable streamReadableStreamBYOBReaderRepresents a reader of a ReadableStreamReadableStreamDefaultReaderRepresents a reader of a ReadableStreamTransformStreamRepresents a transform streamWritableStreamRepresents a writable streamWritableStreamDefaultWriterRepresents a writer of a WritableStream
Crypto APIs
APIDescriptioncryptoProvides access to the cryptographic functionality of the platformCryptoKeyRepresents a cryptographic keySubtleCryptoProvides access to common cryptographic primitives, like hashing, signing, encryption or decryption
Web Standard APIs


APIDescriptionAbortControllerAllows you to abort one or more DOM requests as and when desiredArrayRepresents an array of valuesArrayBufferRepresents a generic, fixed-length raw binary data bufferAtomicsProvides atomic operations as static methodsBigIntRepresents a whole number with arbitrary precisionBigInt64ArrayRepresents a typed array of 64-bit signed integersBigUint64ArrayRepresents a typed array of 64-bit unsigned integersBooleanRepresents a logical entity and can have two values: true and falseclearIntervalCancels a timed, repeating action which was previously established by a call to setInterval()clearTimeoutCancels a timed, repeating action which was previously established by a call to setTimeout()consoleProvides access to the browser's debugging consoleDataViewRepresents a generic view of an ArrayBufferDateRepresents a single moment in time in a platform-independent formatdecodeURIDecodes a Uniform Resource Identifier (URI) previously created by encodeURI or by a similar routinedecodeURIComponentDecodes


Identifier (URI) previously created by encodeURI or by a similar routinedecodeURIComponentDecodes a Uniform Resource Identifier (URI) component previously created by encodeURIComponent or by a similar routineDOMExceptionRepresents an error that occurs in the DOMencodeURIEncodes 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 characterencodeURIComponentEncodes 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 characterErrorRepresents an error when trying to execute a statement or accessing a propertyEvalErrorRepresents an error that occurs regarding the global function eval()Float32ArrayRepresents a typed array of 32-bit floating point numbersFloat64ArrayRepresents a typed array of 64-bit floating point numbersFunctionRepresents a functionInfinityRepresents the mathematical Infinity


typed array of 64-bit floating point numbersFunctionRepresents a functionInfinityRepresents the mathematical Infinity valueInt8ArrayRepresents a typed array of 8-bit signed integersInt16ArrayRepresents a typed array of 16-bit signed integersInt32ArrayRepresents a typed array of 32-bit signed integersIntlProvides access to internationalization and localization functionalityisFiniteDetermines whether a value is a finite numberisNaNDetermines whether a value is NaN or notJSONProvides functionality to convert JavaScript values to and from the JSON formatMapRepresents a collection of values, where each value may occur only onceMathProvides access to mathematical functions and constantsNumberRepresents a numeric valueObjectRepresents the object that is the base of all JavaScript objectsparseFloatParses a string argument and returns a floating point numberparseIntParses a string argument and returns an integer of the specified radixPromiseRepresents the eventual completion (or failure) of an asynchronous operation, and its resulting valueProxyRepresents


the eventual completion (or failure) of an asynchronous operation, and its resulting valueProxyRepresents an object that is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc)queueMicrotaskQueues a microtask to be executedRangeErrorRepresents an error when a value is not in the set or range of allowed valuesReferenceErrorRepresents an error when a non-existent variable is referencedReflectProvides methods for interceptable JavaScript operationsRegExpRepresents a regular expression, allowing you to match combinations of charactersSetRepresents a collection of values, where each value may occur only oncesetIntervalRepeatedly calls a function, with a fixed time delay between each callsetTimeoutCalls a function or evaluates an expression after a specified number of millisecondsSharedArrayBufferRepresents a generic, fixed-length raw binary data bufferStringRepresents a sequence of charactersstructuredCloneCreates a deep copy of a valueSymbolRepresents a unique and immutable data type that is used


a deep copy of a valueSymbolRepresents a unique and immutable data type that is used as the key of an object propertySyntaxErrorRepresents an error when trying to interpret syntactically invalid codeTypeErrorRepresents an error when a value is not of the expected typeUint8ArrayRepresents a typed array of 8-bit unsigned integersUint8ClampedArrayRepresents a typed array of 8-bit unsigned integers clamped to 0-255Uint32ArrayRepresents a typed array of 32-bit unsigned integersURIErrorRepresents an error when a global URI handling function was used in a wrong wayURLRepresents an object providing static methods used for creating object URLsURLPatternRepresents a URL patternURLSearchParamsRepresents a collection of key/value pairsWeakMapRepresents a collection of key/value pairs in which the keys are weakly referencedWeakSetRepresents a collection of objects in which each object may occur only onceWebAssemblyProvides access to WebAssembly


Next.js Specific Polyfills
AsyncLocalStorage
Environment Variables
You can use process.env to access Environment Variables for both next dev and next build.
Unsupported APIs
The Edge Runtime has some restrictions including:
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:
APIDescriptionevalEvaluates JavaScript code represented as a stringnew Function(evalString)Creates a new function with the code provided as an argumentWebAssembly.compileCompiles a WebAssembly module from a buffer sourceWebAssembly.instantiateCompiles 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:
 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, 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.


Next.js CLI
The Next.js CLI allows you to start, build, and export your application.
To get a list of the available CLI commands, run the following command inside your project directory:
Terminal npx next -h
(npx comes with npm 5.2+ and higher)
The output should look like this:
Terminal Usage
  $ next <command>

Available commands
  build, start, export, dev, lint, telemetry, info

Options
  --version, -v   Version number
  --help, -h      Displays this message

For more information run a command with the --help flag
  $ next build --help
You can pass any node arguments to next commands:
Terminal NODE_OPTIONS='--throw-deprecation' next
NODE_OPTIONS='-r esm' next
NODE_OPTIONS='--inspect' next


NODE_OPTIONS='-r esm' next
NODE_OPTIONS='--inspect' next
Good to know: Running next without a command is the same as running next dev
Build
next build creates an optimized production build of your application. The output displays information about each route.
Size – The number of assets downloaded when navigating to the page client-side. The size for each route only includes its dependencies.
First Load JS – The number of assets downloaded when visiting the page from the server. The amount of JS shared by all is shown as a separate metric.
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:
Terminal next build --profile
After that, you can use the profiler in the same way as you would in development.


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:
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:
The application will start at http://localhost:3000 by default. The default port can be changed with -p, like so:
Terminal npx next dev -p 4000
Or using the PORT environment variable:
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:
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 first.
The application will start at http://localhost:3000 by default. The default port can be changed with -p, like so:
Terminal npx next start -p 4000
Or using the PORT environment variable:
Terminal PORT=4000 npx next start
Good to know:
-PORT cannot be set in .env as booting up the HTTP server happens before any other code is initialized.
next start cannot be used with output: 'standalone' or output: 'export'.
Keep Alive Timeout


Keep Alive Timeout
When deploying Next.js behind a downstream proxy (e.g. a load-balancer like AWS ELB/ALB) it's important to configure Next's underlying HTTP server with keep-alive timeouts that are larger than the downstream proxy's timeouts. Otherwise, once a keep-alive timeout is reached for a given TCP connection, Node.js will immediately terminate that connection without notifying the downstream proxy. This results in a proxy error whenever it attempts to reuse a connection that Node.js has already terminated.
To configure the timeout values for the production Next.js server, pass --keepAliveTimeout (in milliseconds) to next start, like so:
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.


your application.
If you have other directories that you would like to lint, you can specify them using the --dir
flag:
Terminal next lint --dir utils
Telemetry
Next.js collects completely anonymous telemetry data about general usage.
Participation in this anonymous program is optional, and you may opt-out if you'd not like to share any information.
To learn more about Telemetry, please read this document.
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).
Running the following in your project's root directory:
Terminal next info
will give you information like this example:
Terminal
    Operating System:
      Platform: linux
      Arch: x64


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

This information should then be pasted into GitHub Issues.


Font Module
This API reference will help you understand how to use next/font/google and next/font/local. For features and usage, please see the Optimizing Fonts page.
Font Function Arguments
For usage, review Google Fonts and Local Fonts.
Keyfont/googlefont/localTypeRequiredsrcString or Array of ObjectsYesweightString or ArrayRequired/OptionalstyleString or Array-subsetsArray of Strings-axesArray of Strings-displayString-preloadBoolean-fallbackArray of Strings-adjustFontFallbackBoolean or String-variableString-declarationsArray of Objects-
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:
src:'./fonts/my-font.woff2' where my-font.woff2 is placed in a directory named fonts inside the app directory


src:[{path: './inter/Inter-Thin.ttf', weight: '100',},{path: './inter/Inter-Regular.ttf',weight: '400',},{path: './inter/Inter-Bold-Italic.ttf', weight: '700',style: 'italic',},]
if the font loader function is called in app/page.tsx using src:'../styles/fonts/my-font.ttf', then my-font.ttf is placed in styles/fonts at the root of the project
weight
The font weight with the following possibilities:
A string with possible values of the weights available for the specific font or a range of values if it's a variable font
An array of weight values if the font is not a variable google font. It applies to next/font/google only.
Used in next/font/google and next/font/local
Required if the font being used is not variable
Examples:


Required if the font being used is not variable
Examples:
weight: '400': A string for a single weight value - for the font 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
The font style with the following possibilities:
A string value with default value of 'normal'
An array of style values if the font is not a variable google font. It applies to next/font/google only.
Used in next/font/google and next/font/local
Optional
Examples:
style: 'italic': A string - it can be normal or italic for next/font/google


style: 'italic': A string - it can be normal or italic for next/font/google
style: 'oblique': A string - it can take any value for next/font/local but is expected to come from standard font styles
style: ['italic','normal']: An array of 2 values for next/font/google - the values are from normal and italic
subsets
The font subsets defined by an array of string values with the names of each subset you would like to be preloaded. Fonts specified via subsets will have a link preload tag injected into the head when the preload option is true, which is the default.
Used in next/font/google
Optional
Examples:
subsets: ['latin']: An array with the subset latin
You can find a list of all subsets on the Google Fonts page for your font.
axes


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. You can find the possible axes values for your font by using the filter on the Google variable fonts page and looking for axes other than wght
display
The font display with possible string values of 'auto', 'block', 'swap', 'fallback' or 'optional' with default value of 'swap'.
Used in next/font/google and next/font/local
Optional
Examples:
display: 'optional': A string assigned to the optional value
preload


Optional
Examples:
display: 'optional': A string assigned to the optional value
preload
A boolean value that specifies whether the font should be preloaded or not. The default is true.
Used in next/font/google and next/font/local
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
Used in next/font/google and next/font/local
Examples:
fallback: ['system-ui', 'arial']: An array setting the fallback fonts to system-ui or arial
adjustFontFallback
For next/font/google: A boolean value that sets whether an automatic fallback font should be used to reduce Cumulative Layout Shift. The default is true.


For next/font/local: A string or boolean false value that sets whether an automatic fallback font should be used to reduce Cumulative Layout Shift. The possible values are 'Arial', 'Times New Roman' or false. The default is 'Arial'.
Used in next/font/google and next/font/local
Optional
Examples:
adjustFontFallback: false: for ``next/font/google`
adjustFontFallback: 'Times New Roman': for next/font/local
variable
A string value to define the CSS variable name to be used if the style is applied with the CSS variable method.
Used in next/font/google and next/font/local
Optional
Examples:
variable: '--my-font': The CSS variable --my-font is declared
declarations
An array of font face descriptor key-value pairs that define the generated @font-face further.
Used in next/font/local
Optional
Examples:
declarations: [{ prop: 'ascent-override', value: '90%' }]


declarations: [{ prop: 'ascent-override', value: '90%' }]
Applying Styles
You can apply the font styles in three ways:
className
style
CSS Variables
className
Returns a read-only CSS className for the loaded font to be passed to an HTML element.

Hello, Next.js!

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.

Hello World

CSS Variables
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:


app/page.tsx import { Inter } from 'next/font/google'
import styles from '../styles/component.module.css'

const inter = Inter({
  variable: '--font-inter',
})
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.
app/page.tsx

Hello World

Define the text selector class in the component.module.css CSS file as follows:
styles/component.module.css .text {
  font-family: var(--font-inter);
  font-weight: 200;
  font-style: italic;
}


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.
Using a font definitions file
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.
Then, specify your font definitions as follows:
styles/fonts.ts import { Inter, Lora, Source_Sans_Pro } from 'next/font/google'
import localFont from 'next/font/local'

// define your variable fonts
const inter = Inter()


// define your variable fonts
const inter = Inter()
const lora = Lora()
// define 2 weights of a non-variable font
const sourceCodePro400 = Source_Sans_Pro({ weight: '400' })
const sourceCodePro700 = Source_Sans_Pro({ weight: '700' })
// define a custom local font where GreatVibes-Regular.ttf is stored in the styles folder
const greatVibes = localFont({ src: './GreatVibes-Regular.ttf' })

export { inter, lora, sourceCodePro400, sourceCodePro700, greatVibes }
You can now use these definitions in your code as follows:
app/page.tsx import { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts'

export default function Page() {
  return (
    <div>


export default function Page() {
  return (

Hello world using Inter font

Hello world using Lora font

        Hello world using Source_Sans_Pro font with weight 700

My title in Great Vibes font

  )
}
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:
tsconfig.json {
  "compilerOptions": {
    "paths": {
      "@/fonts": ["./styles/fonts"]
    }
  }
}
You can now import any font definition as follows:


}
  }
}
You can now import any font definition as follows:
app/about/page.tsx import { greatVibes, sourceCodePro400 } from '@/fonts'
Version Changes
VersionChangesv13.2.0@next/font renamed to next/font. Installation no longer required.v13.0.0@next/font was added.


<Image>
Examples
Image Component
This API reference will help you understand how to use props and configuration options available for the Image Component. For features and usage, please see the Image Component page.
app/page.js import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Picture of the author"
    />
  )
}
Props
Here's a summary of the props available for the Image Component:


}
Props
Here's a summary of the props available for the Image Component:
PropExampleTypeRequiredsrcsrc="/profile.png"StringYeswidthwidth={500}Integer (px)Yesheightheight={500}Integer (px)Yesaltalt="Picture of the author"StringYesloaderloader={imageLoader}Function-fillfill={true}Boolean-sizessizes="(max-width: 768px) 100vw"String-qualityquality={80}Integer (1-100)-prioritypriority={true}Boolean-placeholderplaceholder="blur"String-stylestyle={{objectFit: "contain"}}Object-onLoadingCompleteonLoadingComplete={img => done())}Function-onLoadonLoad={event => done())}Function-onErroronError(event => fail()}Function-loadingloading="lazy"String-blurDataURLblurDataURL="data:image/jpeg..."String-
Required Props
The Image Component requires the following properties: src, width, height, and alt.


The Image Component requires the following properties: src, width, height, and alt.
app/page.js import Image from 'next/image'

export default function Page() {
  return (
    <div>
      <Image
        src="/profile.png"
        width={500}
        height={500}
        alt="Picture of the author"
      />
    </div>
  )
}
src
Must be one of the following:
A statically imported image file
A path string. This can be either an absolute external URL, or an internal path depending on the loader prop.
When using an external URL, you must add it to remotePatterns in next.config.js.
width
The width property represents the rendered width in pixels, so it will affect how large the image appears.
Required, except for statically imported images or images with the fill property.
height


Required, except for statically imported images or images with the fill property.
height
The height property represents the rendered height in pixels, so it will affect how large the image appears.
Required, except for statically imported images or images with the fill property.
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. 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.
If the image is purely decorative or not intended for the user, the alt property should be an empty string (alt="").
Learn more
Optional Props


Learn more
Optional Props
The <Image /> component accepts a number of additional properties beyond those which are required. This section describes the most commonly-used properties of the Image component. Find details about more rarely-used properties in the Advanced Props section.
loader
A custom function used to resolve image URLs.
A loader is a function returning a URL string for the image, given the following parameters:
src
width
quality
Here is an example of using a custom loader:
 'use client'

import Image from 'next/image'

const imageLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

export default function Page() {
  return (
    <Image
      loader={imageLoader}
      src="me.png"
      alt="Picture of the author"
      width={500}


alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}
Good to know: Using props like loader, which accept a function, require using Client Components to serialize the provided function.
Alternatively, you can use the loaderFile configuration in next.config.js to configure every instance of next/image in your application, without passing a prop.
fill
 fill={true} // {true} | {false}
A boolean that causes the image to fill the parent element instead of setting width and height.
The parent element must assign position: "relative", position: "fixed", or position: "absolute" style.
By default, the img element will automatically be assigned the position: "absolute" style.


By default, the img element will automatically be assigned the position: "absolute" style.
The default image fit behavior will stretch the image to fit the container. You may prefer to set object-fit: "contain" for an image which is letterboxed to fit the container and preserve aspect ratio.
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.
For more information, see also:
position
object-fit
object-position
sizes
A string 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 or which are styled to have a responsive size.
The sizes property serves two important purposes related to image performance:


The sizes property serves two important purposes related to image performance:
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 source set. 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 configures how next/image automatically generates an image source set. If no sizes value is present, a small source set is generated, suitable for a fixed-size image. If sizes is defined, a large source set is generated, suitable for a responsive image. If the sizes property includes sizes such as 50vw, which represent a percentage of the viewport width, then the source set 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:
 import Image from 'next/image'

export default function Page() {
  return (
    <div className="grid-element">
      <Image
        fill
        src="/example.png"


<Image
        fill
        src="/example.png"
        sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      />
    </div>
  )
}
This example sizes could have a dramatic effect on performance metrics. Without the 33vw sizes, the image selected from the server would be 3 times as wide as it needs to be. Because file size is proportional to the square of the width, without sizes the user would download an image that's 9 times larger than necessary.
Learn more about srcset and sizes:
web.dev
mdn
quality
 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


priority
 priority={false} // {false} | {true}
When true, the image will be considered high priority and
preload. Lazy loading is automatically disabled for images using priority.
You should use the priority property on any image detected as the Largest Contentful Paint (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
 placeholder = 'empty' // {empty} | {blur}
A placeholder to use while the image is loading. Possible values are blur or empty. Defaults to empty.
When blur, the blurDataURL property will be used as the placeholder. If src is an object from a static import and the imported image is .jpg, .png, .webp, or .avif, then blurDataURL will be automatically populated.


For dynamic images, you must provide the blurDataURL property. Solutions such as Plaiceholder can help with base64 generation.
When empty, there will be no placeholder while the image is loading, only empty space.
Try it out:
Demo the blur placeholder
Demo the shimmer effect with blurDataURL prop
Demo the color effect with blurDataURL prop
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.
components/ProfileImage.js const imageStyle = {
  borderRadius: '50%',
  border: '1px solid #fff',
}

export default function ProfileImage() {
  return <Image src="..." style={imageStyle} />
}


return <Image src="..." style={imageStyle} />
}
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
 'use client'

<Image onLoadingComplete={(img) => console.log(img.naturalWidth)} />
A callback function that is invoked once the image is completely loaded and the placeholder has been removed.
The callback function will be called with one argument, a reference to the underlying <img> element.
Good to know: Using props like onLoadingComplete, which accept a function, require using Client Components to serialize the provided function.
onLoad
 <Image onLoad={(e) => console.log(e.target.naturalWidth)} />
A callback function that is invoked when the image is loaded.


A callback function that is invoked when the image is loaded.
The load event might occur before the image placeholder is removed and the image is fully decoded. If you want to wait until the image has fully loaded, use onLoadingComplete instead.
Good to know: Using props like onLoad, which accept a function, require using Client Components to serialize the provided function.
onError
 <Image onError={(e) => console.error(e.target.id)} />
A callback function that is invoked if the image fails to load.
Good to know: Using props like onError, which accept a function, require using Client Components to serialize the provided function.
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 property instead, which will eagerly preload the image.
 loading = 'lazy' // {lazy} | {eager}