Dan Stroot

Google Analytics API

Using Google Analytics API to get page data.

Date:


Let's assume you have Google Analytics setup for your account and you want to display your analytics in your application like this. Well Google has an API you can use.

You can call this API from a Next API as follows:

1

Create a Google Service Account

  • Go to Google Developer Console and create a new project if you haven't already.
  • On the sidebar click on Credentials and then Create Credentials
  • Select Service Account as the credential type.
  • Go back to the Credentials page and select Service Accounts
  • Select Keys tab and then Add Key then create a JSON key
  • Download and keep this JSON key safe.
2

Enable the Google Analytics Data API

  • On the sidebar click on APIs & Services and ENABLE APIS AND SERVICES
  • Search for Google Analytics Data API and enable it
  • Go to Analytics dashboard and click on Admin -> Property User Management -> Add Users
  • Add your service account email address (look in the JSON key for the email) and give it Read and Analyze access.

This may be a little confusing but you are just granting the service account you just created access to the Google Analytics Data API so you can use it in your Next app.

3

Install the @google-analytics/data package

  • npm install @google-analytics/data or yarn add @google-analytics/data
  • Set the client_email, client_id and private_key as env variables in your .env.local file
4

Get the Data (create a Next API)

analytics.js
import { BetaAnalyticsDataClient } from '@google-analytics/data'
 
export default async function handler(req, res) {
  const analyticsDataClient = new BetaAnalyticsDataClient({
    credentials: {
      client_email: process.env.ANALYTICS_CLIENT_EMAIL,
      private_key: process.env.ANALYTICS_PRIVATE_KEY.replace(/\\n/g, '\n'),
    },
    projectId: process.env.ANALYTICS_PROJECT_ID,
  })
 
  const propertyId = PROPERTY_ID // place your property id here available in analytics console.
  let today = new Date().getTime() - 60 * 60 * 24 * 60 * 1000
  let day = new Date(today).getDate()
  let month = new Date(today).getMonth() + 1
  let year = new Date(today).getFullYear()
 
  let dayFormat = `${year}-${month}-${day}`
 
  const totalReport = await analyticsDataClient.runReport({
    property: 'properties/' + propertyId,
    dateRanges: [
      {
        startDate: dayFormat,
        endDate: 'today',
      },
    ],
 
    metrics: [
      {
        name: 'screenpageViews',
      },
      {
        name: 'engagementRate',
      },
      {
        name: 'totalUsers',
      },
    ],
  })
 
  return res.status(200).json({
    pageViews: totalReport[0].rows[0].metricValues[0].value,
    engagmentRate: totalReport[0].rows[0].metricValues[1].value,
    totalUsers: totalReport[0].rows[0].metricValues[2].value,
  })
}
5

Show the Data

Here's the exact React component I used as linked above. The markup is styled using Tailwindcss so that may look unfamiliar, but we just call the Next API using useSWR (which calls the Google Analytics API) and then we show Page Views, Engagement and Users.

stats.jsx
import millify from 'millify'
import useSWR from 'swr'
 
export const Stats = () => {
  const fetcher = (...args) => fetch(...args).then((res) => res.json())
  const { data: stats } = useSWR('/api/stats', fetcher)
 
  return (
    <div className="mx-5 flex flex-col">
      <h1 className="my-8 text-center text-4xl font-bold leading-tight tracking-tighter md:text-left md:text-6xl md:leading-none lg:text-7xl">
        Analytics
      </h1>
 
      <div className="mb-6 grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
        {/* Views */}
        <div className="relative flex w-full flex-col items-center space-y-5 rounded bg-gray-100 p-5 shadow-lg dark:bg-gray-800">
          <h1 className="text-2xl font-black">Page Views</h1>
          <span className="text-5xl font-black">
            {!stats ? '-' : millify(stats.pageViews)}
          </span>
        </div>
        {/* Engagement */}
        <div className="flex w-full flex-col items-center space-y-5 rounded bg-gray-100 p-5 shadow-lg dark:bg-gray-800">
          <h1 className="text-2xl font-black">Engagement Rate</h1>
          <span className="text-5xl font-black">
            {!stats ? '-' : (stats.engagmentRate * 100).toFixed(0) + '%'}
          </span>
        </div>
        {/* Users */}
        <div className="flex w-full flex-col items-center space-y-5 rounded bg-gray-100 p-5 shadow-lg dark:bg-gray-800">
          <h1 className="text-2xl font-black">Total Users</h1>
          <span className="text-5xl font-black">
            {!stats ? '-' : millify(stats.totalUsers)}
          </span>
        </div>
      </div>
    </div>
  )
}

Sharing is Caring

Edit this page