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

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.

  1. identify

  2. 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!


Share this post


Read more articles...

team

Add Google Analytics with NextJS

team

How to Setup and Add Google Analytics to your React App

Profile Image

Who I am

Hi, I amMohammad Faisal, A full-stack software engineer @Cruise , working remotely from a small but beautiful country named Bangladesh.

I am most experienced inReactJS,NodeJS andAWS

Buy Me a Coffee Widget