Skip to content

Latest commit

 

History

History
2133 lines (1510 loc) · 83.9 KB

File metadata and controls

2133 lines (1510 loc) · 83.9 KB

API Components

index


title: API Reference description: Next.js API Reference for the App Router.

The Next.js API reference is divided into the following sections:

font


title: Font Module nav_title: Font description: Optimizing loading web fonts with the built-in next/font loaders.

{/* The content of this doc is shared between the app and pages router. You can use the <PagesOnly>Content</PagesOnly> component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

This API reference will help you understand how to use next/font/google 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.

Key font/google font/local Type Required
src String or Array of Objects Yes
weight String or Array Required/Optional
style String or Array -
subsets Array of Strings -
axes Array of Strings -
display String -
preload Boolean -
fallback Array of Strings -
adjustFontFallback Boolean or String -
variable String -
declarations Array 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:

  • 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: '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

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

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%' }]

Applying Styles

You can apply the font styles in three ways:

className

Returns a read-only CSS className for the loaded font to be passed to an HTML element.

<p className={inter.className}>Hello, Next.js!</p>

style

Returns a read-only CSS style object for the loaded font to be passed to an HTML element, including style.fontFamily to access the font family name and fallback fonts.

<p style={inter.style}>Hello World</p>

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:

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

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

<main className={inter.variable}>
  <p className={styles.text}>Hello World</p>
</main>
<main className={inter.variable}>
  <p className={styles.text}>Hello World</p>
</main>

Define the text selector class in the component.module.css CSS file as follows:

.text {
  font-family: var(--font-inter);
  font-weight: 200;
  font-style: italic;
}

In the example above, the text Hello World is styled using the Inter font and the generated font fallback with font-weight: 200 and font-style: italic.

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:

import { Inter, Lora, Source_Sans_3 } from 'next/font/google'
import localFont from 'next/font/local'

// define your variable fonts
const inter = Inter()
const lora = Lora()
// define 2 weights of a non-variable font
const sourceCodePro400 = Source_Sans_3({ weight: '400' })
const sourceCodePro700 = Source_Sans_3({ 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 }
import { Inter, Lora, Source_Sans_3 } from 'next/font/google'
import localFont from 'next/font/local'

// define your variable fonts
const inter = Inter()
const lora = Lora()
// define 2 weights of a non-variable font
const sourceCodePro400 = Source_Sans_3({ weight: '400' })
const sourceCodePro700 = Source_Sans_3({ 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:

import { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts'

export default function Page() {
  return (
    <div>
      <p className={inter.className}>Hello world using Inter font</p>
      <p style={lora.style}>Hello world using Lora font</p>
      <p className={sourceCodePro700.className}>
        Hello world using Source_Sans_3 font with weight 700
      </p>
      <p className={greatVibes.className}>My title in Great Vibes font</p>
    </div>
  )
}
import { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts'

export default function Page() {
  return (
    <div>
      <p className={inter.className}>Hello world using Inter font</p>
      <p style={lora.style}>Hello world using Lora font</p>
      <p className={sourceCodePro700.className}>
        Hello world using Source_Sans_3 font with weight 700
      </p>
      <p className={greatVibes.className}>My title in Great Vibes font</p>
    </div>
  )
}

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:

{
  "compilerOptions": {
    "paths": {
      "@/fonts": ["./styles/fonts"]
    }
  }
}

You can now import any font definition as follows:

import { greatVibes, sourceCodePro400 } from '@/fonts'
import { greatVibes, sourceCodePro400 } from '@/fonts'

Version Changes

Version Changes
v13.2.0 @next/font renamed to next/font. Installation no longer required.
v13.0.0 @next/font was added.

image


title: description: Optimize Images in your Next.js Application using the built-in next/image Component.

{/* The content of this doc is shared between the app and pages router. You can use the <PagesOnly>Content</PagesOnly> component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

Examples

Good to know: If you are using a version of Next.js prior to 13, you'll want to use the next/legacy/image documentation since the component was renamed.

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.

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:

| Prop | Example | Type | Status | | ----------------------------------------- | ---------------------------------------- | --------------- | ---------- | | [`src`](#src) | `src="/profile.png"` | String | Required | | [`width`](#width) | `width={500}` | Integer (px) | Required | | [`height`](#height) | `height={500}` | Integer (px) | Required | | [`alt`](#alt) | `alt="Picture of the author"` | String | Required | | [`loader`](#loader) | `loader={imageLoader}` | Function | - | | [`fill`](#fill) | `fill={true}` | Boolean | - | | [`sizes`](#sizes) | `sizes="(max-width: 768px) 100vw, 33vw"` | String | - | | [`quality`](#quality) | `quality={80}` | Integer (1-100) | - | | [`priority`](#priority) | `priority={true}` | Boolean | - | | [`placeholder`](#placeholder) | `placeholder="blur"` | String | - | | [`style`](#style) | `style={{objectFit: "contain"}}` | Object | - | | [`onLoadingComplete`](#onloadingcomplete) | `onLoadingComplete={img => done())}` | Function | Deprecated | | [`onLoad`](#onload) | `onLoad={event => done())}` | Function | - | | [`onError`](#onerror) | `onError(event => fail()}` | Function | - | | [`loading`](#loading) | `loading="lazy"` | String | - | | [`blurDataURL`](#blurdataurl) | `blurDataURL="data:image/jpeg..."` | String | - |

Required Props

The Image Component requires the following properties: src, width, height, and alt.

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

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

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:

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}
      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, which is useful when the width and height are unknown.

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.

If no styles are applied to the image, the image will stretch 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:

sizes

A string, similar to a media query, that provides information about how wide the image will be at different breakpoints. The value of sizes will greatly affect performance for images using fill or which are styled to have a responsive size.

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 srcset. When the browser chooses, it does not yet know the size of the image on the page, so it selects an image that is the same size or larger than the viewport. The sizes property allows you to tell the browser that the image will actually be smaller than full screen. If you don't specify a sizes value in an image with the fill property, a default value of 100vw (full screen width) is used.
  • Second, the sizes property changes the behavior of the automatically generated srcset value. If no sizes value is present, a small srcset is generated, suitable for a fixed-size image (1x/2x/etc). If sizes is defined, a large srcset is generated, suitable for a responsive image (640w/750w/etc). If the sizes property includes sizes such as 50vw, which represent a percentage of the viewport width, then the srcset is trimmed to not include any values which are too small to ever be necessary.

For example, if you know your styling will cause an image to be full-width on mobile devices, in a 2-column layout on tablets, and a 3-column layout on desktop displays, you should include a sizes property such as the following:

import Image from 'next/image'

export default function Page() {
  return (
    <div className="grid-element">
      <Image
        fill
        src="/example.png"
        sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      />
    </div>
  )
}

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:

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={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" | "data:image/..."

A placeholder to use while the image is loading. Possible values are blur, empty, or data:image/.... 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, except when the image is detected to be animated.

For dynamic images, you must provide the blurDataURL property. Solutions such as Plaiceholder can help with base64 generation.

When data:image/..., the Data URL will be used as the placeholder while the image is loading.

When empty, there will be no placeholder while the image is loading, only empty space.

Try it out:

Advanced Props

In some cases, you may need more advanced usage. The <Image /> component optionally accepts the following advanced properties.

style

Allows passing CSS styles to the underlying image element.

const imageStyle = {
  borderRadius: '50%',
  border: '1px solid #fff',
}

export default function ProfileImage() {
  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)} />

Warning: Deprecated since Next.js 14 in favor of onLoad.

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 once the image is completely loaded and the placeholder has been removed.

The callback function will be called with one argument, the Event which has a target that references the underlying <img> element.

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}

The loading behavior of the image. Defaults to lazy.

When lazy, defer loading the image until it reaches a calculated distance from the viewport.

When eager, load the image immediately.

Learn more about the loading attribute.

blurDataURL

A Data URL to be used as a placeholder image before the src image successfully loads. Only takes effect when combined with placeholder="blur".

Must be a base64-encoded image. It will be enlarged and blurred, so a very small image (10px or less) is recommended. Including larger images as placeholders may harm your application performance.

Try it out:

You can also generate a solid color Data URL to match the image.

unoptimized

unoptimized = {false} // {false} | {true}

When true, the source image will be served as-is instead of changing quality, size, or format. Defaults to false.

import Image from 'next/image'

const UnoptimizedImage = (props) => {
  return <Image {...props} unoptimized />
}

Since Next.js 12.3.0, this prop can be assigned to all images by updating next.config.js with the following configuration:

module.exports = {
  images: {
    unoptimized: true,
  },
}

Other Props

Other properties on the <Image /> component will be passed to the underlying img element with the exception of the following:

  • srcSet. Use Device Sizes instead.
  • decoding. It is always "async".

Configuration Options

In addition to props, you can configure the Image Component in next.config.js. The following options are available:

remotePatterns

To protect your application from malicious users, configuration is required in order to use external images. This ensures that only external images from your account can be served from the Next.js Image Optimization API. These external images can be configured with the remotePatterns property in your next.config.js file, as shown below:

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        port: '',
        pathname: '/account123/**',
      },
    ],
  },
}

Good to know: The example above will ensure the src property of next/image must start with https://example.com/account123/. Any other protocol, hostname, port, or unmatched path will respond with 400 Bad Request.

Below is another example of the remotePatterns property in the next.config.js file:

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
      },
    ],
  },
}

Good to know: The example above will ensure the src property of next/image must start with https://img1.example.com or https://me.avatar.example.com or any number of subdomains. Any other protocol or unmatched hostname will respond with 400 Bad Request.

Wildcard patterns can be used for both pathname and hostname and have the following syntax:

  • * match a single path segment or subdomain
  • ** match any number of path segments at the end or subdomains at the beginning

The ** syntax does not work in the middle of the pattern.

domains

Warning: Deprecated since Next.js 14 in favor of strict remotePatterns in order to protect your application from malicious users. Only use domains if you own all the content served from the domain.

Similar to remotePatterns, the domains configuration can be used to provide a list of allowed hostnames for external images.

However, the domains configuration does not support wildcard pattern matching and it cannot restrict protocol, port, or pathname.

Below is an example of the domains property in the next.config.js file:

module.exports = {
  images: {
    domains: ['assets.acme.com'],
  },
}

loaderFile

If you want to use a cloud provider to optimize images instead of using the Next.js built-in Image Optimization API, you can configure the loaderFile in your next.config.js like the following:

module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './my/image/loader.js',
  },
}

This must point to a file relative to the root of your Next.js application. The file must export a default function that returns a string, for example:

'use client'

export default function myImageLoader({ src, width, quality }) {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

Alternatively, you can use the loader prop to configure each instance of next/image.

Examples:

Good to know: Customizing the image loader file, which accepts a function, require using Client Components to serialize the provided function.

Advanced

The following configuration is for advanced use cases and is usually not necessary. If you choose to configure the properties below, you will override any changes to the Next.js defaults in future updates.

deviceSizes

If you know the expected device widths of your users, you can specify a list of device width breakpoints using the deviceSizes property in next.config.js. These widths are used when the next/image component uses sizes prop to ensure the correct image is served for user's device.

If no configuration is provided, the default below is used.

module.exports = {
  images: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  },
}

imageSizes

You can specify a list of image widths using the images.imageSizes property in your next.config.js file. These widths are concatenated with the array of device sizes to form the full array of sizes used to generate image srcsets.

The reason there are two separate lists is that imageSizes is only used for images which provide a sizes prop, which indicates that the image is less than the full width of the screen. Therefore, the sizes in imageSizes should all be smaller than the smallest size in deviceSizes.

If no configuration is provided, the default below is used.

module.exports = {
  images: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}

formats

The default Image Optimization API will automatically detect the browser's supported image formats via the request's Accept header.

If the Accept head matches more than one of the configured formats, the first match in the array is used. Therefore, the array order matters. If there is no match (or the source image is animated), the Image Optimization API will fallback to the original image's format.

If no configuration is provided, the default below is used.

module.exports = {
  images: {
    formats: ['image/webp'],
  },
}

You can enable AVIF support with the following configuration.

module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
}

Good to know:

  • AVIF generally takes 20% longer to encode but it compresses 20% smaller compared to WebP. This means that the first time an image is requested, it will typically be slower and then subsequent requests that are cached will be faster.
  • If you self-host with a Proxy/CDN in front of Next.js, you must configure the Proxy to forward the Accept header.

Caching Behavior

The following describes the caching algorithm for the default loader. For all other loaders, please refer to your cloud provider's documentation.

Images are optimized dynamically upon request and stored in the <distDir>/cache/images directory. The optimized image file will be served for subsequent requests until the expiration is reached. When a request is made that matches a cached but expired file, the expired image is served stale immediately. Then the image is optimized again in the background (also called revalidation) and saved to the cache with the new expiration date.

The cache status of an image can be determined by reading the value of the x-nextjs-cache response header. The possible values are the following:

  • MISS - the path is not in the cache (occurs at most once, on the first visit)
  • STALE - the path is in the cache but exceeded the revalidate time so it will be updated in the background
  • HIT - the path is in the cache and has not exceeded the revalidate time

The expiration (or rather Max Age) is defined by either the minimumCacheTTL configuration or the upstream image Cache-Control header, whichever is larger. Specifically, the max-age value of the Cache-Control header is used. If both s-maxage and max-age are found, then s-maxage is preferred. The max-age is also passed-through to any downstream clients including CDNs and browsers.

  • You can configure minimumCacheTTL to increase the cache duration when the upstream image does not include Cache-Control header or the value is very low.
  • You can configure deviceSizes and imageSizes to reduce the total number of possible generated images.
  • You can configure formats to disable multiple formats in favor of a single image format.

minimumCacheTTL

You can configure the Time to Live (TTL) in seconds for cached optimized images. In many cases, it's better to use a Static Image Import which will automatically hash the file contents and cache the image forever with a Cache-Control header of immutable.

module.exports = {
  images: {
    minimumCacheTTL: 60,
  },
}

The expiration (or rather Max Age) of the optimized image is defined by either the minimumCacheTTL or the upstream image Cache-Control header, whichever is larger.

If you need to change the caching behavior per image, you can configure headers to set the Cache-Control header on the upstream image (e.g. /some-asset.jpg, not /_next/image itself).

There is no mechanism to invalidate the cache at this time, so its best to keep minimumCacheTTL low. Otherwise you may need to manually change the src prop or delete <distDir>/cache/images.

disableStaticImages

The default behavior allows you to import static files such as import icon from './icon.png' and then pass that to the src property.

In some cases, you may wish to disable this feature if it conflicts with other plugins that expect the import to behave differently.

You can disable static image imports inside your next.config.js:

module.exports = {
  images: {
    disableStaticImages: true,
  },
}

dangerouslyAllowSVG

The default loader does not optimize SVG images for a few reasons. First, SVG is a vector format meaning it can be resized losslessly. Second, SVG has many of the same features as HTML/CSS, which can lead to vulnerabilities without a proper Content Security Policy.

If you need to serve SVG images with the default Image Optimization API, you can set dangerouslyAllowSVG inside your next.config.js:

module.exports = {
  images: {
    dangerouslyAllowSVG: true,
    contentDispositionType: 'attachment',
    contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
  },
}

In addition, it is strongly recommended to also set contentDispositionType to force the browser to download the image, as well as contentSecurityPolicy to prevent scripts embedded in the image from executing.

Animated Images

The default loader will automatically bypass Image Optimization for animated images and serve the image as-is.

Auto-detection for animated files is best-effort and supports GIF, APNG, and WebP. If you want to explicitly bypass Image Optimization for a given animated image, use the unoptimized prop.

Responsive Images

The default generated srcset contains 1x and 2x images in order to support different device pixel ratios. However, you may wish to render a responsive image that stretches with the viewport. In that case, you'll need to set sizes as well as style (or className).

You can render a responsive image using one of the following methods below.

Responsive image using a static import

If the source image is not dynamic, you can statically import to create a responsive image:

import Image from 'next/image'
import me from '../photos/me.jpg'

export default function Author() {
  return (
    <Image
      src={me}
      alt="Picture of the author"
      sizes="100vw"
      style={{
        width: '100%',
        height: 'auto',
      }}
    />
  )
}

Try it out:

Responsive image with aspect ratio

If the source image is a dynamic or a remote url, you will also need to provide width and height to set the correct aspect ratio of the responsive image:

import Image from 'next/image'

export default function Page({ photoUrl }) {
  return (
    <Image
      src={photoUrl}
      alt="Picture of the author"
      sizes="100vw"
      style={{
        width: '100%',
        height: 'auto',
      }}
      width={500}
      height={300}
    />
  )
}

Try it out:

Responsive image with fill

If you don't know the aspect ratio, you will need to set the fill prop and set position: relative on the parent. Optionally, you can set object-fit style depending on the desired stretch vs crop behavior:

import Image from 'next/image'

export default function Page({ photoUrl }) {
  return (
    <div style={{ position: 'relative', width: '500px', height: '300px' }}>
      <Image
        src={photoUrl}
        alt="Picture of the author"
        sizes="500px"
        fill
        style={{
          objectFit: 'contain',
        }}
      />
    </div>
  )
}

Try it out:

Theme Detection

If you want to display a different image for light and dark mode, you can create a new component that wraps two <Image> components and reveals the correct one based on a CSS media query.

.imgDark {
  display: none;
}

@media (prefers-color-scheme: dark) {
  .imgLight {
    display: none;
  }
  .imgDark {
    display: unset;
  }
}
import styles from './theme-image.module.css'
import Image, { ImageProps } from 'next/image'

type Props = Omit<ImageProps, 'src' | 'priority' | 'loading'> & {
  srcLight: string
  srcDark: string
}

const ThemeImage = (props: Props) => {
  const { srcLight, srcDark, ...rest } = props

  return (
    <>
      <Image {...rest} src={srcLight} className={styles.imgLight} />
      <Image {...rest} src={srcDark} className={styles.imgDark} />
    </>
  )
}
import styles from './theme-image.module.css'
import Image from 'next/image'

const ThemeImage = (props) => {
  const { srcLight, srcDark, ...rest } = props

  return (
    <>
      <Image {...rest} src={srcLight} className={styles.imgLight} />
      <Image {...rest} src={srcDark} className={styles.imgDark} />
    </>
  )
}

Good to know: The default behavior of loading="lazy" ensures that only the correct image is loaded. You cannot use priority or loading="eager" because that would cause both images to load. Instead, you can use fetchPriority="high".

Try it out:

Known Browser Bugs

This next/image component uses browser native lazy loading, which may fallback to eager loading for older browsers before Safari 15.4. When using the blur-up placeholder, older browsers before Safari 12 will fallback to empty placeholder. When using styles with width/height of auto, it is possible to cause Layout Shift on older browsers before Safari 15 that don't preserve the aspect ratio. For more details, see this MDN video.

  • Safari 15 - 16.3 display a gray border while loading. Safari 16.4 fixed this issue. Possible solutions:
    • Use CSS @supports (font: -apple-system-body) and (-webkit-appearance: none) { img[loading="lazy"] { clip-path: inset(0.6px) } }
    • Use priority if the image is above the fold
  • Firefox 67+ displays a white background while loading. Possible solutions:

Version History

Version Changes
v14.0.0 onLoadingComplete prop and domains config deprecated.
v13.4.14 placeholder prop support for data:/image...
v13.2.0 contentDispositionType configuration added.
v13.0.6 ref prop added.
v13.0.0 The next/image import was renamed to next/legacy/image. The next/future/image import was renamed to next/image. A codemod is available to safely and automatically rename your imports. <span> wrapper removed. layout, objectFit, objectPosition, lazyBoundary, lazyRoot props removed. alt is required. onLoadingComplete receives reference to img element. Built-in loader config removed.
v12.3.0 remotePatterns and unoptimized configuration is stable.
v12.2.0 Experimental remotePatterns and experimental unoptimized configuration added. layout="raw" removed.
v12.1.1 style prop added. Experimental support for layout="raw" added.
v12.1.0 dangerouslyAllowSVG and contentSecurityPolicy configuration added.
v12.0.9 lazyRoot prop added.
v12.0.0 formats configuration added.
AVIF support added.
Wrapper <div> changed to <span>.
v11.1.0 onLoadingComplete and lazyBoundary props added.
v11.0.0 src prop support for static import.
placeholder prop added.
blurDataURL prop added.
v10.0.5 loader prop added.
v10.0.1 layout prop added.
v10.0.0 next/image introduced.

index


title: Components description: API Reference for Next.js built-in components.

{/* The content of this doc is shared between the app and pages router. You can use the <PagesOnly>Content</PagesOnly> component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

link


title: description: Enable fast client-side navigation with the built-in next/link component.

{/* The content of this doc is shared between the app and pages router. You can use the <PagesOnly>Content</PagesOnly> component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

Examples

<Link> is a React component that extends the HTML <a> element to provide prefetching and client-side navigation between routes. It is the primary way to navigate between routes in Next.js.

import Link from 'next/link'

export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}
import Link from 'next/link'

export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}

For an example, consider a pages directory with the following files:

  • pages/index.js
  • pages/about.js
  • pages/blog/[slug].js

We can have a link to each of these pages like so:

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">Home</Link>
      </li>
      <li>
        <Link href="/about">About Us</Link>
      </li>
      <li>
        <Link href="/blog/hello-world">Blog Post</Link>
      </li>
    </ul>
  )
}

export default Home

Props

Here's a summary of the props available for the Link Component:

Prop Example Type Required
href href="/dashboard" String or Object Yes
replace replace={false} Boolean -
scroll scroll={false} Boolean -
prefetch prefetch={false} Boolean -

Good to know: <a> tag attributes such as className or target="_blank" can be added to <Link> as props and will be passed to the underlying <a> element.

href (required)

The path or URL to navigate to.

<Link href="/dashboard">Dashboard</Link>

href can also accept an object, for example:

// Navigate to /about?name=test
<Link
  href={{
    pathname: '/about',
    query: { name: 'test' },
  }}
>
  About
</Link>

replace

Defaults to false. When true, next/link will replace the current history state instead of adding a new URL into the browser’s history stack.

import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" replace>
      Dashboard
    </Link>
  )
}
import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" replace>
      Dashboard
    </Link>
  )
}

scroll

Defaults to true. The default behavior of <Link> is to scroll to the top of a new route or to maintain the scroll position for backwards and forwards navigation. When false, next/link will not scroll to the top of the page after a navigation.

import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" scroll={false}>
      Dashboard
    </Link>
  )
}
import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" scroll={false}>
      Dashboard
    </Link>
  )
}

prefetch

Defaults to true. When true, next/link will prefetch the page (denoted by the href) in the background. This is useful for improving the performance of client-side navigations. Any <Link /> in the viewport (initially or through scroll) will be preloaded.

Prefetch can be disabled by passing prefetch={false}. Prefetching is only enabled in production.

import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" prefetch={false}>
      Dashboard
    </Link>
  )
}
import Link from 'next/link'

export default function Page() {
  return (
    <Link href="/dashboard" prefetch={false}>
      Dashboard
    </Link>
  )
}

Other Props

legacyBehavior

An <a> element is no longer required as a child of <Link>. Add the legacyBehavior prop to use the legacy behavior or remove the <a> to upgrade. A codemod is available to automatically upgrade your code.

Good to know: when legacyBehavior is not set to true, all anchor tag properties can be passed to next/link as well such as, className, onClick, etc.

passHref

Forces Link to send the href property to its child. Defaults to false

scroll

Scroll to the top of the page after a navigation. Defaults to true

shallow

Update the path of the current page without rerunning getStaticProps, getServerSideProps or getInitialProps. Defaults to false

locale

The active locale is automatically prepended. locale allows for providing a different locale. When false href has to include the locale as the default behavior is disabled.

Examples

Linking to Dynamic Routes

For dynamic routes, it can be handy to use template literals to create the link's path.

For example, you can generate a list of links to the dynamic route pages/blog/[slug].js

import Link from 'next/link'

function Posts({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  )
}

export default Posts

For example, you can generate a list of links to the dynamic route app/blog/[slug]/page.js:

import Link from 'next/link'

function Page({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <Link href={`/blog/${post.slug}`}>{post.title}</Link>
        </li>
      ))}
    </ul>
  )
}

If the child is a custom component that wraps an <a> tag

If the child of Link is a custom component that wraps an <a> tag, you must add passHref to Link. This is necessary if you’re using libraries like styled-components. Without this, the <a> tag will not have the href attribute, which hurts your site's accessibility and might affect SEO. If you're using ESLint, there is a built-in rule next/link-passhref to ensure correct usage of passHref.

If the child of Link is a custom component that wraps an <a> tag, you must add passHref to Link. This is necessary if you’re using libraries like styled-components. Without this, the <a> tag will not have the href attribute, which hurts your site's accessibility and might affect SEO. If you're using ESLint, there is a built-in rule next/link-passhref to ensure correct usage of passHref.

import Link from 'next/link'
import styled from 'styled-components'

// This creates a custom component that wraps an <a> tag
const RedLink = styled.a`
  color: red;
`

function NavLink({ href, name }) {
  return (
    <Link href={href} passHref legacyBehavior>
      <RedLink>{name}</RedLink>
    </Link>
  )
}

export default NavLink
  • If you’re using emotion’s JSX pragma feature (@jsx jsx), you must use passHref even if you use an <a> tag directly.
  • The component should support onClick property to trigger navigation correctly

If the child is a functional component

If the child of Link is a functional component, in addition to using passHref and legacyBehavior, you must wrap the component in React.forwardRef:

import Link from 'next/link'

// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
  return (
    <a href={href} onClick={onClick} ref={ref}>
      Click Me
    </a>
  )
})

function Home() {
  return (
    <Link href="/about" passHref legacyBehavior>
      <MyButton />
    </Link>
  )
}

export default Home

With URL Object

Link can also receive a URL object and it will automatically format it to create the URL string. Here's how to do it:

import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link
          href={{
            pathname: '/about',
            query: { name: 'test' },
          }}
        >
          About us
        </Link>
      </li>
      <li>
        <Link
          href={{
            pathname: '/blog/[slug]',
            query: { slug: 'my-post' },
          }}
        >
          Blog Post
        </Link>
      </li>
    </ul>
  )
}

export default Home

The above example has a link to:

  • A predefined route: /about?name=test
  • A dynamic route: /blog/my-post

You can use every property as defined in the Node.js URL module documentation.

Replace the URL instead of push

The default behavior of the Link component is to push a new URL into the history stack. You can use the replace prop to prevent adding a new entry, as in the following example:

<Link href="/about" replace>
  About us
</Link>

Disable scrolling to the top of the page

The default behavior of Link is to scroll to the top of the page. When there is a hash defined it will scroll to the specific id, like a normal <a> tag. To prevent scrolling to the top / hash scroll={false} can be added to Link:

<Link href="/#hashid" scroll={false}>
  Disables scrolling to the top
</Link>

Middleware

It's common to use Middleware for authentication or other purposes that involve rewriting the user to a different page. In order for the <Link /> component to properly prefetch links with rewrites via Middleware, you need to tell Next.js both the URL to display and the URL to prefetch. This is required to avoid un-necessary fetches to middleware to know the correct route to prefetch.

For example, if you want to serve a /dashboard route that has authenticated and visitor views, you may add something similar to the following in your Middleware to redirect the user to the correct page:

export function middleware(req) {
  const nextUrl = req.nextUrl
  if (nextUrl.pathname === '/dashboard') {
    if (req.cookies.authToken) {
      return NextResponse.rewrite(new URL('/auth/dashboard', req.url))
    } else {
      return NextResponse.rewrite(new URL('/public/dashboard', req.url))
    }
  }
}

In this case, you would want to use the following code in your <Link /> component:

import Link from 'next/link'
import useIsAuthed from './hooks/useIsAuthed'

export default function Page() {
  const isAuthed = useIsAuthed()
  const path = isAuthed ? '/auth/dashboard' : '/dashboard'
  return (
    <Link as="/dashboard" href={path}>
      Dashboard
    </Link>
  )
}

Good to know: If you're using Dynamic Routes, you'll need to adapt your as and href props. For example, if you have a Dynamic Route like /dashboard/[user] that you want to present differently via middleware, you would write: <Link href={{ pathname: '/dashboard/authed/[user]', query: { user: username } }} as="/dashboard/[user]">Profile</Link>.

Version History

Version Changes
v13.0.0 No longer requires a child <a> tag. A codemod is provided to automatically update your codebase.
v10.0.0 href props pointing to a dynamic route are automatically resolved and no longer require an as prop.
v8.0.0 Improved prefetching performance.
v1.0.0 next/link introduced.

script


title: <Script> description: Optimize third-party scripts in your Next.js application using the built-in next/script Component.

{/* The content of this doc is shared between the app and pages router. You can use the <PagesOnly>Content</PagesOnly> component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

This API reference will help you understand how to use props available for the Script Component. For features and usage, please see the Optimizing Scripts page.

import Script from 'next/script'

export default function Dashboard() {
  return (
    <>
      <Script src="https://example.com/script.js" />
    </>
  )
}
import Script from 'next/script'

export default function Dashboard() {
  return (
    <>
      <Script src="https://example.com/script.js" />
    </>
  )
}

Props

Here's a summary of the props available for the Script Component:

Prop Example Type Required
src src="http://example.com/script" String Required unless inline script is used
strategy strategy="lazyOnload" String -
onLoad onLoad={onLoadFunc} Function -
onReady onReady={onReadyFunc} Function -
onError onError={onErrorFunc} Function -

Required Props

The <Script /> component requires the following properties.

src

A path string specifying the URL of an external script. This can be either an absolute external URL or an internal path. The src property is required unless an inline script is used.

Optional Props

The <Script /> component accepts a number of additional properties beyond those which are required.

strategy

The loading strategy of the script. There are four different strategies that can be used:

  • beforeInteractive: Load before any Next.js code and before any page hydration occurs.
  • afterInteractive: (default) Load early but after some hydration on the page occurs.
  • lazyOnload: Load during browser idle time.
  • worker: (experimental) Load in a web worker.

beforeInteractive

Scripts that load with the beforeInteractive strategy are injected into the initial HTML from the server, downloaded before any Next.js module, and executed in the order they are placed before any hydration occurs on the page.

Scripts denoted with this strategy are preloaded and fetched before any first-party code, but their execution does not block page hydration from occurring.

beforeInteractive scripts must be placed inside the root layout (app/layout.tsx) and are designed to load scripts that are needed by the entire site (i.e. the script will load when any page in the application has been loaded server-side).

This strategy should only be used for critical scripts that need to be fetched before any part of the page becomes interactive.

import Script from 'next/script'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
      <Script
        src="https://example.com/script.js"
        strategy="beforeInteractive"
      />
    </html>
  )
}
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      <Script
        src="https://example.com/script.js"
        strategy="beforeInteractive"
      />
    </html>
  )
}
import { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
        <Script
          src="https://example.com/script.js"
          strategy="beforeInteractive"
        />
      </body>
    </Html>
  )
}

Good to know: Scripts with beforeInteractive will always be injected inside the head of the HTML document regardless of where it's placed in the component.

Some examples of scripts that should be loaded as soon as possible with beforeInteractive include:

  • Bot detectors
  • Cookie consent managers

afterInteractive

Scripts that use the afterInteractive strategy are injected into the HTML client-side and will load after some (or all) hydration occurs on the page. This is the default strategy of the Script component and should be used for any script that needs to load as soon as possible but not before any first-party Next.js code.

afterInteractive scripts can be placed inside of any page or layout and will only load and execute when that page (or group of pages) is opened in the browser.

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="afterInteractive" />
    </>
  )
}

Some examples of scripts that are good candidates for afterInteractive include:

  • Tag managers
  • Analytics

lazyOnload

Scripts that use the lazyOnload strategy are injected into the HTML client-side during browser idle time and will load after all resources on the page have been fetched. This strategy should be used for any background or low priority scripts that do not need to load early.

lazyOnload scripts can be placed inside of any page or layout and will only load and execute when that page (or group of pages) is opened in the browser.

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="lazyOnload" />
    </>
  )
}

Examples of scripts that do not need to load immediately and can be fetched with lazyOnload include:

  • Chat support plugins
  • Social media widgets

worker

Warning: The worker strategy is not yet stable and does not yet work with the app directory. Use with caution.

Scripts that use the worker strategy are off-loaded to a web worker in order to free up the main thread and ensure that only critical, first-party resources are processed on it. While this strategy can be used for any script, it is an advanced use case that is not guaranteed to support all third-party scripts.

To use worker as a strategy, the nextScriptWorkers flag must be enabled in next.config.js:

module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
}

worker scripts can only currently be used in the pages/ directory:

import Script from 'next/script'

export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}
import Script from 'next/script'

export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}

onLoad

Warning: onLoad does not yet work with Server Components and can only be used in Client Components. Further, onLoad can't be used with beforeInteractive – consider using onReady instead.

Some third-party scripts require users to run JavaScript code once after the script has finished loading in order to instantiate content or call a function. If you are loading a script with either afterInteractive or lazyOnload as a loading strategy, you can execute code after it has loaded using the onLoad property.

Here's an example of executing a lodash method only after the library has been loaded.

'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"
        onLoad={() => {
          console.log(_.sample([1, 2, 3, 4]))
        }}
      />
    </>
  )
}
'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"
        onLoad={() => {
          console.log(_.sample([1, 2, 3, 4]))
        }}
      />
    </>
  )
}

onReady

Warning: onReady does not yet work with Server Components and can only be used in Client Components.

Some third-party scripts require users to run JavaScript code after the script has finished loading and every time the component is mounted (after a route navigation for example). You can execute code after the script's load event when it first loads and then after every subsequent component re-mount using the onReady property.

Here's an example of how to re-instantiate a Google Maps JS embed every time the component is mounted:

'use client'

import { useRef } from 'react'
import Script from 'next/script'

export default function Page() {
  const mapRef = useRef()

  return (
    <>
      <div ref={mapRef}></div>
      <Script
        id="google-maps"
        src="https://maps.googleapis.com/maps/api/js"
        onReady={() => {
          new google.maps.Map(mapRef.current, {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          })
        }}
      />
    </>
  )
}
'use client'

import { useRef } from 'react'
import Script from 'next/script'

export default function Page() {
  const mapRef = useRef()

  return (
    <>
      <div ref={mapRef}></div>
      <Script
        id="google-maps"
        src="https://maps.googleapis.com/maps/api/js"
        onReady={() => {
          new google.maps.Map(mapRef.current, {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          })
        }}
      />
    </>
  )
}
import { useRef } from 'react';
import Script from 'next/script';

export default function Page() {
  const mapRef = useRef();

  return (
    <PagesOnly>
      <div ref={mapRef}></div>
      <Script
        id="google-maps"
        src="https://maps.googleapis.com/maps/api/js"
        onReady={() => {
          new google.maps.Map(mapRef.current, {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          });
        }}
      />
    </>
  );
}

onError

Warning: onError does not yet work with Server Components and can only be used in Client Components. onError cannot be used with the beforeInteractive loading strategy.

Sometimes it is helpful to catch when a script fails to load. These errors can be handled with the onError property:

'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error('Script failed to load', e)
        }}
      />
    </>
  )
}
'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error('Script failed to load', e)
        }}
      />
    </>
  )
}
import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error('Script failed to load', e)
        }}
      />
    </>
  )
}

Version History

Version Changes
v13.0.0 beforeInteractive and afterInteractive is modified to support app.
v12.2.4 onReady prop added.
v12.2.2 Allow next/script with beforeInteractive to be placed in _document.
v11.0.0 next/script introduced.