要为多个路由加载第三方脚本,请导入 next/script 并将脚本直接包含在您的布局组件中:
import Script from 'next/script'
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<section>{children}</section>
<Script src="https://example.com/script.js" />
</>
)
}import Script from 'next/script'
export default function DashboardLayout({ children }) {
return (
<>
<section>{children}</section>
<Script src="https://example.com/script.js" />
</>
)
}当用户访问文件夹路由(例如 dashboard/page.js)或任何嵌套路由(例如 dashboard/settings/page.js)时,会获取第三方脚本。Next.js 将确保脚本只加载一次,即使同一布局中的用户在多个路由之间导航也是如此。
要为所有路由加载第三方脚本,请导入 next/script 并将脚本直接包含在您的根布局中:
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" />
</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" />
</html>
)
}要为所有路由加载第三方脚本,请导入 next/script 并将脚本直接包含在您的自定义 _app 中:
import Script from 'next/script'
export default function MyApp({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<Script src="https://example.com/script.js" />
</>
)
}当您的应用程序中的_任何_路由被访问时,此脚本都将加载并执行。Next.js 将确保脚本只加载一次,即使同一用户在多个页面之间导航也是如此。
建议:我们建议只在特定的页面或布局中包含第三方脚本,以最大程度地减少对性能不必要的冲击。
尽管 next/script 的默认行为允许您在任何页面或布局中加载第三方脚本,但您可以使用 strategy 属性来微调其加载行为:
beforeInteractive: 在任何 Next.js 代码之前以及任何页面水合作用发生之前加载脚本。afterInteractive: (默认)尽早加载脚本,但在页面发生部分水合作用之后。lazyOnload: 在浏览器空闲时稍后加载脚本。worker: (实验性)在 Web Worker 中加载脚本。请参阅 next/script API 参考文档,以了解每种策略及其用例。
警告:
worker策略尚未稳定,并且尚不支持 App Router。请谨慎使用。
使用 worker 策略的脚本将与 Partytown 一起卸载并在 Web Worker 中执行。这可以通过将主线程专用于应用程序的其余代码来提高站点的性能。
此策略仍处于实验阶段,仅当在 next.config.js 中启用 nextScriptWorkers 标志时才能使用:
module.exports = {
experimental: {
nextScriptWorkers: true,
},
}然后,运行 next(通常是 npm run dev 或 yarn dev),Next.js 将指导您安装所需的包以完成设置:
npm run dev您将看到如下说明:Please install Partytown by running npm install @builder.io/partytown
设置完成后,定义 strategy="worker" 将自动在您的应用程序中实例化 Partytown 并将脚本卸载到 Web Worker。
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" />
</>
)
}在 Web Worker 中加载第三方脚本时,需要考虑许多权衡。请参阅 Partytown 的 tradeoffs 文档以获取更多信息。
尽管 worker 策略不需要任何额外的配置即可工作,但 Partytown 支持使用配置对象来修改其部分设置,包括启用 debug 模式以及转发事件和触发器。
如果您想添加额外的配置选项,可以将其包含在 自定义 _document.js 中使用的 <Head /> 组件内:
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html>
<Head>
<script
data-partytown-config
dangerouslySetInnerHTML={{
__html: `
partytown = {
lib: "/_next/static/~partytown/",
debug: true
};
`,
}}
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}要修改 Partytown 的配置,必须满足以下条件:
data-partytown-config 属性才能覆盖 Next.js 使用的默认配置。lib: "/_next/static/~partytown/" 属性和值,以便让 Partytown 知道 Next.js 存储必要静态文件的位置。注意:如果您正在使用 asset prefix 并希望修改 Partytown 的默认配置,则必须将其作为
lib路径的一部分。
请查看 Partytown 的 configuration options 以查看可以添加的其他属性的完整列表。
内联脚本,即未从外部文件加载的脚本,也受 Script 组件支持。它们可以通过将 JavaScript 放在花括号内来编写:
<Script id="show-banner">
{`document.getElementById('banner').classList.remove('hidden')`}
</Script>或者通过使用 dangerouslySetInnerHTML 属性:
<Script
id="show-banner"
dangerouslySetInnerHTML={{
__html: `document.getElementById('banner').classList.remove('hidden')`,
}}
/>警告:内联脚本必须分配一个
id属性,以便 Next.js 跟踪和优化脚本。
Script 组件可以使用事件处理程序在特定事件发生后执行额外代码:
onLoad: 脚本加载完成后执行代码。onReady: 脚本加载完成后以及组件每次挂载时执行代码。onError: 如果脚本加载失败则执行代码。这些处理程序仅在 next/script 被导入并用于 客户端组件 内部时才有效,其中 "use client" 被定义为代码的第一行:
'use client'
import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
onLoad={() => {
console.log('Script has loaded')
}}
/>
</>
)
}'use client'
import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
onLoad={() => {
console.log('Script has loaded')
}}
/>
</>
)
}请参阅 next/script API 参考,以了解每个事件处理程序并查看示例。
这些处理程序仅在 next/script 被导入并用于 客户端组件 内部时才有效,其中 "use client" 被定义为代码的第一行:
import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
onLoad={() => {
console.log('Script has loaded')
}}
/>
</>
)
}import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
onLoad={() => {
console.log('Script has loaded')
}}
/>
</>
)
}请参阅 next/script API 参考,以了解每个事件处理程序并查看示例。
有许多 DOM 属性可以分配给 <script> 元素,而这些属性不被 Script 组件使用,例如 nonce 或 custom data attributes。包含任何附加属性都将自动将其转发到 HTML 中包含的最终优化 <script> 元素。
import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
id="example-script"
nonce="XUENAJFW"
data-test="script"
/>
</>
)
}import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
id="example-script"
nonce="XUENAJFW"
data-test="script"
/>
</>
)
}import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
id="example-script"
nonce="XUENAJFW"
data-test="script"
/>
</>
)
}import Script from 'next/script'
export default function Page() {
return (
<>
<Script
src="https://example.com/script.js"
id="example-script"
nonce="XUENAJFW"
data-test="script"
/>
</>
)
}