Skip to content

Add high level filter #497

@vitonsky

Description

@vitonsky

Hi, I glad you've implemented this high level abstraction over analytics services for me, because it's nice idea!

I have started thought about this idea when I've start creating my own implementation of plausible client https://github.com/vitonsky/plausible-client and my idea was to implement abstraction to aggregate all analytics services we use in project under single API to make only one call.

One of important features of this abstraction I needed in is a filter and transformer on high level, to implement flexible moderation of events.

Proposal

Some of my use cases is require to enrich events data at high level. Trivial example is add user ID and some specific data about current client like tags related to A/B testing group, etc.

In my solution mentioned above i can do it like that

import { Plausible, enableAutoOutboundTracking } from 'plausible-client';

const plausible = new Plausible({
  apiHost: 'https://plausible.io',
  domain: 'example.org',
  transform(event, eventName) {
    event.props = {
      ...event.props,
      group: 'clients',
      userId: event.props.uid ? "uuid:" + event.props.uid : undefined,
      isPreferDarkTheme: window.matchMedia("(prefers-color-scheme: dark)").matches,
    };

    return event;
  }
});

Another case is high level filtering for all events based on user preferences and groups. In my solution it works like that

import { Plausible, enableAutoOutboundTracking } from 'plausible-client';

const plausible = new Plausible({
  apiHost: 'https://plausible.io',
  domain: 'example.org',
  filter(event, eventName) {
    // Skip all events while development
    if (location.hostname === 'localhost') {
      console.warn('Analytics event is skipped, since run on localhost', event);
      return false;
    }

    // Skip all events for users who don't want to be tracked
    if (window.localStorage.plausible_ignore === 'true') return false;

    // Skip events by event props
    if (event.props.group === 'no-track') return false;

    // Skip events by its name, for users who does not participate in preview program
    if (!event.props.previewEnabled && eventName.startsWith('preview:')) return false;

    // Pass all events otherwise
    return true;
  }
});

As I said, I glad you've implemented this idea with high level abstraction. Now, let's implement this features to rule data on high level, instead of copying this logic for every service config.

If code designed fine, implementation of this features will be trivial.
Look at my implementation that takes a few lines of code: https://github.com/vitonsky/plausible-client/blob/8d2e3877067c655c8b5fafcd52bd1fa2262fa491/src/Plausible.ts#L73-L79

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions