New: SEO Blog Writer, a readable, checked blog post for your site every week. Pay once, download straight away.

See it
AI Skill Up
Browse skills

How to add Google Analytics 4 to a Next.js site

The shortest correct way to add GA4 to Next.js, with the official third-parties component or next/script, how route changes count, and how to check it works.

Adding Google Analytics 4 to Next.js takes a few lines. Most of the trouble comes afterwards: double-counted page views, the tag loading in development, and not knowing whether it works. This is the setup that avoids those.

App Router, with the official component

// app/layout.tsx
import { GoogleAnalytics } from "@next/third-parties/google";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
      {process.env.NEXT_PUBLIC_GA_ID && (
        <GoogleAnalytics gaId={process.env.NEXT_PUBLIC_GA_ID} />
      )}
    </html>
  );
}

Install @next/third-parties, set NEXT_PUBLIC_GA_ID to your G- ID in production only, and the tag loads after hydration. Leaving the variable unset in development keeps your own testing out of the data. Where to find the ID is in the GA4 measurement ID.

Pages Router, or without the package

// pages/_app.tsx
import Script from "next/script";
const id = process.env.NEXT_PUBLIC_GA_ID;

<Script src={`https://www.googletagmanager.com/gtag/js?id=${id}`} strategy="afterInteractive" />
<Script id="ga" strategy="afterInteractive">{`
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag("js", new Date());
  gtag("config", "${id}");
`}</Script>

Route changes

Next.js navigates without full page loads. GA4 handles that through enhanced measurement: under the web stream's settings, page views include page changes based on browser history events, on by default. Do not also send page_view manually on route change, or every navigation counts twice. GA4 on a single page app has the details.

Consent

If you have visitors in the EEA or UK, set consent defaults before the config call. Consent mode v2 shows the lines.

Check it works

  1. Deploy, open the site, and look for a request to google-analytics.com/g/collect in the network tab.
  2. Open GA4's Realtime report; your visit should appear within a minute.
  3. For event detail, use DebugView, covered in GA4 DebugView.

GA4 + Search Console Setup does this for Next.js and ten other frameworks: it puts the tag in the right file with consent defaults, creates the property and stream in your own Chrome if you connect Claude in Chrome, and checks the tag is live after you deploy.

Questions

What is the easiest way to add GA4 to Next.js?

The GoogleAnalytics component from @next/third-parties/google, placed in the root layout with your measurement ID. It loads gtag after the page is interactive.

Does GA4 track page changes in a Next.js app?

Yes, if enhanced measurement's page changes based on browser history events option is on, which it is by default. Client-side navigations then send page views without extra code.

Should the measurement ID be an environment variable?

It is convenient, for example NEXT_PUBLIC_GA_ID, so that preview and production can differ. It is not a secret; it appears in your page source either way.

Or skip the afternoonand drop one in.