Open AnalyticsOpen Analytics
Home/Documentation

Tracking script

Add tracker.js to every page you want to measure. Events are sent with fetch to Supabase or your own endpoint.

Basic embed

After adding a site in the dashboard, open Tracking (/app/[siteId]/setup) and copy the snippet. It looks like:

<!-- Open Analytics -->
<script
  src="https://your-app.com/tracker.js"
  data-site-key="YOUR_SITE_KEY"
  data-supabase-url="https://xxx.supabase.co"
  data-supabase-key="YOUR_ANON_KEY"
  data-geo-url="https://your-app.com/api/geo"
></script>

Script attributes

AttributeRequiredDescription
data-site-keyYesSite key from Add website / Setup (projects.site_key in the app DB)
data-supabase-urlYes*Site project Supabase URL (*unless using endpoint)
data-supabase-keyYes*Site project anon key (*unless using endpoint)
data-endpointNoPOST JSON to your API instead of Supabase (hides anon key from the browser)
data-geo-urlNoURL for geo lookup (recommended: your app's /api/geo)
data-domainsNoComma-separated hostnames; tracking only runs on these hosts (e.g. example.com,www.example.com)
data-do-not-track="true"NoSkip tracking when the browser sends Do Not Track
data-auto-track="false"NoDisable automatic first pageview; call OpenAnalytics.trackPageview() manually

Global configuration

You can set options on window.OpenAnalytics before loading the script:

<script>
  window.OpenAnalytics = {
    siteKey: "…",
    supabaseUrl: "…",
    supabaseKey: "…",
    geoUrl: "…",
    domains: "example.com",
    doNotTrack: false,
    autoTrack: true
  };
</script>
<script src="https://your-app.com/tracker.js" …></script>

JavaScript API

MethodDescription
OpenAnalytics.track(name, props?)Custom event (event_type = 10). props is stored as JSON in source (max 200 chars).
OpenAnalytics.identify(id)Set distinct_id (logged-in user id). Pass null to clear.
OpenAnalytics.trackPageview()Send a pageview manually (when data-auto-track="false")
OpenAnalytics.getVisitorId()Returns the fingerprint-based visitor id (also in localStorage)

Example: custom event

OpenAnalytics.track("signup", { plan: "pro" });

Declarative click tracking

Track clicks without writing JavaScript:

<button
  data-oa-event="signup"
  data-oa-event-plan="pro"
>
  Sign up
</button>

Extra attributes use the prefix data-oa-event-; hyphens in the name become underscores in the payload (e.g. data-oa-event-plan plan).

Automatic behavior

  • Pageview on load (unless auto-track is off or tracking is disabled)
  • Page leave with duration_ms on tab hide / pagehide
  • SPA navigation — wraps history.pushState / replaceState, listens to popstate and hashchange
  • UTM & click IDsutm_*, gclid, fbclid, msclkid from the URL
  • Visit — new visit_id after 30 minutes of inactivity
  • Bot filter — skips tracking when User-Agent matches common crawlers/preview bots

Event payload (stored fields)

Each event includes identifiers and context:

  • visitor_id, session_id, visit_id
  • path, page_title, hostname, url_query, referrer, source
  • device, platform, browser (numeric enums)
  • country_code, latitude, longitude (if geo available)
  • language, screen, distinct_id
  • UTM and ad click id columns
  • event_name for custom events; duration_ms for page leave

Encoded enums

FieldValues
event_type1 pageview, 2 page leave, 10 custom
device0 unknown, 1 desktop, 2 mobile, 3 tablet, 4 TV
platform0 unknown, 1 Windows, 2 macOS, 3 Linux, 4 iOS, 5 Android, 6 Chrome OS
browser0 unknown, 1 Chrome, 2 Firefox, 3 Safari, 4 Edge, 5 Opera, 6 Samsung

Geo caching

Geo is not fetched on every event. Results are cached in localStorage (oa_geo) and refreshed when the network connection changes. Use data-geo-url pointing at your deployed /api/geo route.