16 visitors

Using Google Analytics Data API in Next.js

2025-06-05

Next.jsGoogle AnalyticsData APITypeScript

Introduction

In this post, I'll share how I implemented the Google Analytics Data API in my Next.js portfolio website to fetch and display visitor analytics data.

Setting Up Google Analytics Data API

First, we need to set up the Google Analytics Data API and get the necessary credentials. Here's a step-by-step guide:

1. Set Up Google Analytics Data API

  1. Go to Google Cloud Console
  2. Create a new project or select an existing one
  3. Enable the Google Analytics Data API for your project
  4. Go to "APIs & Services" → "Credentials"
  5. Click "Create Credentials" → "Service Account"
  6. Fill in the service account details and click "Create"
  7. Click on the created service account → "Keys" → "Add Key" → "Create new key"
  8. Choose JSON format and download the key file
  9. Add the service account email to your Google Analytics property with "Viewer" permissions

2. Configure Environment Variables

Add the following variables to your .env.local file:
# Google Analytics Configuration
NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID=XXXXXXXXXX  # Your GA4 Property ID
NEXT_PUBLIC_GOOGLE_CLIENT_EMAIL=your-service-account@project.iam.gserviceaccount.com  # From service account JSON
NEXT_PUBLIC_GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
"  # From service account JSON

3. Install Required Dependencies

Install the necessary packages for Google Analytics Data API integration:
npm install @google-analytics/data
# or
yarn add @google-analytics/data
# or
pnpm add @google-analytics/data

4. Create Analytics Client

Create a client using the Google Analytics Data API:
import { BetaAnalyticsDataClient } from "@google-analytics/data";

const { private_key } = JSON.parse(
  process.env.NEXT_PUBLIC_GOOGLE_PRIVATE_KEY || "{ private_key: null }"
);

export const analyticsDataClient = new BetaAnalyticsDataClient({
  credentials: {
    client_email: process.env.NEXT_PUBLIC_GOOGLE_CLIENT_EMAIL!,
    private_key: private_key,
  },
});

5. Create API Route

Create an API route to fetch analytics data securely from the server side:
import { NextResponse } from "next/server";
import { analyticsDataClient } from "@/lib/google/client";

export async function GET() {
  try {
    const propertyId = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_PROPERTY_ID;
    if (!propertyId) {
      return NextResponse.json(
        { error: "Google Analytics Property ID is not configured" },
        { status: 500 }
      );
    }

    const [response] = await analyticsDataClient.runReport({
      property: `properties/${propertyId}`,
      dateRanges: [
        {
          startDate: "2024-06-30",
          endDate: "today",
        },
      ],
      metrics: [{ name: "totalUsers" }],
    });

    const metrics = response.rows?.[0]?.metricValues || [];
    const visitorCount = Number(metrics[0]?.value) || 0;

    return NextResponse.json({ visitorCount });
  } catch (error) {
    console.error("Error fetching analytics data:", error);
    return NextResponse.json(
      { error: "Failed to fetch analytics data" },
      { status: 500 }
    );
  }
}

6. Create Visitor Count Component

Create a component to display the visitor count in the UI:
import { useEffect, useState } from "react";
import { getUniqueVisitors } from "@/utils/analytics";
import { motion } from "framer-motion";
import { Users } from "lucide-react";

export default function VisitorCount() {
  const [visitorCount, setVisitorCount] = useState<number>(0);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchVisitors = async () => {
      try {
        const count = await getUniqueVisitors();
        setVisitorCount(count);
      } catch (error) {
        console.error("Failed to fetch visitor count:", error);
      } finally {
        setLoading(false);
      }
    };

    fetchVisitors();
    // Refresh count every 5 minutes
    const interval = setInterval(fetchVisitors, 5 * 60 * 1000);
    return () => clearInterval(interval);
  }, []);

  if (loading) {
    return (
      <div className="flex items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground">
        <Users className="h-4 w-4" />
        <span>Loading...</span>
      </div>
    );
  }

  return (
    <motion.div
      initial={{ opacity: 0, y: -10 }}
      animate={{ opacity: 1, y: 0 }}
      className="flex items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground"
    >
      <Users className="h-4 w-4" />
      <span>{visitorCount.toLocaleString()} visitors</span>
    </motion.div>
  );
}

Best Practices

When implementing Google Analytics Data API in a Next.js application, consider these best practices:
  • Use environment variables for sensitive credentials
  • Implement server-side data fetching for better security
  • Add proper error handling and loading states
  • Consider rate limiting and caching for API calls
  • Follow privacy regulations and add cookie consent if needed

Conclusion

Implementing Google Analytics Data API in a Next.js application provides valuable insights into user behavior and website performance. The combination of server-side data fetching and proper error handling offers a robust solution for analytics integration.

References