DEV Community

Cover image for Integrating Amplitude Analytics with NextJS App: A Comprehensive Guide
Radzion Chachura
Radzion Chachura

Posted on • Originally published at radzion.com

Integrating Amplitude Analytics with NextJS App: A Comprehensive Guide

Watch on YouTube | 🐙 GitHub | 🎮 Demo

Let's add Amplitude analytics to a NextJS app!

In the example below, we will track page views by calling the trackEvent method on the analytics instance from the useEffect hook:

function MyApp({ Component, pageProps }: AppProps) {
  const { pathname } = router
  useEffect(() => {
    analytics.trackEvent("Visit page", { pathname })
  }, [pathname])

  return <p>my app</p>
}

export default MyApp
Enter fullscreen mode Exit fullscreen mode

This is how you create the analytics instance for your app:

import { isProduction } from "shared"
import { shouldBeDefined } from "@increaser/utils/shouldBeDefined"
import { AmplitudeAnalytics } from "@increaser/ui/analytics/AmplitudeAnalytics"
import { LocalAnalytics } from "@increaser/ui/analytics/LocalAnalytics"

export const analytics = isProduction
  ? new AmplitudeAnalytics(
      shouldBeDefined(process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY)
    )
  : new LocalAnalytics()
Enter fullscreen mode Exit fullscreen mode

First, we check if the environment is set to production. We want to avoid sending analytics events in development or testing environments.

export const isProduction = process.env.NODE_ENV === "production"
Enter fullscreen mode Exit fullscreen mode

The shouldBeDefined function will throw an error if the value is undefined. This is useful to ensure we never forget to set the environment variable.

export function shouldBeDefined<T>(
  value: T | undefined,
  valueName: string = "value"
): T {
  if (value === undefined) {
    throw new Error(`${valueName} is undefined`)
  }

  return value
}
Enter fullscreen mode Exit fullscreen mode

Both AmplitudeAnalytics and LocalAnalytics adhere to the same interface, which should include:

  • setUser: used to associate the user with the analytics events. This would only be used if your app or website has authenticated users.
  • trackEvent: used to track events. Extra info can be passed into the second argument, such as the name of the page in our previous example.
export interface Analytics {
  setUser: (id: string) => void
  trackEvent: (name: string, data?: Record<string, any>) => void
}
Enter fullscreen mode Exit fullscreen mode

Here's how you would implement AmplitudeAnalytics:

import { Analytics } from "./Analytics"
import * as amplitude from "@amplitude/analytics-browser"

export class AmplitudeAnalytics implements Analytics {
  apiKey: string
  isInitialized: boolean = false

  constructor(apiKey: string) {
    this.apiKey = apiKey
  }

  private initialize() {
    if (!this.isInitialized) {
      amplitude.init(this.apiKey)
      this.isInitialized = true
    }
  }

  setUser(id: string) {
    this.initialize()
    amplitude.setUserId(id)
  }

  trackEvent(name: string, data?: Record<string, any>) {
    this.initialize()
    amplitude.track(name, data)
  }
}
Enter fullscreen mode Exit fullscreen mode

It requires the @amplitude/analytics-browser package to be installed and an apiKey to be passed as a constructor argument. We don't initialize Amplitude immediately; instead, we only do so the first time setUser or trackEvent is called. This ensures that requests are only sent to Amplitude upon tracking.

Here's how you can implement LocalAnalytics:

import { Analytics } from "./Analytics"

export class LocalAnalytics implements Analytics {
  constructor() {
    console.log("Initialize local analytics")
  }

  setUser(id: string) {
    console.log("Set user for analytics: ", id)
  }

  trackEvent(name: string, data?: Record<string, any>) {
    console.log("Track event: ", name, data)
  }
}
Enter fullscreen mode Exit fullscreen mode

This merely logs the events to the console. It's useful for debugging events during development.

Imagine monitoring actually built for developers

Billboard image

Join Vercel, CrowdStrike, and thousands of other teams that trust Checkly to streamline monitor creation and configuration with Monitoring as Code.

Start Monitoring

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay