Skip to main content
The Script component provides optimized loading strategies for third-party scripts (analytics, ads, widgets) with control over when and how they execute.

Import

Basic Usage

API Reference

Props

string
Script source URL.
'beforeInteractive' | 'afterInteractive' | 'lazyOnload' | 'worker'
default:"'afterInteractive'"
Loading strategy that controls when the script executes.
  • beforeInteractive — Load before page becomes interactive (SSR output)
  • afterInteractive — Load after page becomes interactive (default)
  • lazyOnload — Load during idle time (after window.load)
  • worker — Load in a web worker (requires Partytown)
(e: Event) => void
Callback invoked when the script has loaded.
() => void
Callback invoked when the script is ready.Called after onLoad, and also on every re-render if the script is already loaded.
(e: Event) => void
Callback invoked when the script fails to load.
string
Unique identifier for the script (prevents duplicate loading).
string
Inline script content.
{ __html: string }
Alternative to children for inline scripts.

Standard Script Attributes

All standard <script> attributes are supported:
string
Script MIME type (e.g., "module", "text/partytown").
boolean
Load script asynchronously.
boolean
Defer script execution.
string
CORS setting ("anonymous" or "use-credentials").
string
Nonce for Content Security Policy.
string
Subresource Integrity hash.

Loading Strategies

beforeInteractive

Load the script before the page becomes interactive. Rendered in SSR output. Use for:
  • Critical polyfills
  • Feature detection scripts
  • Scripts that must run before React hydration
Only works in app/layout.tsx or pages/_document.tsx. Ignored elsewhere.

afterInteractive (Default)

Load the script after the page becomes interactive. Use for:
  • Analytics scripts
  • Tag managers
  • Chat widgets

lazyOnload

Load the script during idle time (after window.load + requestIdleCallback). Use for:
  • Non-critical scripts
  • Ads
  • Social media widgets
  • Anything that can wait

worker (Partytown)

Load the script in a web worker using Partytown. Use for:
  • Heavy analytics scripts
  • Anything that blocks the main thread
Requires Partytown setup. Sets type="text/partytown" on the script tag.

Examples

Google Analytics

Facebook Pixel

External SDK

Inline Configuration

Deduplication

Scripts with the same id or src are only loaded once:

SSR Behavior

  • beforeInteractive: Rendered in SSR HTML output
  • afterInteractive: Not rendered (injected client-side)
  • lazyOnload: Not rendered (injected client-side)
  • worker: Not rendered (injected client-side)

Performance

Impact on Core Web Vitals

Best Practices

  1. Use lazyOnload for non-critical scripts
  2. Minimize beforeInteractive usage (blocks hydration)
  3. Use worker for heavy analytics (requires Partytown)
  4. Always provide id for inline scripts (enables deduplication)
  5. Avoid blocking the main thread

Limitations

beforeInteractive placement: Only works in app/layout.tsx or pages/_document.tsx. Silently ignored in page components.
No SSR execution: Inline scripts do not execute during SSR. Use them for browser-only code.
CSP nonces: If using CSP, pass nonce to all inline scripts.

Migration from HTML script tag

Source

View source code → Implementation: /home/daytona/workspace/source/packages/vinext/src/shims/script.tsx