跳到内容

Script

本 API 参考将帮助您了解如何使用 Script 组件可用的属性。有关功能和用法,请参阅优化脚本页面。

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

属性

以下是 Script 组件可用属性的摘要

属性示例类型必需
srcsrc="http://example.com/script"字符串除非使用内联脚本,否则为必填项
策略strategy="lazyOnload"字符串-
onLoadonLoad={onLoadFunc}函数-
onReadyonReady={onReadyFunc}函数-
onErroronError={onErrorFunc}函数-

必需属性

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

src

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

可选属性

<Script /> 组件除了必需的属性外,还接受许多其他属性。

strategy

脚本的加载策略。有四种不同的策略可以使用

  • beforeInteractive:在任何 Next.js 代码之前以及任何页面水合之前加载。
  • afterInteractive:(默认)尽早加载,但在页面发生部分水合之后。
  • lazyOnload:在浏览器空闲时间加载。
  • worker:(实验性)在 Web Worker 中加载。

beforeInteractive

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

标有此策略的脚本会预加载并在任何第一方代码之前获取,但其执行**不会阻止页面水合发生**。

`beforeInteractive` 脚本必须放置在 `Document` 组件 (`pages/_document.js`) 内部,并且旨在加载整个站点所需的脚本(即当应用程序中的任何页面在服务器端加载时,脚本将加载)。

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

pages/_document.js
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>
  )
}

**值得了解**:使用 `beforeInteractive` 的脚本无论在组件中放置在哪里,都将始终注入到 HTML 文档的 `head` 内部。

一些应尽快使用 `beforeInteractive` 获取的脚本示例包括

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

afterInteractive

使用 `afterInteractive` 策略的脚本会在客户端注入到 HTML 中,并在页面发生部分(或全部)水合后加载。**这是 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 策略尚不稳定,并且尚不支持 App Router。请谨慎使用。

使用 `worker` 策略的脚本会卸载到 Web Worker 中,以释放主线程并确保只有关键的第一方资源在主线程上处理。虽然此策略可用于任何脚本,但它是一种高级用例,不能保证支持所有第三方脚本。

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

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

`worker` 脚本**目前只能在 `pages/` 目录中使用**

pages/home.tsx
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 代码,以实例化内容或调用函数。如果您使用 `afterInteractive` 或 `lazyOnload` 作为加载策略加载脚本,则可以在脚本加载后使用 `onLoad` 属性执行代码。

这是一个仅在 Lodash 库加载后才执行其方法的示例。

app/page.tsx
'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 嵌入的示例。

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` 属性处理。

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`beforeInteractive` 和 `afterInteractive` 已修改以支持 `app`。
v12.2.4添加了 `onReady` 属性。
v12.2.2允许将带有 `beforeInteractive` 的 `next/script` 放置在 `_document` 中。
v11.0.0引入 `next/script`。