Browser installation & consent
Install with one script while keeping collection and integrations off by default
The browser bundle provides the same identity, session, attribution, retry, and autocapture behavior as the npm SDK without requiring a build step. It starts with analytics consent denied: no identifier is created, nothing is written to storage, and no event is sent until your site explicitly updates consent.
Copy-paste installation
Add the queue stub before the asynchronous bundle. Commands called while the bundle downloads are replayed in order after it initializes.
<script>
window.realanalytics = window.realanalytics || function () {
(window.realanalytics.q = window.realanalytics.q || []).push(arguments)
}
</script>
<script
async
src="https://cdn.jsdelivr.net/npm/@realanalytics/sdk@0.1.0/dist/browser.global.js"
data-public-key="pk_live_your_public_key"
></script>Fetching the example from jsDelivr is itself a third-party CDN request; denied SDK consent cannot suppress the browser's asset request. If your policy permits no CDN request before consent, serve the published bundle from your own origin or inject it only after your CMP permits it. The SDK API still starts with explicit consent denied in either setup.
A pk_live_ project key is public and is the only key that belongs in browser HTML. Never place an sk_live_ project secret in a script, browser environment variable, tag manager, or client bundle.
Connect your consent manager
Send the decision recorded by your CMP or consent banner. Analytics, advertising user data, and advertising personalization are independent purposes; do not infer the advertising decisions from analytics consent.
// Call after the visitor saves a decision in your CMP.
realanalytics('consent', {
analytics: true,
adUserData: false,
adPersonalization: false,
recordedAt: new Date().toISOString(),
source: 'cmp:your-provider'
})The values may be booleans or granted, denied, andunknown. The SDK stores the complete snapshot and attaches it to every event so later attribution uses the decision that existed when the event occurred.
Withdrawal
// Purges this project's local identity, session,
// attribution touchpoints, pending events, and offline queue.
realanalytics('optOut')Withdrawal also expires the SDK's first-party _fbp and_fbc cookies so a later grant cannot restore the withdrawn browser identity. Global Privacy Control and Do Not Track are respected by default and prevent an API call from overriding the browser signal.optIn() grants analytics only; both advertising purposes remainunknown. Use the complete consent object when your CMP exposes separate choices.
Track and identify
realanalytics('track', 'lead_created', {
form: 'hero'
})
// Use an internal opaque ID, not an email address or phone number.
realanalytics('identify', 'person_123', {
plan: 'pro'
})Calls made before analytics consent is granted are discarded rather than replayed later. After consent, the SDK preserves a project-scoped anonymous ID and stores the identified person ID separately so server conversions can join to the original landing-page touchpoint.
Verify the installation locally
const status = realanalytics.verify()
console.log(status.ready) // true
console.log(status.verification) // "local"
console.log(status.consent)
console.log(status.pendingEvents)verify() and status() only inspect local SDK state; they do not make a verification request. The bundle also emitsrealanalytics:ready and realanalytics:error custom events for an installation wizard or browser test. The ready event detail is sanitized and omits identity values; a direct local status call can include them for debugging.
window.addEventListener('realanalytics:ready', (event) => {
console.log(event.detail)
})
window.addEventListener('realanalytics:error', (event) => {
console.error(event.detail.message)
})Confirm delivery, then debugger observation
window.addEventListener('realanalytics:success', (event) => {
console.log('newly accepted', event.detail.acceptedEvents)
console.log('idempotent duplicates', event.detail.duplicateEvents)
console.log('still pending', event.detail.pendingEvents)
})
// Call after consent and after a real test-page action queues an event.
await realanalytics.flush()flush() waits for the current delivery attempts and retries to settle. Its completion alone is not a receipt. Arealanalytics:success detail reports exact receipt counts:acceptedEvents is newly accepted events,duplicateEvents is the sum of in-batch and previously accepted duplicates, and pendingEvents is work still held locally. Delivery failures or rejections use the saferealanalytics:error detail. An ambiguous or failed receipt can remain durably pending after flush() returns. Neither signal requires a secret or exposes event payloads and identifiers.
A receipt is separate from query visibility. Open the Event Debugger and search for the event name or event ID to confirm it is observable through the analytics query path. A duplicate receipt may refer to an event that was already visible.
Script configuration
| Attribute | Behavior |
|---|---|
data-public-key | Required project public key. data-key is also accepted. |
data-endpoint | Optional HTTPS ingest endpoint. HTTP is accepted only for local or .test hosts. |
data-autocapture | true or false; autocapture starts only after consent. |
data-config | Strict JSON containing only the three options above. |
The same fields can be assigned to window.realanalyticsConfigbefore loading the bundle; script attributes win. Consent and destination settings are rejected in loader configuration.
Integrations are optional
Meta, Google, and Attio are off by default. Installing the browser bundle does not connect or enable any destination. Attio is only an optional CRM conversion source; it is not required for browser or server tracking.