跳到主要内容

Script 组件

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

app/dashboard/page.tsx
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"StringRequired unless inline script is used
strategystrategy="lazyOnload"String-
onLoadonLoad={onLoadFunc}Function-
onReadyonReady={onReadyFunc}Function-
onErroronError={onErrorFunc}Function-

必填 Props

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

src

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

可选 Props

<Script /> 组件接受许多超出必需属性的附加属性。

strategy

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

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

beforeInteractive

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

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

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

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

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

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>
)
}
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 路由一起工作。请谨慎使用。

使用 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 代码以实例化内容或调用函数。如果你使用 afterInteractivelazyOnload 作为加载策略加载脚本,可以使用 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 嵌入的示例:

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

版本历史

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