C.W.K.
Stream
Lesson 07 of 08 · published

next/script

~18 min · next/script, loading strategy, third-party

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Pick the loading strategy on purpose

StrategyWhen it loadsUse case
beforeInteractiveBefore hydrationCritical: bot detection, consent banners
afterInteractive (default)After hydrationAnalytics, tag managers
lazyOnloadDuring idle timeChat widgets, social embeds
workerIn a web workerHeavy compute that shouldn't block main thread

One rule

beforeInteractive is allowed only inside the root layout (it injects into the document head). Anywhere else it's a runtime error.

Code

Three loading strategies in one layout·tsx
import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>
        {children}

        {/* analytics — after hydration */}
        <Script
          src="https://www.googletagmanager.com/gtag/js?id=G-XXXXX"
          strategy="afterInteractive"
        />

        {/* chat widget — during idle */}
        <Script
          src="https://widget.intercom.io/widget/abc123"
          strategy="lazyOnload"
        />

        {/* inline init — must be after the gtag script */}
        <Script id="gtag-init" strategy="afterInteractive">
          {`window.dataLayer = window.dataLayer || [];
            function gtag(){ dataLayer.push(arguments); }
            gtag('js', new Date());
            gtag('config', 'G-XXXXX');`}
        </Script>
      </body>
    </html>
  );
}

External links

Exercise

Audit a real Next.js app's third-party scripts. Reclassify any that don't need afterInteractive as lazyOnload and measure the impact on Time to Interactive.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.