Web SDK reference
Client options, methods, events, React bindings and errors of @voidhash/web.
Everything createVoidhashClient accepts and the client exposes. To install the SDK, see
Web SDK.
Client options
| Option | Default | Description |
|---|---|---|
publishableKey | none | Required. Your project's vh_pk_... or vh_pk_test_... key. |
baseUrl | https://api.voidhash.com | API origin: a first-party proxy, tracking domain or self-hosted deployment. |
analyticsConsent | "granted" | Initial consent: "granted", "denied" or "pending". A choice stored by setAnalyticsConsent() wins unless analyticsConsentSource is "app". |
analyticsConsentSource | "sdk" | "app" makes your consent tool the only consent source and starts every page at "pending". See Use a consent tool. |
storeBeforeConsent | true | false keeps the SDK's state in memory until consent is granted. See Ask for consent first. |
crossSubdomainIdentity | false | true shares the anonymous ID across your subdomains in a cookie. See Keep one visitor across subdomains. |
distinctId | Stored or new anonymous ID | Starts the client as this ID. Usually omit it and call identify(). See Seed the identity. |
onDiagnostic | none | Called for every SDK diagnostic. See Diagnostics. |
analytics | See below | Page view and event delivery options. |
featureFlags | See below | Feature flag options. |
analytics fields:
| Field | Default | Description |
|---|---|---|
capturePageViews | true | Records $pageview on load and after each client-side navigation. Campaign attribution is always recorded. |
capturePageLeaves | capturePageViews | Records $pageleave with time on page, scroll depth and Web Vitals. See Page engagement. |
captureOutboundClicks | true | Records $outbound_click with the target origin only. |
beforeSend | none | Function, or list of functions, editing or dropping each event. See Edit or drop events. |
sanitizeUrl | none | Rewrites an address, or returns null to keep a page out. See Keep pages out by address. |
enabled | true | false turns analytics off, as if consent were denied, without storing a choice. |
baseUrl | Client's baseUrl | Origin for analytics only. |
flushIntervalMs | 5000 | Send interval for queued events, in milliseconds. |
maxBatchSize | 20 | Events per request, at most 100. A full batch is sent at once. |
maxBatchBytes | 262144 | Maximum bytes of events per request. A larger event is sent on its own. |
maxQueueSize | 1000 | Events kept while offline; the oldest are dropped first. |
featureFlags fields:
| Field | Default | Description |
|---|---|---|
defaults | none | Values before evaluation, such as { "new-checkout": true }. Others read as false. |
maxWaitMs | 2000 | How long an uncached read waits for Voidhash, in milliseconds. 0 never waits. |
ttlMs | 300000 | Age after which cached flags are refreshed, in milliseconds. |
persist | true | Keeps flags in localStorage for the next page load. |
prefetchOnInit | false | Evaluates every flag in the background during initialize(). |
refreshOnOnline | true | Refreshes flags when the browser reconnects, at most once a minute. |
refreshOnVisibility | true | Refreshes flags when the tab becomes visible, at most once a minute. |
createVoidhashClient throws VoidhashConfigurationError for a missing or secret key, a
non-absolute or non-http(s) URL, an unknown consent value or source, a non-function beforeSend
or sanitizeUrl, a size or interval that isn't a positive integer, or non-boolean defaults.
Blank strings count as not set.
Client methods
Methods that return a promise wait for a running initialize(). They reject with
VoidhashNotInitializedError if it was never called, and with VoidhashDestroyedError after
destroy(). Only setPersonAttributesSync() rejects on network failure; everything else queues or
answers from the cache.
| Method | Returns | Description |
|---|---|---|
initialize() | Promise<void> | Loads saved state and starts the SDK. Safe to call more than once. |
destroy() | Promise<void> | Sends what it can, removes listeners and stops the client for good. Called during initialize(), it records no page view. |
track(name, properties?, options?) | Promise<void> | Queues a product event. See Track events. |
page(name?, properties?, options?) | Promise<void> | Records a $pageview yourself. See Page views. |
identify(userId, traits?) | Promise<void> | Switches to your user ID and links the visitor in the background. See Identify users. |
signOut() | Promise<void> | Records $sign_out, then starts a new anonymous identity and session. |
reset() | Promise<void> | Starts a new anonymous identity and session without recording a sign-out. |
setPersonAttributes(attributes) | Promise<void> | Queues person attributes with the events. Needs analytics consent. |
setPersonAttributesSync(attributes) | Promise<VoidhashPerson> | Writes attributes now and returns { personId, distinctId, email, name }. Rejects after 10 seconds without an answer. |
getDistinctId() | string | undefined | The current anonymous or identified ID; undefined before initialize() resolves. Put it on payments. |
getSessionId() | string | undefined | The session the next event joins; undefined without consent or after 30 idle minutes. |
setAnalyticsConsent(consent) | Promise<void> | Stores and applies the visitor's choice. Works before initialize(). See Privacy and consent. |
getAnalyticsConsent() | AnalyticsConsent | The consent in effect. Always "denied" while analytics.enabled is false. |
setAdDataSharing(granted) | Promise<void> | Records whether the person agreed to share purchases with ad platforms. See Meta ads. |
playStoreUrl(packageName) | string | A Google Play link carrying the latest campaign. See Web-to-app handoff. |
pauseAnalytics() | void | Stops recording until resumeAnalytics(). Works before initialize(). See Pause recording. |
resumeAnalytics() | void | Records again after pauseAnalytics(). |
isAnalyticsPaused() | boolean | Whether recording is paused. |
flushAnalytics() | Promise<AnalyticsFlushStatus> | Sends queued identity links and events, waiting at most 2 seconds. Resolves with { flushed, pending, lastError? }. |
getFeatureFlags(keys?) | Promise<FeatureFlagsResult> | Evaluates flags, cache first. See Feature flags. |
refreshFeatureFlags(keys?) | Promise<FeatureFlagsResult> | Evaluates flags from the network. |
isFeatureEnabled(key) | boolean | The last evaluated value, or the flag's default. Throws before initialize() and after destroy(). |
getFeatureVariant(key) | FeatureFlagEntry | undefined | The last evaluated entry; undefined until evaluated. Throws before initialize() and after destroy(). |
on(event, handler) | () => void | Subscribes to a client event. Returns the unsubscribe function. |
off(event, handler) | void | Removes a handler added with on(). |
onDiagnostic(handler) | () => void | Same as on("diagnostic", handler). |
The React bindings also use three public methods you rarely need:
peekDistinctId()returnsgetDistinctId()'s ID without handing it to your app. That matters only withcrossSubdomainIdentity, where an ID your app has read stays on the device.getConfiguredAnalyticsConsent()returns the configured consent, ignoring any stored choice, so a server render and the first client render agree.isFeatureEnabledByDefault(key)returns the flag'sfeatureFlags.defaultsentry, orfalse.
isAnonymousDistinctId(id), exported from @voidhash/web, tells whether an ID is an anonymous
vh_anon_... ID.
Client events
| Event | Payload | When |
|---|---|---|
initialized | { distinctId } | initialize() has finished. |
identity-changed | { distinctId, previousDistinctId } | After identify(), signOut() or reset(). |
analytics-consent-changed | { consent } | Consent changed, in this tab or another one. |
analytics-flushed | { accepted, rejected, requestId? } | A batch was delivered. |
analytics-partial-rejection | { accepted, rejected, requestId? } | Voidhash refused some events of a batch. |
feature-flags-updated | { distinctId, keys?, result } | New flag values arrived for distinctId. |
diagnostic | VoidhashDiagnostic | See Diagnostics. |
error | { source, message, error? } | A background task failed, such as a scheduled flush. |
React
@voidhash/web/react exports a provider and three hooks. This separate entry point is marked
"use client"; pages without React never load it.
import { VoidhashProvider } from "@voidhash/web/react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
createRoot(document.getElementById("root")!).render(
<VoidhashProvider config={{ publishableKey: "vh_pk_..." }}>
<App />
</VoidhashProvider>,
);VoidhashProvider takes either config or client, read once on mount:
config: the provider creates the client, initializes it on mount and destroys it on unmount. React Strict Mode's remount keeps the same client.client: the provider initializes your client and never destroys it, so code outside React can share it.
| Hook | Returns |
|---|---|
useVoidhash() | { client, status, isInitialized, initError, retryInit, distinctId }. status is "initializing", "ready" or "failed"; distinctId follows identity changes. |
useAnalytics() | { track, page, flushAnalytics, consent, enabled, setAnalyticsConsent, setAdDataSharing, pauseAnalytics, resumeAnalytics }. Follows consent in other tabs. |
useFeatureFlags(keys?) | { data, isEnabled, getVariant, isLoading, isStale, isExpired, error, refetch }. See Feature flags. |
Hooks throw outside a VoidhashProvider. If initialize() fails, for example because browser
storage is blocked, status is "failed", initError says why and retryInit() tries again.
Analytics never block rendering, so most apps render normally in every status.
Errors
Rejections are VoidhashError instances exported from @voidhash/web, such as
VoidhashNotInitializedError or VoidhashInvalidArgumentError. Background work reports through
diagnostics instead. Errors lists every class, code and diagnostic.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.