MenuScript tag

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

index.html
<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.

AttributeDefaultMeaning
data-siterequiredThe site id from Settings → Sites.
data-apiscript originBase URL that receives events at <base>/api/e. Only needed when you proxy the script.
data-spatrueSet "false" to stop recording history route changes. See pageviews and single-page apps.
data-outboundtrueSet "false" to stop recording outbound links and file downloads. See outbound links and downloads.
data-excludenoneComma-separated path globs that are never tracked, such as /admin/*,/preview. See exclude pages.
data-devfalseSet "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.

HTML
<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:

Text
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

  1. Deploy, then open your site in a normal browser window.
  2. Open the Live page in the ProductLense dashboard. Your visit appears within a few seconds.
  3. In the browser's developer tools, the Network tab shows a POST to https://api.productlense.app/api/e with status 204.

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.

    ↑ ↓ to move, Enter to open