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.
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. pageviewand$identifyare 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.
<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:
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.