Setup Mixpanel Analytics in a NextJS Application
Analytics is crucial for any profitable application, whether it’s a small application with 100 users or a large application with 10,000 users.
Understanding your users is one of the most critical things. And mixpanel is one of the best tools to do that.
Today, we will learn how to integrate and start mixpanel tracking.
Setup the project
I assume you already have a NextJS project setup. Also, create a new Mixpanel account from here (If you haven’t already).
Keep in mind that I am showing for NextJS but it’s applicable for any ReactJS app too.
Then, install the dependency
npm install mixpanel-browser
Get a token
First, add the following environment variable
NEXT_PUBLIC_MIXPANEL_TOKEN="YOUR_TOKEN_HERE"
Now, you can get the mixpanel token from your project’s dashboard.
Then go to Settings -> Project Settings
Then grab the Project Token and add it in the environment file.
Create Configuration File
Create a file named mixpanel.ts and add the following code
import mixpanel from 'mixpanel-browser';
// Define event names as constants to prevent typos
export const ANALYTICS_EVENTS = {
PAGE_VIEW: 'Page View',
BUTTON_CLICK: 'Button Click',
FORM_SUBMIT: 'Form Submit',
USER_SIGNED_IN: 'User Signed In',
USER_SIGNED_UP: 'User Signed Up',
USER_SIGNED_OUT: 'User Signed Out',
// ... other events
};
// Initialize mixpanel
const MIXPANEL_TOKEN = process.env.NEXT_PUBLIC_MIXPANEL_TOKEN;
if (MIXPANEL_TOKEN) {
mixpanel.init(MIXPANEL_TOKEN, {
debug: process.env.NODE_ENV === 'development',
track_pageview: true,
persistence: 'localStorage',
ignore_dnt: true,
});
}
So, initialize the mixpanel as high as possible in your component tree.
Add Analytics Functions
Now, after you add the configuration, it’s time to add some reusable functions to track mixpanel events.
So add the following code in the same file:
export const MixpanelAnalytics = {
track: <T extends Record<string, any>>(
eventName: string,
properties?: T & CommonEventProperties
) => {
try {
if (MIXPANEL_TOKEN) {
mixpanel.track(eventName, {
...properties,
timestamp: Date.now(),
path: typeof window !== 'undefined' ? window.location.pathname : undefined,
});
}
} catch (error) {
console.error('Error tracking event:', error);
}
},
pageView: (pageName: string, properties?: Record<string, any>) => {
try {
if (MIXPANEL_TOKEN) {
MixpanelAnalytics.track(ANALYTICS_EVENTS.PAGE_VIEW, {
page: pageName,
...properties,
});
}
} catch (error) {
console.error('Error tracking page view:', error);
}
}
};
If you analyze these 2 functions above
track
This function is used to track any kind of event.
For example, if you want to track a user, click a button to visit an external website. Maybe for affiliate calculation
You can do the following:
MixpanelAnalytics.track("VISIT_WEBSITE", {
website_name: name,
website_url: website,
visit_count: (mixpanel.get_property('total_website_visits') ?? 0) + 1,
});
pageView
This is a pretty straightforward method to track every page view inside your application.
Now remember — when we initialized mixpanel, we already told it to track page views:
mixpanel.init(MIXPANEL_TOKEN, {
track_pageview: true, << HERE
...others
});
So this custom tracking is only for more detailed analysis.
Know your users
Now, tracking clicks is cool and all, but many times, it’s not enough.
Maybe you want to track specific users. Maybe you want to know who is doing what. Maybe you are creating a funnel to analyze user behavior.
For these scenarios,mixpanel provides 2 functions.
identify
reset
So, on a high level, after a user logs in, you can call
mixpanel.identify("whatever identified you want (usually email or userid)")
And on logout, you can reset it
mixpanel.reset()
Now you can also add additional context or details about your users using the people.set() method
For example,
mixpanel.people.set({
plan: 'Enterprise', // Update "plan" from "Premium" to "Enterprise"
company: 'mixpanel' // Create new "company" profile prop
});
There are some additional methods like append, union, increment etc., to handle more scenarios, but skip them as they are not the focus of this article. You can read more here
But what about anonymous users?
Now, in many applications (especially public sites) — it’s not mandatory to log in to see the contents.
But how do we track those people if they don’t log in?
To handle all these scenarios, let’s create two more utility functions.
export const MixpanelAnalytics = {
// ... other methods ...
identifyKnownUsers: (userId: string, userProperties?: Record<string, any>) => {
try {
mixpanel.identify(userId);
if (userProperties) {
mixpanel.people.set(userProperties);
}
} catch (error) {
console.error('Error identifying user:', error);
}
},
identifyUnknownUsers: () => {
try {
const anonymousId =
mixpanel.get_distinct_id() ||
`anon-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
MixpanelAnalytics.identify(anonymousId);
MixpanelAnalytics.setPeople({
$first_seen: new Date().toISOString(),
user_type: 'anonymous',
platform: typeof window !== 'undefined' ? window.navigator.platform : 'unknown',
});
} catch (error) {
console.error('Error initializing user:', error);
}
}
};
So you can track your known and unknown users with this.
An example usage can look like the following: In one of the root files — (layout.tsx file in app router, _app.tsx in pages router)
Add the following
useEffect(() => {
const getUser = async () => {
const user = functionToGetUser();
if (user) {
await MixpanelAnalytics.identifyKnownUser(user);
} else {
await MixpanelAnalytics.initializeUnknownUser();
}
};
getUser();
}, []);
So this will initialize the user appropriately when they visit the site.
You can gather data and assign it to this particular user going forward.
Example usage
Now comes the fun part. Notice the following code and update it according to your needs.
const handleClick = () => {
MixpanelAnalytics.setPeople({
$last_visited: websiteName,
last_visit_date: new Date().toISOString(),
total_visits: (mixpanel.get_property('total_visits') ?? 0) + 1,
});
MixpanelAnalytics.track(ANALYTICS_EVENTS.VISIT_WEBSITE, {
website_name: websiteName,
website_url: website,
visit_count: (mixpanel.get_property('total_visits') ?? 0) + 1,
});
};
In the above function we are tracking the particular user’s profile with the tracking data and also making sure that we are counting their visits to the particular website as well.
Cool right?
Best practices
When working with analytics — it’s very important to keep the data consistent.
So, make sure to add proper types for analytics events.
For example
Define constants for the events.
Never use plain strings for event names.
export const ANALYTICS_EVENTS = {
PAGE_VIEW: 'Page View',
BUTTON_CLICK: 'Button Click',
// ... other events
} as const;
Type safety
For events payload, make sure to use consistent structure by using types
interface CommonEventProperties {
timestamp?: number;
path?: string;
referrer?: string;
}
User Properties
Always maintain consistent user properties across sessions.
MixpanelAnalytics.setPeople({
$email: user.email,
$name: user.user_metadata?.full_name,
$created: user.created_at,
last_sign_in: new Date().toISOString(),
user_type: 'registered',
auth_provider: user.app_metadata?.provider || 'email',
});
Otherwise, down the road, the data will be useless.
Conclusion
Remember to handle analytics initialization properly in your client-side components.
Also, ensure that sensitive user data is handled appropriately according to your privacy policy and data protection regulations.
Hope you learned something new today.
Have a great day!