Add Splitbee Analytics to Your Next.js App
Tags: javascript, webdev, nextjs, react
Published: 2021-02-03 20:11:18

> I talk about Splitbee — a new analytics tool; and how to add it to your Next.js app.

![Splitbee Dashboard of Share By Cam](https://dev-to-uploads.s3.amazonaws.com/i/7d91iuzt5mhrn63kmqlw.png "Splitbee Dashboard of Share By Cam")

### Introduction

Analytics, for the most of us, does not have to be as complicated as Google Analytics. [Splitbee](https://splitbee.io) takes a fresh approach to analytics and you’ll find reasons to appreciate it in addition to these:

- It has a clean, responsive and user-friendly UI with features like live updates and journey view
- It does not need additional setup for SPA routing
- It has the simplest onboarding process

However, unlike Google Analytics, Splitbee isn’t free. Unless you don’t have any visitors on your app, sooner or later, you will run into this message and your custom event data will be redacted:

![Splitbee doesn’t provide a free-forever plan](https://dev-to-uploads.s3.amazonaws.com/i/uk6p3m03gw3yf6x8wowe.png "Splitbee doesn’t provide a free-forever plan")

You can learn more about their pricing [here](https://splitbee.io/pricing).

### A Note About Next.js Rewrites

Next.js supports [Rewrites](https://nextjs.org/docs/migrating/incremental-adoption#rewrites), which enable you to remap URLs on-the-fly. By routing Splitbee communication through your own domain, you get to:

- Reduce DNS lookups
- Circumvent ad-blockers that prevent loading content from external domains
- Clean-up CSP header — from `connect-src https://hive.splitbee.io; script-src https://cdn.splitbee.io;` to `connect-src 'self'; script-src 'self';`

We will be configuring Rewrites in each of the two approaches below.

### “Just Add Water” Approach

Add the script directly from Splitbee:

```tsx
// ./pages/_document.tsx

...
<Head>
  <script async src="https://cdn.splitbee.io/sb.js"></script>
</Head>
...
```

You can now track events like so:

```typescript
// Anywhere

if ((window as any).splitbee) {

  const action: string = 'action';
  const data: any = {};

  (window as any).splitbee.track(action, data);

}
```

You can set data against a user like so:

```typescript
// Anywhere

if ((window as any).splitbee) {

  const data: any = {};

  (window as any).splitbee.user.set(data);

}
```

A disadvantage of this approach is that it is possible the library is not loaded when `track()` or `user.set()` is invoked; thereby needing the `if()` wrap.

Configure Next.js Rewrite by pointing the script tag to relative paths instead:

```tsx
// ./pages/_document.tsx

...
<Head>
  <script async data-api="/sb-api" src="/sb.js"></script>
</Head>
...
```

Then, add the Rewrite for those relative paths:

```javascript
// ./next.config.js

const rewrites = async () => [
  {
    destination: 'https://cdn.splitbee.io/sb.js',
    source: '/sb.js'
  },
  {
    destination: 'https://hive.splitbee.io/:slug',
    source: '/sb-api/:slug'
  }
];
module.exports = {
  rewrites
};
```

### NPM Package Approach

Using the [Splitbee NPM package](https://www.npmjs.com/package/@splitbee/web) is beneficial in several ways:

- It automatically makes the library available to the client
- It makes writing synchronous logic possible
- It provides typings to be used with TypeScript

Install the package from NPM:

```
// Command

npm i @splitbee/web
```

Initialize Splitbee:

```tsx
// ./pages/_app.tsx

import splitbee from '@splitbee/web';
import type { AppProps } from 'next/app';
import { useEffect } from 'react';

const MyApp: (props: AppProps) => JSX.Element = ({ Component, pageProps }: AppProps): JSX.Element => {

  useEffect((): void => { splitbee.init(); }, []);

  return <Component {...pageProps} />

}
```

You can now track events like so:

```typescript
// Anywhere

import splitbee from '@splitbee/web';

const action: string = 'action';
const data: any = {};

splitbee.track(action, data);
```

You can set data against a user like so:

```typescript
// Anywhere

import splitbee from '@splitbee/web';

const data: any = {};

splitbee.user.set(data);
```

Configure Next.js Rewrite by first passing a configuration object of relative paths to `init()`:

```tsx
// ./pages/_app.tsx

import splitbee from '@splitbee/web';
import type { AppProps } from 'next/app';
import { useEffect } from 'react';

const MyApp: (props: AppProps) => JSX.Element = ({ Component, pageProps }: AppProps): JSX.Element => {

  useEffect((): void => {

    splitbee.init({
      apiUrl: '/sb-api',
      scriptUrl: '/sb.js'
    });

  }, []);

  return <Component {...pageProps} />

}
```

Then, add the Rewrite for those relative paths:

```javascript
// ./next.config.js

const rewrites = async () => [
  {
    destination: 'https://cdn.splitbee.io/sb.js',
    source: '/sb.js'
  },
  {
    destination: 'https://hive.splitbee.io/:slug',
    source: '/sb-api/:slug'
  }
];

module.exports = {
  rewrites
};
```
---
Cheers!