Skip to main content

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

AttributeDescription
data-site-idYour project ID. Used to associate events with your Flaggr project.

Optional attributes

AttributeDefaultDescription
data-endpointhttps://ingest.flaggr.dev/eCustom analytics ingestion endpoint
data-track-clicksfalseEnable click tracking on interactive elements
data-track-errorsfalseEnable JavaScript error tracking
data-track-scrollfalseEnable scroll depth milestone tracking
data-respect-dnttrueRespect the browser's Do Not Track setting
data-debugfalseEnable [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 path
  • title — Document title
  • referrer — Referring page
  • viewportWidth, viewportHeight — Browser viewport dimensions
  • connectionType — Network connection type (if available)

Web Vitals (always on)

Collected via PerformanceObserver. Each vital includes a numeric value and a rating:

MetricGoodNeeds ImprovementPoor
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 element
  • tag — HTML tag name
  • text — Button/link text (truncated to 100 characters)
  • trackId — Value of data-track attribute, if set on the element
  • href — 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 message
  • source — Source file
  • line, column — Error location
  • stack — 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

  1. window.__FLAGGR_BOOTSTRAP__ — SSR-injected flag values (set by Next.js server components)
  2. window.__FLAGGR_FLAGS__ — Live SDK state (updated after client-side evaluation)
  3. flaggr:flags-changed event — 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:

LevelCollects
"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 events
  • 1 — 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 sessionStorage only (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.doNotTrack by default (opt out with data-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:

  1. Validation — Payload size, event count, required fields
  2. Authentication — Site ID verified against project registry
  3. Enrichment — Country, browser, OS, device from request headers
  4. Session upsert — Page count incremented, duration calculated, flags merged
  5. Bulk insert — Valid events written to analytics_events table

The worker responds with 202 Accepted and returns { accepted: N, rejected: M }.

Next Steps