Third-party scripts — analytics, chat widgets, ad tags — are a common source of slow, janky pages if loaded carelessly. next/script gives you explicit control over when each script loads relative to the rest of the page.
Controlling Script Loading with a Strategy
A plain <script> tag in the <head> blocks the browser from rendering the rest of the page until it downloads and executes, which is rarely what you want for non-critical third-party code. next/script's strategy prop lets you explicitly choose when a script should load relative to the page's own content.
Choosing the right strategy per script — rather than loading everything eagerly — is one of the simpler, highest-leverage performance wins available in a Next.js app with several third-party integrations.
import Script from "next/script";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
{children}
<Script
src="https://analytics.example.com/script.js"
strategy="afterInteractive"
/>
</>
);
}
afterInteractive loads this analytics script only after the page has become interactive, avoiding any render-blocking impact.
Available Loading Strategies
strategy="beforeInteractive" // loads before any page content is interactive
strategy="afterInteractive" // loads right after the page becomes interactive (default)
strategy="lazyOnload" // loads during idle time, well after everything else
strategy="worker" // (experimental) runs off the main thread via a web worker
beforeInteractive should be reserved for scripts truly required before anything else, like bot detection.
afterInteractive is the default and right choice for most analytics and tag manager scripts.
lazyOnload is ideal for low-priority scripts like chat widgets or non-critical ads.
Choosing the least aggressive strategy that still meets the script's actual requirement improves performance.
Script Strategy Cheat Sheet
Which strategy fits which type of script.
Script Type
Recommended Strategy
Bot/fraud detection (rare)
beforeInteractive
Analytics (Google Analytics, etc.)
afterInteractive
Tag managers
afterInteractive
Chat widgets
lazyOnload
Non-critical ads
lazyOnload
Inline Scripts and onLoad Handlers
next/script also supports inline script content and lifecycle event handlers like onLoad, useful for running code that depends on a third-party script finishing initialization.
Placing a <Script> in a layout used by many nested routes ensures the script loads once for that section, rather than being duplicated if it were placed in every individual page — Next.js also deduplicates identical script tags automatically across navigations.
Common Mistakes
Using a plain <script> tag instead of next/script, losing control over loading strategy.
Defaulting every third-party script to beforeInteractive, blocking meaningful content unnecessarily.
Placing the same script in multiple pages instead of a shared layout, risking duplicate loads.
Not using onLoad when code genuinely needs to run only after a script has finished initializing.
Key Takeaways
next/script gives explicit control over third-party script loading via the strategy prop.
afterInteractive is the default and fits most analytics and tag manager use cases.
lazyOnload is best for low-priority widgets that shouldn't compete with page content for resources.
beforeInteractive should be reserved for scripts genuinely required before interactivity.
Placing shared scripts in a layout avoids duplication across nested routes.
Pro Tip
Audit every third-party script currently loaded eagerly in your app and ask, honestly, whether it needs to block anything — most analytics and marketing scripts have no real dependency on loading before the page is interactive, and moving them to afterInteractive or lazyOnload is often a five-minute change with a real, measurable performance benefit.
You now understand script optimization. Next, learn bundle analysis — how to actually measure your app's client-side JavaScript size.