Lightweight, privacy-first browser analytics — setup, configuration, data attributes, and collection control
Last updated March 21, 2026
Browser Analytics
Flaggr includes a lightweight browser analytics script that captures Web Vitals, page views, and user interactions — and automatically correlates them with active feature flag variants. This lets you measure real-world performance impact of every flag change.
The script is under 5KB gzipped, uses no cookies, collects no PII, and respects Do Not Track by default.
Video walkthrough: See Setting Up the Analytics Script Tag for a step-by-step visual guide covering installation, configuration, and custom event tracking.
Quick Start
Add the script tag to your HTML:
<script
src="https://cdn.flaggr.dev/a.js"
data-site-id="proj_abc123"
defer
></script>That's it. The script automatically collects:
- Web Vitals — LCP, CLS, INP, TTFB, FCP
- Page views — initial load and SPA navigations
- Sessions — anonymous session tracking via
sessionStorage - Flag variants — auto-detected from Flaggr SDK globals
Events are batched and sent to https://ingest.flaggr.dev/e via fetch with keepalive, falling back to navigator.sendBeacon on page unload.
Configuration
All configuration is via data-* attributes on the script tag. No JavaScript API is needed.
Required attributes
| Attribute | Description |
|---|---|
data-site-id | Your project ID. Used to associate events with your Flaggr project. |
Optional attributes
| Attribute | Default | Description |
|---|---|---|
data-endpoint | https://ingest.flaggr.dev/e | Custom analytics ingestion endpoint |
data-track-clicks | false | Enable click tracking on interactive elements |
data-track-errors | false | Enable JavaScript error tracking |
data-track-scroll | false | Enable scroll depth milestone tracking |
data-respect-dnt | true | Respect the browser's Do Not Track setting |
data-debug | false | Enable [flaggr:analytics] console logging |
Full example
<script
src="https://cdn.flaggr.dev/a.js"
data-site-id="proj_abc123"
data-endpoint="https://ingest.flaggr.dev/e"
data-track-clicks="true"
data-track-errors="true"
data-track-scroll="false"
data-respect-dnt="true"
data-debug="false"
defer
></script>Event Types
Page views (always on)
Captured on initial page load and SPA navigations (History API). Each event includes:
path— URL pathtitle— Document titlereferrer— Referring pageviewportWidth,viewportHeight— Browser viewport dimensionsconnectionType— Network connection type (if available)
Web Vitals (always on)
Collected via PerformanceObserver. Each vital includes a numeric value and a rating:
| Metric | Good | Needs Improvement | Poor |
|---|---|---|---|
| LCP | ≤ 2500ms | ≤ 4000ms | > 4000ms |
| CLS | ≤ 0.1 | ≤ 0.25 | > 0.25 |
| INP | ≤ 200ms | ≤ 500ms | > 500ms |
| TTFB | ≤ 800ms | ≤ 1800ms | > 1800ms |
| FCP | ≤ 1800ms | ≤ 3000ms | > 3000ms |
Click tracking (opt-in)
When data-track-clicks="true", captures clicks on interactive elements:
selector— CSS selector of the clicked elementtag— HTML tag nametext— Button/link text (truncated to 100 characters)trackId— Value ofdata-trackattribute, if set on the elementhref— Link URL, if applicable
Use data-track="signup-cta" on elements to give them stable identifiers for analytics.
Error tracking (opt-in)
When data-track-errors="true", captures unhandled JavaScript errors and promise rejections:
message— Error messagesource— Source fileline,column— Error locationstack— Stack trace (truncated to 500 characters)
Scroll depth (opt-in)
When data-track-scroll="true", captures scroll depth milestones at 25%, 50%, 75%, and 100%. Uses requestAnimationFrame throttling for minimal performance impact.
Flag Variant Correlation
The analytics script automatically detects active feature flag variants and attaches them to every event. This enables per-variant performance analysis in the Analytics Dashboard.
Detection order
window.__FLAGGR_BOOTSTRAP__— SSR-injected flag values (set by Next.js server components)window.__FLAGGR_FLAGS__— Live SDK state (updated after client-side evaluation)flaggr:flags-changedevent — Custom event dispatched when flag values change
The Flaggr Web Provider automatically populates these globals. If you use a custom provider, expose flag values on window.__FLAGGR_FLAGS__ and dispatch a flaggr:flags-changed CustomEvent with { detail: Record<string, unknown> } when values change.
Dynamic Collection Control
Collection can be controlled remotely via the _flaggr_analytics feature flag, allowing you to adjust what data is collected without redeploying.
String levels
Set the _flaggr_analytics flag to one of these string values:
| Level | Collects |
|---|---|
"off" | Nothing (sampling = 0) |
"minimal" | Page views + Web Vitals |
"standard" | Page views + Web Vitals |
"detailed" | Page views + Web Vitals + clicks + errors |
"full" | Everything (page views + vitals + clicks + errors + scroll) |
Object config
For fine-grained control, set _flaggr_analytics to a JSON object:
{
"pageviews": true,
"vitals": true,
"clicks": false,
"errors": false,
"scroll": false,
"sampling": 1.0
}Sampling
The sampling field controls probabilistic collection:
0— Block all events1— Collect all events (default)0.5— Collect from 50% of sessions
Sampling is decided once per session and remains stable until the page is reloaded.
Elevation rules
The data-* attributes on the script tag define a static floor. The _flaggr_analytics flag can only elevate collection above this floor, never reduce below it. For example, if data-track-clicks="true" is set, clicks will always be collected regardless of the flag value.
Transport & Delivery
Events are queued in memory and flushed:
- Every 5 seconds (periodic flush)
- When 20 events accumulate (queue size limit)
- On page unload via
navigator.sendBeacon()
Failed requests are retried once with a 1-second backoff. The transport uses fetch with keepalive: true for reliability during page transitions.
Privacy
The analytics script is designed to be privacy-friendly by default:
- No cookies — Session IDs use
sessionStorageonly (scoped to tab, cleared on close) - No PII — Never collects user IDs, emails, names, or IP addresses
- No third-party sharing — All data stays in your project's database
- Do Not Track — Respects
navigator.doNotTrackby default (opt out withdata-respect-dnt="false") - Country-level geo only — Derived from Cloudflare edge headers, not IP geolocation
- GDPR-friendly — Minimal data collection with anonymous sessions
Ingestion Pipeline
Events flow through a Cloudflare Worker at ingest.flaggr.dev/e:
- Validation — Payload size, event count, required fields
- Authentication — Site ID verified against project registry
- Enrichment — Country, browser, OS, device from request headers
- Session upsert — Page count incremented, duration calculated, flags merged
- Bulk insert — Valid events written to
analytics_eventstable
The worker responds with 202 Accepted and returns { accepted: N, rejected: M }.
Next Steps
- Analytics Dashboard — Interpret vitals, flag impact, and session data
- Analytics API Reference — Query analytics data programmatically
- Analytics & A/B Testing — Measure experiment outcomes with analytics