Setting up Google Analytics in Next.js without _app.js and _document.js files

I’m having trouble getting Google Analytics to work properly in my Next.js project. My app doesn’t use the traditional _app.js or _document.js files, and when I try to add the tracking script to my main layout component, it won’t load on the actual pages.

Here’s what my main layout file looks like:

import "./styles/global.css";
import { Roboto } from "next/font/google";
import Navigation from "@/components/layout/navigation";
import Head from "next/head";

const roboto = Roboto({
  subsets: ["latin"],
  variable: "--font-roboto",
  display: "swap",
});

export const metadata = {
  title: "My App",
  description: "Built with Next.js",
};

export default function MainLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <Head>
        <meta charSet="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>{metadata.title}</title>
        <meta name="description" content={metadata.description} />
        <link rel="icon" href="/favicon.ico" />
        
        {/* Analytics Setup */}
        <script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
        <script
          dangerouslySetInnerHTML={{
            __html: `
              window.dataLayer = window.dataLayer || [];
              function gtag(){dataLayer.push(arguments);}
              gtag('js', new Date());
              gtag('config', 'GA_MEASUREMENT_ID');
            `,
          }}
        />
      </Head>
      <body className={`${roboto.variable} font-roboto bg-gray-50 text-slate-800`}>
        <div className="min-h-screen flex flex-col">
          <Navigation />
          <main className="flex-1">
            {children}
          </main>
        </div>
      </body>
    </html>
  );
}

I put the analytics code inside the Head component but when I check the browser dev tools or use Google’s tag helper extension, the tracking script isn’t there. My folder structure looks like this:

- app
  - (main)
    - layout.tsx
  - components
    - layout
    - shared
- pages  
  - page.tsx
- public
- styles

I expected the analytics script to appear in the document head but it’s not working. What’s the right way to add Google Analytics tracking to this kind of Next.js setup?

you’re using app router, but the Head component doesn’t work there - that’s for pages router. drop the script tags directly into your html without the Head wrapper, or better yet, use next/script with strategy=“beforeInteractive”. that’s fixed my loading issues every time.

Your main issue is mixing Next.js 13 App Router with the old Pages Router approach. You’re using App Router structure but trying to use the Head component in a layout - that won’t work. Since you’re already using App Router with metadata export, handle analytics differently. Move your Google Analytics script tags directly into your root layout’s HTML structure without the Head component wrapper. App Router manages document head through metadata and direct script placement. You’ve got a few options: add scripts to a custom head.tsx in your app directory, or use Next.js Script component with beforeInteractive strategy in your layout. I’d go with the Script component - it’s more reliable for tracking since you get better control over when scripts load. Your folder structure screams App Router, so stick with that instead of mixing approaches.