Menu

<Script>

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

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

属性

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

属性示例类型是否必需
srcsrc="http://example.com/script"String除非使用内联脚本,否则必需
strategystrategy="lazyOnload"String-
onLoadonLoad={onLoadFunc}Function-
onReadyonReady={onReadyFunc}Function-
onErroronError={onErrorFunc}Function-

必需属性

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

src

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

可选属性

<Script /> 组件除了必需属性外,还接受一些额外的属性。

strategy

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

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

beforeInteractive

使用 beforeInteractive 策略加载的脚本会被注入到服务器返回的初始 HTML 中,在任何 Next.js 模块之前下载,并按照它们放置的顺序在页面上发生 任何 水合之前执行。

使用这种策略的脚本会在任何第一方代码之前被预加载和获取,但它们的执行不会阻止页面水合的发生。

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

这种策略应该只用于那些需要在页面的任何部分变为可交互之前获取的关键脚本。

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>
  );
}
app/layout.js
import Script from "next/script";
 
export default function RootLayout({ children }) {
  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 中,并在页面上发生一些 (或全部) 水合之后加载。这是 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 目录一起使用。请谨慎使用。

使用 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" />
    </>
  );
}
pages/home.js
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]));
        }}
      />
    </>
  );
}
app/page.js
"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 嵌入:

app/page.tsx
"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,
          });
        }}
      />
    </>
  );
}
app/page.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 属性来处理:

app/page.tsx
"use client";
 
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error("脚本加载失败", e);
        }}
      />
    </>
  );
}
app/page.js
"use client";
 
import Script from "next/script";
 
export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error("脚本加载失败", e);
        }}
      />
    </>
  );
}

版本历史

版本变更
v13.0.0修改了 beforeInteractiveafterInteractive 以支持 app 目录。
v12.2.4添加了 onReady 属性。
v12.2.2允许在 _document 中放置带有 beforeInteractivenext/script
v11.0.0引入了 next/script