For Developers

Integration Guide

Add our lightweight tracker to your frontend and start capturing user behavior receipts for your Customer Success team.

Two lines of code. Zero config. Zero performance impact.

01

Setup

Add the Snippet

Add this to the <head> of your website. If you already know the user's ID at render time, pass it directly in the config. Otherwise, just set the projectKey and identify later.

index.html
<script>
  window.witnesConfig = {
    projectKey: 'YOUR_PROJECT_KEY',
    userId:     'user_4821',  // optional — pass it if you know it
  };
</script>
<script src="https://cdn.witnes.io/w.min.js" async></script>
02

Identification

Identifying Users

There are three ways to associate sessions with a user. Pick whichever fits your app.

Do not use personally identifiable information as the User ID

Never pass emails, full names, or phone numbers. Use an opaque internal identifier (e.g. a database ID or UUID). If you choose to send identifiable data, you are solely responsible for any privacy violations (GDPR, CCPA, etc.). See our Privacy Policy.

A

Static — userId known at render time

Pass userId directly in the config. The tracker picks it up immediately.

index.html
window.witnesConfig = {
  projectKey: 'YOUR_PROJECT_KEY',
  userId:     'user_4821',
};
B

Dynamic — userId known after login

For classic JavaScript, call window.Witnes.identify() after login. You can do this inside any normal inline <script> block as well. For TypeScript with the CDN snippet, call (window as any).Witnes?.identify?.() to avoid global type errors.

Type-safe npm package coming soon

If you prefer typed imports over (window as any), we are shipping an official type-safe package next.

app.js / app.ts
// JavaScript
window.Witnes.identify("user_4821");

// Inline script usage
<script>
  window.Witnes.identify(user.id);
</script>

// TypeScript (CDN snippet)
(window as any).Witnes?.identify?.("user_4821");
C

Guest Mode — explicit identification

For guest sessions, call identify(null, { guest: true }) explicitly.

app.js / app.ts
// JavaScript
window.Witnes.identify(null, { guest: true });

// TypeScript (CDN snippet)
(window as any).Witnes?.identify?.(null, { guest: true });
03

Billing

How Billing Works

Witnes calculates usage based on Page loads.

Tracked Page Loads

LOAD

Triggered when a page is first opened.

SPA_NAV

Triggered when the URL changes (even without a full page reload).

04

Compatibility

Browser Coverage

We support all modern browsers. Some advanced metrics are subject to browser API availability.

Feature Chrome Edge Safari Firefox
Session Tracking Tested Tested Tested Expected
LCP Tested Tested Tested Expected
CLS Tested Tested Tested Expected
FCP Tested Tested Tested Expected
Long Tasks Tested Tested N/A Expected
Resource Timing Tested Tested Partial Expected
Network Info Tested Tested N/A N/A
sendBeacon Tested Tested Tested Expected

Tested Versions: Chrome 131, Edge 131, Safari 18.5

Expected: Firefox 133+ per MDN compatibility data

Safari: LCP support added in Safari 18.2 / macOS 15.2 (December 2024)

05

Under the Hood

Technical Details

Performance

  • Zero Blocking — Uses async and sendBeacon. Never slows your page.
  • Lightweight — < 2.5KB gzipped.

Security & Privacy

  • Project Key — Routes data to your specific dashboard.
  • User ID — Must be a non-identifiable internal ID (database ID or UUID). Never send PII.
06

Troubleshooting

Events not appearing?

  • 1

    Check that projectKey matches your dashboard exactly.

  • 2

    Ensure Witnes.identify() is being called with a non-null string.

  • 3

    Open your browser console and verify that requests to api.witnes.io/ingest are returning 202 Accepted.

  • 4

    Enable debug mode to see detailed output in the browser console:

index.html
<script>
  window.witnesConfig = {
    projectKey: 'YOUR_PROJECT_KEY',
    debug: true,
  };
</script>

Ad blockers

Some ad blockers or privacy extensions may block the tracking script from loading. Ask the user to temporarily disable their ad blocker and try again to rule this out.