Next.js
Integrating Third-Party Scripts Safely (GTM, Analytics, Pixels)
How to load GTM, analytics, and tracking pixels in Next.js without hurting performance or blocking the main thread.

Third-party scripts (GTM, analytics, ads) are often heavy and blocking. In Next.js you can load them in a controlled way so they don’t delay LCP or block interaction.
next/script and strategy
Use the Next.js Script component instead of a raw <script> tag. The strategy prop controls when the script loads. afterInteractive (default) runs after the page becomes interactive; lazyOnload defers until the browser is idle. For analytics and tags, afterInteractive or lazyOnload keeps them off the critical path. Reserve beforeInteractive for scripts that must run before hydration (e.g. feature detection or polyfills); use it sparingly.
// app/layout.tsx
import Script from "next/script";
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-XXX"
strategy="afterInteractive"
/>
<Script id="gtag-config" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-XXX');
`}
</Script>
</body>
</html>
);
}Put scripts that don’t affect initial render at the end of the body and use afterInteractive or lazyOnload so they don’t compete with your own JS.
GTM and consent
If you use a tag manager (GTM), load the GTM script with afterInteractive or lazyOnload. Fire tags (analytics, pixels) from inside GTM based on consent or events. That way you have one script to manage and you avoid loading multiple analytics scripts separately. If you need consent before any tracking, gate the GTM container load or the config call on the user’s choice and load the script only after consent.
Limiting impact
Even with deferred loading, third-party code can still slow the main thread. Prefer a single tag manager over many separate scripts. Use GTM’s built-in triggers and delays so heavy tags don’t run on first paint. Consider loading some pixels or analytics only on specific routes (e.g. thank-you page) by conditionally rendering the Script component. Monitor Core Web Vitals; if a script hurts INP or LCP, move it to lazyOnload or load it only when the user interacts (e.g. after first click or scroll).
Summary
Use next/script with afterInteractive or lazyOnload for GTM, analytics, and pixels. Prefer one tag manager and gate tracking on consent where required. Keep third-party scripts off the critical path and monitor their impact so they integrate safely without hurting performance.