Script

本 API 参考将帮助您理解如何使用 Script 组件提供的 props。关于功能特性和用法,请参阅 脚本优化 页面。

import Script from 'next/script'

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

Props

以下是 Script 组件可用的 props 概览:

Prop示例类型是否必需
srcsrc="http://example.com/script"字符串除非使用内联脚本,否则必需
strategystrategy="lazyOnload"字符串-
onLoadonLoad={onLoadFunc}函数-
onReadyonReady={onReadyFunc}函数-
onErroronError={onErrorFunc}函数-

必需 Props

<Script /> 组件需要以下属性。

src

指定外部脚本 URL 的路径字符串。可以是绝对外部 URL 或内部路径。除非使用内联脚本,否则 src 属性是必需的。

可选 Props

<Script /> 组件还接受许多额外属性。

strategy

脚本的加载策略。共有四种可用策略:

  • beforeInteractive: 在任何 Next.js 代码和页面 hydration 之前加载。
  • afterInteractive: (默认) 在页面部分 hydration 后尽早加载。
  • lazyOnload: 在浏览器空闲时加载。
  • worker: (实验性) 在 web worker 中加载。

beforeInteractive

使用 beforeInteractive 策略的脚本会从服务器注入到初始 HTML 中,在任何 Next.js 模块之前下载,并按放置顺序执行。

标记为此策略的脚本会被预加载并在任何第一方代码之前获取,但其执行不会阻塞页面 hydration

beforeInteractive 脚本必须放置在根布局 (app/layout.tsx) 中,设计用于加载整个站点所需的脚本(即当应用程序中的任何页面在服务端加载时,该脚本都会加载)。

此策略仅适用于需要尽快获取的关键脚本。

import Script from 'next/script'

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

须知:无论放置在组件何处,beforeInteractive 脚本始终会注入到 HTML 文档的 head 中。

适合使用 beforeInteractive 尽快加载的脚本示例包括:

  • 机器人检测器
  • Cookie 同意管理器

afterInteractive

使用 afterInteractive 策略的脚本会在客户端注入到 HTML 中,在页面部分(或全部)hydration 完成后加载。这是 Script 组件的默认策略,适用于需要尽快加载但不应在任何第一方 Next.js 代码之前加载的脚本。

afterInteractive 脚本可以放置在任何页面或布局中,仅当该页面(或页面组)在浏览器中打开时才会加载和执行。

app/page.js
import Script from 'next/script'

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

适合使用 afterInteractive 的脚本示例包括:

  • 标签管理器
  • 分析工具

lazyOnload

使用 lazyOnload 策略的脚本会在浏览器空闲时客户端注入到 HTML 中,并在页面所有资源获取完成后加载。此策略适用于不需要提前加载的后台或低优先级脚本。

lazyOnload 脚本可以放置在任何页面或布局中,仅当该页面(或页面组)在浏览器中打开时才会加载和执行。

app/page.js
import Script from 'next/script'

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

不需要立即加载且适合使用 lazyOnload 的脚本示例包括:

  • 聊天支持插件
  • 社交媒体小组件

worker

警告worker 策略尚未稳定,且目前不适用于应用路由。请谨慎使用。

使用 worker 策略的脚本会被卸载到 web worker 中,以释放主线程并确保仅处理关键的第一方资源。虽然此策略可用于任何脚本,但这是一个高级用例,不保证支持所有第三方脚本。

要使用 worker 策略,必须在 next.config.js 中启用 nextScriptWorkers 标志:

next.config.js
module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
}

worker 脚本目前只能用于 pages/ 目录

import Script from 'next/script'

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

onLoad

警告onLoad 目前不适用于服务端组件,仅能在客户端组件中使用。此外,onLoad 不能与 beforeInteractive 一起使用——请考虑改用 onReady

某些第三方脚本要求在脚本加载完成后立即执行 JavaScript 代码以初始化内容或调用函数。如果使用 afterInteractivelazyOnload 作为加载策略,可以通过 onLoad 属性在脚本加载后执行代码。

以下示例展示了仅在 lodash 库加载完成后才执行其方法:

'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

警告onReady 目前不适用于服务端组件,仅能在客户端组件中使用。

某些第三方脚本要求在脚本加载完成后以及每次组件挂载时(例如路由导航后)执行 JavaScript 代码。可以通过 onReady 属性在脚本首次加载时及其后每次组件重新挂载时执行代码。

以下示例展示了如何在每次组件挂载时重新实例化 Google Maps JS 嵌入:

'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,
          })
        }}
      />
    </>
  )
}

onError

警告onError 目前不适用于服务端组件,仅能在客户端组件中使用。onError 不能与 beforeInteractive 加载策略一起使用。

有时捕获脚本加载失败很有帮助。可以通过 onError 属性处理这些错误:

'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)
        }}
      />
    </>
  )
}

版本历史

版本变更
v13.0.0修改 beforeInteractiveafterInteractive 以支持 app
v12.2.4新增 onReady prop。
v12.2.2允许在 _document 中使用 beforeInteractivenext/script
v11.0.0引入 next/script

On this page