Capítulo 369 de 456

Script

Core Idea

next/script optimizes loading of third-party scripts by controlling exactly when they execute relative to hydration.

Key Concepts

  • src: required unless using an inline script.
  • strategy: beforeInteractive, afterInteractive (default), lazyOnload, worker (experimental).
  • beforeInteractive: injected in initial HTML, executed before any Next.js code; must live in pages/_document.js.
  • afterInteractive: loads after some hydration; default, usable in any page/layout.
  • lazyOnload: loads during browser idle time; for low-priority scripts.
  • worker: offloads to a web worker (needs experimental.nextScriptWorkers in next.config.js; Pages Router only, not App Router).
  • onLoad / onReady / onError: callbacks after load, after every mount, and on load failure respectively; only work in Client Components, not usable with beforeInteractive (except onReady, which also can't be used with Server Components).

Code Examples

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>
  )
}
  • O que demonstra: beforeInteractive scripts must go in _document.js and always inject into <head>.

Reference Tables

PropTypeRequired
srcStringrequired unless inline
strategyString-
onLoadFunction-
onReadyFunction-
onErrorFunction-

Anti-patterns

  • beforeInteractive for non-critical scripts: blocks nothing but delays hydration priority; reserve for bot detectors/cookie consent only.
  • onLoad with beforeInteractive: unsupported combination; use onReady instead.
  • worker strategy in production without testing: still experimental and not App Router compatible.

Key Takeaways

  1. Pick strategy by urgency: critical → beforeInteractive, needed soon → afterInteractive, deferrable → lazyOnload.
  2. Only beforeInteractive scripts must be in _document.js; the rest can live in any page/layout and load only when that page mounts.
  3. onLoad/onReady/onError require Client Components ('use client').

Connects To

  • instrumentation.js: another server-lifecycle hook, but for observability rather than client scripts.
  • _document.js (Pages Router): the only valid home for beforeInteractive scripts.