Integrating Third-Party Scripts in Next.js
Learn how to use next/script to integrate analytics and trackers into your Next.js project without harming your site performance or Core Web Vitals.
Previously in this course, we built an RSS feed for our blog. Now that our content is discoverable, it's time to understand how users interact with it. In this lesson, we’ll explore how to safely add third-party analytics and trackers to our Next.js application.
Why Standard HTML Scripts Fail
In standard web development, adding a <script> tag is straightforward: you drop it into the <head> or before the closing </body> tag. However, this is dangerous for performance.
Third-party scripts (analytics, chat widgets, ad trackers) are often heavy and execute on the main thread. If you load them improperly, they block the browser from parsing your HTML, rendering your CSS, or responding to user clicks. This often leads to poor Core Web Vitals, specifically impacting your LCP (Largest Contentful Paint) and INP (Interaction to Next Paint). As discussed in our deep dives on Core Web Vitals and INP optimization, we must control when and how these scripts load.
Introducing next/script
Next.js provides the next/script component, which acts as a wrapper around the native HTML <script> tag. It gives us fine-grained control over the loading priority, ensuring that critical content renders before the third-party noise begins.
Strategies for Loading
The strategy prop is the most important part of next/script. It dictates when the script executes:
| Strategy | Description | Best For |
|---|---|---|
beforeInteractive | Loads before the page becomes interactive. | Essential bots/cookies. |
afterInteractive | (Default) Loads as soon as possible after the page is interactive. | Analytics and tag managers. |
lazyOnload | Loads during idle time. | Non-critical widgets (e.g., chat, social feeds). |
worker | Offloads execution to a Web Worker (experimental). | Complex, heavy scripts. |
Worked Example: Adding Google Analytics
Let’s add a common analytics script to our blog. We'll place this in our root layout so it tracks every page view.
TSX// app/layout.tsx import Script from CE9178">'next/script'; export default function RootLayout({ children }) { return ( <html lang="en"> <body> {children} {/* Analytics Script */} <Script src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" strategy="afterInteractive" /> <Script id="google-analytics" strategy="afterInteractive"> {CE9178">` window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXXX'); `} </Script> </body> </html> ); }
In this example, we use afterInteractive. This ensures the script doesn't block the initial render of our blog posts, but still fires early enough to capture user data. Notice the use of an inline script block (the second Script component) to initialize the configuration—this is a standard pattern for many marketing tools.
Hands-on Exercise
- Identify a third-party service you want to use (e.g., Google Analytics, Plausible, or a simple custom tracking pixel).
- Open your
app/layout.tsxfile. - Import
Scriptfromnext/script. - Add your script using
strategy="afterInteractive". If it's a non-critical widget like a "Buy Me a Coffee" button, trystrategy="lazyOnload"to keep your site snappy. - Verify it's working by checking the "Network" tab in your browser's DevTools; you should see the script file loading after the page content.
Common Pitfalls
- Overloading the site: Just because you can add a script doesn't mean you should. Every script adds latency. Audit your tracking needs periodically.
- Forgetting the
id: When using inline scripts (as shown in the example), Next.js requires anidprop so it can track and optimize the execution of that specific block. - Blocking critical renders: Never use
beforeInteractiveunless the script is absolutely required to render the page (e.g., a bot-detection script or critical security header). For almost everything else,afterInteractiveorlazyOnloadis safer.
FAQ
Q: Can I use next/script in a Client Component?
Yes, but it is best practice to keep tracking scripts in the root layout.js so they aren't re-initialized every time the user navigates.
Q: How do I handle third-party performance issues? If a specific script is still causing issues, check out our guide on third-party script optimization using Partytown to offload execution to a background web worker.
Recap
We’ve learned that third-party scripts are a major source of performance degradation. By using next/script, we can defer non-essential code, protect our main thread, and ensure our blog remains fast. Always prioritize your user's experience over data collection.
Up next: We will learn how to handle multi-language support with Internationalization (i18n).
Work with me

Next.js Full-Stack Web App Development
A fast, SEO-ready full-stack web app built with Next.js 16 — from idea to deployed product, by an engineer who ships to production.

Next.js E-commerce Store Development
Turn your Facebook page or small shop into a real online store — fast, mobile-first, and built to sell. Own your storefront, not just a social page.
