MenuCustom events

Track

Custom events

Send named events with properties from the browser to count signups, upgrades and any other action as goals.

Call window.productlense('event', name, props) to record an action. Custom events appear in the events breakdown and can be used as goals and funnel steps.

JavaScript
window.productlense('event', 'Signup', { plan: 'starter' });
window.productlense('event', 'Upgrade clicked', { from: 'pricing' });

Rules for names and props

  • The name must match ^[a-zA-Z0-9_\- ]{1,64}$: letters, digits, spaces, underscores and hyphens, up to 64 characters. Any other name is ignored silently in the browser and rejected by the server.
  • pageview and $identify are reserved.
  • Props are optional and must be a JSON object, at most 2,048 bytes once serialised. The browser does not check props; the server rejects the whole batch an invalid event arrived in, so keep props small and flat.
  • The whole request is limited to 8 KB.

Call it before the script loads

The script loads with defer. If your code may run first, add the queue stub above the script tag. Calls made before the script loads are kept and replayed in order.

HTML
<script>window.productlense=window.productlense||function(){(window.productlense.q=window.productlense.q||[]).push(arguments)}</script>
<script defer data-site="SITE_ID" src="https://api.productlense.app/a.js"></script>

In TypeScript, declare the global once:

src/productlense.d.ts
declare global {
  interface Window {
    productlense?: (...args: unknown[]) => void;
  }
}
export {};

Then call it with optional chaining so server rendering never fails: window.productlense?.('event', 'Signup').

Examples

document.querySelector('#upgrade')?.addEventListener('click', () => {
  window.productlense('event', 'Upgrade clicked', { from: 'navbar' });
});
document.querySelector('form#signup')?.addEventListener('submit', () => {
  window.productlense('event', 'Signup');
});
export function UpgradeButton() {
  return (
    <button onClick={() => window.productlense?.('event', 'Upgrade clicked', { from: 'pricing' })}>
      Upgrade
    </button>
  );
}

Use events as goals

Goals are defined in the dashboard, not in code: a goal matches an event name (such as Signup) or a page path. See Goals and funnels.

From a server

To send events from your backend, for example a trial that starts after a webhook, use the Events API.

    ↑ ↓ to move, Enter to open