Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply Next.js best practices for RSC boundaries, async APIs, routing, metadata, and optimization.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts.md
1# Scripts23Loading third-party scripts in Next.js.45## Use next/script67Always use `next/script` instead of native `<script>` tags for better performance.89```tsx10// Bad: Native script tag11<script src="https://example.com/script.js"></script>1213// Good: Next.js Script component14import Script from 'next/script'1516<Script src="https://example.com/script.js" />17```1819## Inline Scripts Need ID2021Inline scripts require an `id` attribute for Next.js to track them.2223```tsx24// Bad: Missing id25<Script dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />2627// Good: Has id28<Script id="my-script" dangerouslySetInnerHTML={{ __html: 'console.log("hi")' }} />2930// Good: Inline with id31<Script id="show-banner">32{`document.getElementById('banner').classList.remove('hidden')`}33</Script>34```3536## Don't Put Script in Head3738`next/script` should not be placed inside `next/head`. It handles its own positioning.3940```tsx41// Bad: Script inside Head42import Head from 'next/head'43import Script from 'next/script'4445<Head>46<Script src="/analytics.js" />47</Head>4849// Good: Script outside Head50<Head>51<title>Page</title>52</Head>53<Script src="/analytics.js" />54```5556## Loading Strategies5758```tsx59// afterInteractive (default) - Load after page is interactive60<Script src="/analytics.js" strategy="afterInteractive" />6162// lazyOnload - Load during idle time63<Script src="/widget.js" strategy="lazyOnload" />6465// beforeInteractive - Load before page is interactive (use sparingly)66// Only works in app/layout.tsx or pages/_document.js67<Script src="/critical.js" strategy="beforeInteractive" />6869// worker - Load in web worker (experimental)70<Script src="/heavy.js" strategy="worker" />71```7273## Google Analytics7475Use `@next/third-parties` instead of inline GA scripts.7677```tsx78// Bad: Inline GA script79<Script src="https://www.googletagmanager.com/gtag/js?id=G-XXXXX" />80<Script id="ga-init">81{`window.dataLayer = window.dataLayer || [];82function gtag(){dataLayer.push(arguments);}83gtag('js', new Date());84gtag('config', 'G-XXXXX');`}85</Script>8687// Good: Next.js component88import { GoogleAnalytics } from '@next/third-parties/google'8990export default function Layout({ children }) {91return (92<html>93<body>{children}</body>94<GoogleAnalytics gaId="G-XXXXX" />95</html>96)97}98```99100## Google Tag Manager101102```tsx103import { GoogleTagManager } from '@next/third-parties/google'104105export default function Layout({ children }) {106return (107<html>108<GoogleTagManager gtmId="GTM-XXXXX" />109<body>{children}</body>110</html>111)112}113```114115## Other Third-Party Scripts116117```tsx118// YouTube embed119import { YouTubeEmbed } from '@next/third-parties/google'120121<YouTubeEmbed videoid="dQw4w9WgXcQ" />122123// Google Maps124import { GoogleMapsEmbed } from '@next/third-parties/google'125126<GoogleMapsEmbed127apiKey="YOUR_API_KEY"128mode="place"129q="Brooklyn+Bridge,New+York,NY"130/>131```132133## Quick Reference134135| Pattern | Issue | Fix |136|---------|-------|-----|137| `<script src="...">` | No optimization | Use `next/script` |138| `<Script>` without id | Can't track inline scripts | Add `id` attribute |139| `<Script>` inside `<Head>` | Wrong placement | Move outside Head |140| Inline GA/GTM scripts | No optimization | Use `@next/third-parties` |141| `strategy="beforeInteractive"` outside layout | Won't work | Only use in root layout |142