SaketSingh

How I Integrated Google Analytics into My Next.js Portfolio (The Simple Way)

👤Saket Singh
|
📅July 19, 2025
|
⏱️4 min read
How I Integrated Google Analytics into My Next.js Portfolio (The Simple Way)

Introduction

If you’re like me, building your personal portfolio isn’t just about showcasing projects-it’s also about understanding who’s visiting, where they’re coming from, and what they’re checking out.

For that, Google Analytics is still one of the simplest and most powerful tools out there.

When I set up analytics for my portfolio (built with Next.js App Router), I wanted two things:

  • A clean, minimal integration (no extra libraries unless absolutely needed)
  • Environment-based configuration (so analytics only runs in production)

Let me walk you through how I did it.


❓Why Add Google Analytics to Your Portfolio?

A lot of developers skip analytics on personal sites because they think:

“It’s just a portfolio, who cares about stats?”

But I believe in tracking the little wins too!

Even if it’s just to see if your latest blog post brought in some traffic, or if recruiters are spending time on your project pages.


⚙️ Setting Things Up: Google Analytics in Next.js (App Router)

Here’s the method I used - directly injecting the Google Analytics script into layout.tsx using Next.js Script component.

No external plugins. No fancy wrappers. Just straightforward code.


🪪 Step 1: Get Your Google Analytics ID

If you don’t have it yet:

It looks like:

  G-XXXXXXXXXX

📂 Step 2: Store the Analytics ID in .env

In your .env.local (for local development) and Vercel environment variables (for production):

  NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX

Using NEXT_PUBLIC_ makes the variable accessible on the client side. That’s important because the Google Analytics script runs in the browser.

🧩 Step 3: Inject the Script in layout.tsx

Here’s exactly how I did it:

import { Inter } from "next/font/google";
import Script from "next/script";
import ClientWrapper from "@/components/Common/ClientWrapper"; 

const inter = Inter({ subsets: ["latin"] });

const GA_ID = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID!;

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        
        {/* Google Analytics Script */}
        <Script
          strategy="afterInteractive"
          src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`}
        />
        
        <Script
          id="google-analytics"
          strategy="afterInteractive"
          dangerouslySetInnerHTML={{
            __html: `
              window.dataLayer = window.dataLayer || [];
              function gtag(){dataLayer.push(arguments);}
              gtag('js', new Date());
              gtag('config', '${GA_ID}', {
                page_path: window.location.pathname,
              });
            `,
          }}
        />
      </head>
      <body className={`dark:bg-black ${inter.className}`}>
        <ClientWrapper>{children}</ClientWrapper>
      </body>
    </html>
  );
}


🚀 Why Use next/script?

  • strategy="afterInteractive" ensures the script loads after the page is interactive, so it doesn’t block rendering.
  • Using dangerouslySetInnerHTML is safe here because this is the exact snippet Google provides. No user-generated content is involved.

🔒 Step 4: Keep It Production-Only (Optional)

Since you’ve set the Analytics ID via environment variables, this code is already safe for production use.

In local development, if NEXT_PUBLIC_GOOGLE_ANALYTICS_ID is missing, Google Analytics simply won’t load. No extra checks are needed.

☁️ Step 5: Push to Vercel

In Vercel:

  • Go to your project dashboard
  • Open Settings → Environment Variables
  • Add:
  NEXT_PUBLIC_GOOGLE_ANALYTICS_ID=G-XXXXXXXXXX

Now when you deploy, your site automatically uses the production GA ID.

🎯 The Result?

  • Minimal code
  • No third-party wrappers
  • Analytics works seamlessly across all routes (thanks to placing it in layout.tsx)

💡 Final Thoughts: Keep It Simple

  • A lot of blogs will tell you to install next-ga, react-ga, or other wrappers.
  • For a portfolio site, that’s usually overkill.
  • If you’re using Next.js App Router, injecting the GA script in layout.tsx is the cleanest approach.

🔍 What’s Next?

Once you’ve set up analytics, check out:

  • Google Analytics Realtime Dashboard
  • See which blog posts or projects get attention
  • Use the data to improve your content
Google Analytics Integration in Next.js Portfolio

Happy building! 🚀


Tags

#Google Analytics#Nextjs#Web Development
Share this post: