How to add Google Analytics 4 to a Next.js site
Add GA4 to a Next.js App Router site with the official @next/third-parties package or next/script, keep the ID in an environment variable, and track signups.
The simplest way to add Google Analytics 4 to Next.js is the official @next/third-parties package: install it, then add <GoogleAnalytics gaId="G-…" /> to your root layout. Page changes are counted automatically by GA4's enhanced measurement, so you don't need any routing code.
1. Install the package
npm install @next/third-parties2. Add the ID to your environment
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXXAdd it to your hosting provider's environment variables too (on Vercel: Project → Settings → Environment Variables), then redeploy.
3. Add GoogleAnalytics to the root layout
import { GoogleAnalytics } from "@next/third-parties/google";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
{process.env.NEXT_PUBLIC_GA_ID ? (
<GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_ID} />
) : null}
</html>
);
}The component loads Google's tag after the page is interactive, so it doesn't slow down the first paint. Without the variable (for example in local development), nothing is loaded.
Without the package: next/script
If you'd rather not add a dependency, load the tag with next/script:
import Script from "next/script";
const GA_ID = process.env.NEXT_PUBLIC_GA_ID;
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
{GA_ID ? (
<>
<Script src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`} strategy="afterInteractive" />
<Script id="ga4" strategy="afterInteractive">
{`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_ID}');`}
</Script>
</>
) : null}
</body>
</html>
);
}Page changes in the App Router
Navigating with <Link> doesn't reload the page, but GA4 still counts it: enhanced measurement sends a page view when the browser's history changes. Check it's on in GA4: Admin → Data streams → your stream → Enhanced measurement → Page views → Page changes based on browser history events.
Track a signup
In a client component, after the signup succeeds, use the package's sendGAEvent:
"use client";
import { sendGAEvent } from "@next/third-parties/google";
// after the server confirms the signup:
sendGAEvent("event", "sign_up", { method: "Email" });With the next/script setup instead, call window.gtag("event", "sign_up", { method: "Email" }). Then mark sign_up as a key event.
Pages Router
In pages/_app.tsx, render <GoogleAnalytics gaId={…} /> (from the same package) next to <Component {...pageProps} />.
Check it works
Deploy, open your site and look at GA4's Realtime overview, or filter your browser's network tab for collect. More ways to check.
Related
Sources
- Next.js: Third-party libraries: Google Analytics
- Google: Enhanced measurement events
Last updated
Cross-domain
When your site and your app or shop are on different domains, set up GA4 cross-domain measurement so one visit isn't counted as two. Subdomains need nothing.
Framer
Add GA4 to your Framer site by pasting your G- Measurement ID into Framer's Site Settings, then publish and check visits arrive in GA4's Realtime report.