Create a Dashboard with Next.js API Routes - Google Analytics API

LR

Lee Robinson / February 18, 2020

4 min read––– views

In this series, you will learn how to create a dashboard using Next.js API routes and integrate with third-party APIs.

All-Time Views

-

Overview#

Google Analytics is, by far, the most popular analytics platform. In this post, we'll look at how we can retrieve the number of page views in a specific time range programmatically.

If you're more concerned about privacy, you might consider using Fathom or SimpleAnalytics.

Note: You'll need to turn off your ad blocker for this page to work.

Getting Access to Google Analytics#

To gain access to the Google Analytics API, you need to:

  • Go to the Google Developer Console.
  • Create a new project.
  • Credentials -> Create Credentials -> Service-account key.
  • Click “Enable APIs and services.”
  • Find "Google Analytics API" and enable it.

Since we're communicating server-to-server, we'll need a service account.

  • Go to your service accounts page.
  • Create a service account.
  • Click "Create Key" and choose JSON.

You should now have a JSON file similar to this:

{
  "type": "service_account",
  "project_id": "...",
  "private_key_id": "...",
  "private_key": "...",
  "client_email": "...",
  "client_id": "...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://accounts.google.com/o/oauth2/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "..."
}

We use this key later to set up our client in our API Route. Okay, back to the service account. We need to delegate domain-wide authority.

  • On the table row, click Actions -> Edit.
  • Show Domain-Wide Delegation -> Enable G-Suite Domain-Wide Delegation.

Finally, we need to add our service account email to the Google Analytics account we want to use.

  • Go to the Admin panel inside Google Analytics.
  • Click "User Management."
  • Add the client_email from your service account.

That's it! 🎉 You now have access to make requests to the Google Analytics API with your service account.

Creating an Environment Variable#

To securely access the API, we need to include the secret with each request. We also do not want to commit secrets to git. Thus, we should use an environment variable.

Since I'm deploying via Now, I can add the secrets via their CLI. We only need a few of the values from the JSON file. For the private key, make sure you convert the new line characters (\n) to actual new lines.

$ now secret add -- google-private-key "-----BEGIN PRIVATE KEY-----
MIIEvQIBA
..
..
2DAVOW4c=
-----END PRIVATE KEY-----"
$ now secret add google-client-email my-account@project.iam.gserviceaccount.com
$ now secret add google-client-id 721877721877

To reference these values locally when using now dev, they need to be added to your .env file.

GOOGLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nDVOW4c=\n-----END PRIVATE KEY-----\n"
GOOGLE_CLIENT_EMAIL=my-account@project.iam.gserviceaccount.com
GOOGLE_CLIENT_ID=721877721877

Finally, we need to add the secrets to our now.json.

{
  "env": {
    "GOOGLE_PRIVATE_KEY": "@google-private-key",
    "GOOGLE_CLIENT_EMAIL": "@google-client-email",
    "GOOGLE_CLIENT_ID": "@google-client-id"
  }
}

We can now reference the secrets via process.env.GOOGLE_PRIVATE_KEY in our API route.

Note: If you have a lot of environment variables on Now, you might need to encrpyt your service account.

Creating the API Route#

Let's start by creating a new API route at pages/api/page-views.js.

export default (req, res) => {
  return res.status(200).json({});
};

To make server-side requests to Google Analytics, we can install the googleapis library.

$ yarn add googleapis

Then, we can initialize googleapis inside our API route.

import { google } from 'googleapis';

let googleAuth;

export default async (_, res) => {
  googleAuth = new google.auth.GoogleAuth({
    credentials: {
      client_email: process.env.GOOGLE_CLIENT_EMAIL,
      client_id: process.env.GOOGLE_CLIENT_ID,
      private_key: process.env.GOOGLE_PRIVATE_KEY
    },
    scopes: ['https://www.googleapis.com/auth/analytics.readonly']
  });

  const analytics = google.analytics({
    auth,
    version: 'v3'
  });

  return res.status(200).json({});
};

Finally, we want to pull statistics about our site. We'd like to know the total number of views for a given time range. To allow the API route to be re-used, let's pass the start date as a query parameter.

const startDate = req.query.startDate;

Then, we can use the same API route to fetch stats about different time ranges.

import { google } from 'googleapis';

let googleAuth;

export default async (_, res) => {
  googleAuth = new google.auth.GoogleAuth({
    credentials: {
      client_email: process.env.GOOGLE_CLIENT_EMAIL,
      client_id: process.env.GOOGLE_CLIENT_ID,
      private_key: process.env.GOOGLE_PRIVATE_KEY
    },
    scopes: ['https://www.googleapis.com/auth/youtube.readonly']
  });

  const analytics = google.analytics({
    auth,
    version: 'v3'
  });

  const startDate = req.query.startDate;
  const response = await analytics.data.ga.get({
    'end-date': 'today',
    ids: 'ga:187331021',
    metrics: 'ga:pageviews',
    'start-date': startDate
  });

  return res.status(200).json({
    pageViews: response.data.rows[0][0]
  });
};

Example#

The two cards below talk to /api/page-views and pull back stats about my site.

Bonus: You can cache the API route with the cache-control header.

Cache-Control: public, max-age=120, stale-while-revalidate=60

Keep Reading#

Create a Dashboard with Next.js API Routes

Subscribe to the newsletter

Get emails from me about web development, tech, and early access to new articles.