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
| Attribute | Required | Description |
|---|---|---|
data-site-key | Yes | Site key from Add website / Setup (projects.site_key in the app DB) |
data-supabase-url | Yes* | Site project Supabase URL (*unless using endpoint) |
data-supabase-key | Yes* | Site project anon key (*unless using endpoint) |
data-endpoint | No | POST JSON to your API instead of Supabase (hides anon key from the browser) |
data-geo-url | No | URL for geo lookup (recommended: your app's /api/geo) |
data-domains | No | Comma-separated hostnames; tracking only runs on these hosts (e.g. example.com,www.example.com) |
data-do-not-track="true" | No | Skip tracking when the browser sends Do Not Track |
data-auto-track="false" | No | Disable 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
| Method | Description |
|---|---|
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_mson tab hide /pagehide - SPA navigation — wraps
history.pushState/replaceState, listens topopstateandhashchange - UTM & click IDs —
utm_*,gclid,fbclid,msclkidfrom the URL - Visit — new
visit_idafter 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_idpath,page_title,hostname,url_query,referrer,sourcedevice,platform,browser(numeric enums)country_code,latitude,longitude(if geo available)language,screen,distinct_id- UTM and ad click id columns
event_namefor custom events;duration_msfor page leave
Encoded enums
| Field | Values |
|---|---|
event_type | 1 pageview, 2 page leave, 10 custom |
device | 0 unknown, 1 desktop, 2 mobile, 3 tablet, 4 TV |
platform | 0 unknown, 1 Windows, 2 macOS, 3 Linux, 4 iOS, 5 Android, 6 Chrome OS |
browser | 0 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.