Installation guides
Script tag
Add ProductLense to any website with one script tag in the head of every page, then identify users after signup.
ProductLense is one script of about 2.3 KB gzipped. Paste it into the head of every page, replace SITE_ID with the id from Settings → Sites in the ProductLense dashboard, and pageviews start arriving within seconds. The script sets no cookies and loads with defer, so it never blocks rendering.
You rarely need to pick a guide yourself. When you add a site, the dashboard reads your homepage once, detects what it is built with (Next.js, Nuxt, SvelteKit, Astro, WordPress, Shopify, Webflow, Framer, Laravel, Django, Rails and more), and shows the code with your site id filled in, the exact file it goes in, and a ready prompt for Claude Code, Codex, Cursor or Lovable. It also tells you when the script is already on the page.
Add the script
<head>
<meta charset="utf-8" />
<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>
</head>The first line is the queue stub. It lets you call window.productlense(...) before the deferred script has loaded; calls are kept and replayed in order once it runs. If you never call window.productlense from inline code, the stub is optional.
Script attributes
These are every setting the script reads. All are optional except data-site.
| Attribute | Default | Meaning |
|---|---|---|
data-site | required | The site id from Settings → Sites. |
data-api | script origin | Base URL that receives events at <base>/api/e. Only needed when you proxy the script. |
data-spa | true | Set "false" to stop recording history route changes. See pageviews and single-page apps. |
data-outbound | true | Set "false" to stop recording outbound links and file downloads. See outbound links and downloads. |
data-exclude | none | Comma-separated path globs that are never tracked, such as /admin/*,/preview. See exclude pages. |
data-dev | false | Set "true" to send events from localhost. |
Send events and identify users
After signup or login, link the visitor to your own user id. This is what lets ProductLense attribute later payments to the channel that first brought the person.
<script>
window.productlense('identify', 'user_123', { plan: 'starter' });
window.productlense('event', 'Signup', { plan: 'starter' });
</script>The user id is any non-empty string of up to 128 bytes without control characters. Use the same id you store on the customer in your billing provider; see how payments are attributed. Event names allow letters, digits, spaces, underscores and hyphens, up to 64 characters; see custom events.
Content Security Policy
If your site sends a Content-Security-Policy header, allow the script and the endpoint it posts to:
script-src 'self' https://api.productlense.app;
connect-src 'self' https://api.productlense.app;If you keep the queue stub inline, also allow it, for example with its sha256- hash in script-src.
Verify your installation
- Deploy, then open your site in a normal browser window.
- Open the Live page in the ProductLense dashboard. Your visit appears within a few seconds.
- In the browser's developer tools, the Network tab shows a
POSTtohttps://api.productlense.app/api/ewith status204.
Nothing is sent from localhost unless the tag has data-dev="true", and ad blockers in your own browser may block the request. If the visit does not appear, follow Verify your installation.