Integrating Amplitude Analytics with NextJS App: A Comprehensive Guide
Radzion Chachura
Posted on August 26, 2023
✨ 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
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()
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"
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
}
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
}
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)
}
}
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)
}
}
This merely logs the events to the console. It's useful for debugging events during development.
Posted on August 26, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.