Filtering and transforming events

Important: This feature is on beta, and some breaking changes might be required as more dimensions are added. Have suggestions, or feedback? Feel free to reach out anytime.

The Panelbear Analytics script lets you filter out and transform the events that get sent to our servers. While we already handle various sensitive data points for you (such as the URL query parameters, and anonymizing the IP address), sometimes you need more control over what exactly is being collected.

The recommended approach is to avoid sending unnecessary data at the client level. This helps reduce network overhead, and prevents sensitive data from ever reaching our servers.

The event schema

Every event is passed through the beforeSend function before being sent to Panelbear. The event object contains the following fields:

  • pid: The Panelbear property ID (site).
  • event: The event name. For example Pageview or MyCustomEventName.
  • url: The page URL on which the event was triggered, including the protocol and hostname. For example https://panelbear.com/docs/.
  • screen_width: The screen width, rounded to the lower bound 100th pixel. For example 2400.
  • user_language: The user language code as provided by the browser. For example en-US.
  • timezone: The user timezone as provided by the browser. For example Europe/London.
  • referrer: The page referrer, if available. For example https://duckduckgo.com/.
  • utm_source: The UTM source query param, if available. For example producthunt.
  • utm_campaign: The UTM campaign query param, if available. For example launch-campaign.
  • utm_medium: The UTM medium query param, if available. For example email.

More fields will be available soon (for example the performance data), but this feature is currently on beta and not recommended for production use until more documentation is available.

Filtering events

You can skip events from being sent by returning null on the beforeSend callback. For example in the case of the plain Javascript snippet:

panelbear("config", {
  beforeSend(event) {
    // If you return null or undefined, the event will be skipped
    return null;
  },
});

This is very useful, as it allows you to skip events based on any condition. For example let's suppose you wanted to avoid sending events for sensible paths:

panelbear("config", {
  beforeSend(event) {
    // If URL contains '/billing/', skip event
    if (event.url.includes("/billing/")) {
      return null;
    }
    // Otherwise send as usual
    return event;
  },
});

Tip: when testing things out, you could enable Debug Mode to view more detailed information on your browser's console:

panelbear("config", {
  debug: true, // Enable debug mode
  beforeSend(event) { ... },
});

Transforming events

In addition to being able to filter out events, you can also transform the event data as part of the beforeSend hook:

panelbear("config", {
  beforeSend(event) {
    // Rewrite all URL paths that start with '/users*' to '/users'
    // For example: '/users/123-456/account-settings' will be replaced by '/users/private'
    const url = new URL(event.url);
    if (url.pathname.startswith("/users/")) {
      url.pathname = "/users/private";

      // Note that event URL is a string, including the protocol and hostname
      event.url = url.toString();
    }

    // You can also remove any data from the event
    // For example, to remove the user language:
    delete event.user_language;

    return event;
  },
});

This is incredibly useful to fully customize the behaviour of the analytics code. It gives you full control over what exactly is sent to Panelbear. If you wanted you could even send the event data to your own in-house solution by hooking into the beforeSend function:

panelbear("config", {
  beforeSend(event) {
    // Serialize as JSON and send to your own API endpoint
    const body = JSON.stringify(event);
    fetch("/my-analytics-endpoint", { body, method: "POST", keepalive: true });

    // Continue sending event to Panelbear
    return event;
  },
});

Usage with the JS library

If you're using the panelbear-js library, you can easily configure the beforeSend hook when initializing the Panelbear script:

import * as Panelbear from "@panelbear/panelbear-js";

// Load the Panelbear tracker once in your app
Panelbear.load("YOUR_SITE_ID", {
  beforeSend: (event) => {
    // Filter or transform event here
    return event;
  },
});

If you're using integrations such as the NextJS React hook, it will be part of the config object also passed during initialization:

// ./pages/_app.js
import { usePanelbear } from "./../hooks/panelbear";

function CustomApp({ Component, pageProps }) {
  // Load Panelbear only once during the app lifecycle
  usePanelbear("YOUR_SITE_ID", {
    beforeSend: (event) => {
      // Filter or transform event here
      return event;
    },
  });

  return <Component {...pageProps} />;
}

export default CustomApp;