Configuration Reference
Complete reference for all Mythic Analytics JavaScript SDK configuration options including network, auto-capture, privacy, consent, HIPAA, and more.
Configuration reference
The full set of options you can pass to init(key, config).
Network and batching
Base URL for API calls. Default: https://api.adberserk.com (auto-detected from the host the loader script was served from). Change this if you use a custom domain or proxy.
Number of events to queue before sending. Default: 10.
Milliseconds between automatic flushes. Default: 2000.
Custom headers to include with every network request.
Auto-capture
Enable automatic capture of clicks and form submissions. Default: true, which captures links and forms only — note buttons is not in the default set, so <button> clicks need { elements: [...] }. Pass an object to choose element types: { elements: ['links', 'forms', 'buttons'] }. Valid types: links, forms, buttons, inputs, selects, textareas, changes.
A per-location override set through the Settings API (PUT /client/v1/settings/autocapture) takes precedence over this option, so an agency can turn autocapture off or change its element types without editing this snippet. The override does not reach sites that set disable_remote_config: true.
Auto-capture a $pageview event on page load. Default: true.
Auto-capture page views on SPA navigation (History API pushState/replaceState). Default: true.
Auto-capture a $pageleave event with time-on-page and exit intent data. Default: true.
Auto-capture UTM parameters and advertising click IDs from the URL. Default: true.
Track text copied to clipboard. Default: false.
Privacy and persistence
Storage strategy. Options: 'localStorage', 'cookie', 'memory', 'localStorage+cookie'. Default: 'localStorage+cookie'.
'localStorage+cookie' mirrors only the visitor IDs (distinct_id,
device_id) to cookies. Super properties stay in localStorage.
When the browser blocks localStorage (private browsing, Firefox Focus), the
localStorage modes degrade to tab-scoped sessionStorage — a multi-page visit
keeps one device/session id (and one session replay) instead of minting fresh
ids on every navigation, while nothing outlives the tab, honoring the
browser's privacy stance. If sessionStorage is also blocked, 'localStorage'
falls to memory and 'localStorage+cookie' to cookies. Explicit 'memory'
is never escalated.
Custom prefix for storage keys. Defaults to {globalName}_{key}_.
Honor the browser's Do Not Track setting. Default: false.
Start with tracking disabled. Requires explicit opt_in(). Default: false.
Consent
When true, no events are sent until grantConsent() is called. Default: false.
Automatically sync consent from Google Consent Mode v2 via the dataLayer. When enabled, forces requireConsent: true. Pass an object for custom settings: { enabled: true, consentParam: 'analytics_storage', dataLayerName: 'dataLayer' }.
Identity
Allow calling identify with a different user ID after one has already been set. Default: false — re-identification is blocked to prevent accidental merges. Call reset() before identifying as a different user, or set this to true to permit switching identities directly. (An identity previously set only by auto-capture can always be overridden by a later identify().)
Tracking the same visitor from a second surface on the page — a Shopify Web Pixel, an embedded widget — and need both to resolve to one person? See the Identity Storage Contract.
Session
Session timeout in milliseconds. After this period of inactivity, a new session starts. Default: 4 hours (14400000).
Debugging
Enable verbose console logging. Default: false.
Even more detailed logging (includes internal state). Default: false.
Log events to console instead of sending them. Useful for development. Default: false.
HIPAA compliance
Enable HIPAA mode. Applies a hipaaFilter to all outgoing events (whitelists safe properties, redacts PHI from URLs, and drops $set/$set_once person-property mutations) and force-disables autocapture, form identification, input capture, framework extraction, GTM sync, booking/survey listeners, network interception, geolocation, cross-domain tracking, web vitals, error tracking, and cookies. It also forces respect_dnt, mask_all_text, mask_all_element_attributes, disable_remote_config, and persistence: 'localStorage'. These overrides are immutable — updateConfig() cannot re-enable them. Default: false.
Prevent loading server-defined configuration from the /decide endpoint: tags, snippets, transformers, and the per-location session_replay, error_tracking, and autocapture overrides. Setting this cuts the site off from server-side control, so those overrides can no longer be changed without editing the snippet. Force-enabled in HIPAA mode. Default: false.
Maximum hours to retain data in local storage; stale data is purged on init. Default: 24 in HIPAA mode, 0 (disabled) otherwise.
HIPAA mode reduces the risk of sending sensitive data but does not guarantee compliance. Review your event schemas and legal requirements with your compliance team.
Masking
Mask text content in autocaptured events. Force-enabled in HIPAA mode.
Mask element attributes in autocaptured events. Force-enabled in HIPAA mode.
Callbacks
Called with the Mythic instance after initialization completes. Signature: (instance) => void.
Transform or filter events before sending. Return the event to send it, or null to drop it. Signature: (event) => event | null.
Modify properties before they are attached to an event. Signature: (properties, eventName) => properties.
Called when a network request fails. Signature: (error) => void.
Advanced auto-tracking
Automatically identify users from email fields on form submission. Default: true.
Capture email addresses as they are typed into input fields. Default: true.
Automatically detect and track booking API calls (LeadConnector, Calendly, Acuity). Default: true. Fires appointment_booked, calendly_booked, or acuity_booked.
Automatically track survey submission API calls (LeadConnector, Typeform, SurveyMonkey). Default: true. Fires survey_completed, typeform_submitted, or surveymonkey_completed.
Intercept fetch/XHR requests to the endpoints listed in network_endpoints and capture them as events. Default: false.
Custom endpoints to monitor when auto_network_intercept is enabled. Each entry: { url, method?, event_name, event_prefix?, extract_fields? }. url supports wildcards (e.g. */api/checkout).
Extract page context from frameworks (Nuxt, Next.js, React, Vue, Angular). Default: true. Pass an object for control: { enabled: true, framework: 'auto', extract_properties: ['funnelId', 'pageId'] }.
Sync events to Google Tag Manager's dataLayer. Default: true.
Buffer events until framework extraction completes so the first $pageview includes framework-detected properties. Default: true when auto_framework_extract is enabled. A 2-second safety timeout prevents indefinite blocking; set to false to opt out of buffering.
Web Vitals
Capture Core Web Vitals (LCP, FID, CLS, FCP, TTFB, INP). Default: false. Pass an object for fine-grained control: { enabled: true, metrics: ['LCP', 'CLS', 'INP'], sample_rate: 0.5 }.
Error tracking
Capture uncaught JS errors and unhandled promise rejections as $exception events (with type, message, and stack). Default: true. Grouping into issues happens in the read layer; the SDK ships the raw fields. Force-disabled under HIPAA.
A per-exception-type token bucket keeps a page that throws in a loop from flooding ingestion: each error type gets burst events, then one every refillSeconds, while other types keep their own budget. Pass an object to tune it: { burst: 10, refillSeconds: 10, maxPerPage: 100 } (maxPerPage is a coarse backstop across all types). When errors are suppressed, the next $exception that gets through carries an $exception_suppressed count.
Capturing load-time errors requires early placement. The loader installs its error listeners synchronously when it runs and buffers anything thrown before the SDK core finishes loading. But it can't see errors thrown before the loader itself executes — so if you inject the loader through a tag manager (e.g. GTM), that tag manager's own init errors are missed. Load the loader directly in <head>, above the tag-manager container, to capture them. See the installation note.
This setting is also server-controllable: a per-location override is served via remote config and, when set, wins over this init value (HIPAA still forces it off).
Session replay
Record user sessions (DOM, console, and network activity) with rrweb for later playback. Default: false (off). Pass true to enable with defaults, or an object for control:
enabled(boolean) — turn recording on. Default:false.sampleRate(number, 0–1) — fraction of sessions to record, decided deterministically per session ID. Default:1.sampleRules(array) — per-traffic sample rates, matched against the query string of the URL the session landed on. Each rule is{ param, value?, sampleRate }:paramis a query parameter name,value(optional, case-insensitive) narrows the match, andsampleRateis the fraction of matching sessions to record. The first matching rule wins; sessions that match none usesampleRate. Example, every Mythic link click plus 10% of the rest:{ sampleRate: 0.1, sampleRules: [{ param: 'iiid', sampleRate: 1 }] }.minDurationMsstill applies to matched sessions.minDurationMs(number) — only keep a recording once the session has lasted this long (measured on session age, across page loads). Events buffer from the start, but nothing is transmitted (and no recording appears) until the threshold is crossed, so shorter bounce sessions send zero data. Default:10000(10s); set0to keep every recording.maskAllInputs(boolean) — mask all form input values. Default:true.captureConsole(boolean) — recordconsolelog/warn/error calls. Default:true.captureNetwork(boolean) — record fetch/XHR/resource timing (a waterfall). Default:true.recordNetworkHeaders(boolean) — include request/response headers. Default:false.recordNetworkBody(boolean) — include response bodies (capped at 10 KB). Default:false.blockSelector(string) — CSS selector for elements to exclude from the recording.maskTextSelector(string) — CSS selector for text nodes to mask.flushEventThreshold(number) — buffered events before an upload. Default:100.flushIntervalMs(number) — maximum milliseconds between uploads. Default:5000.
Session replay is normally turned on per client from the server (via the /decide remote config). The server value wins over your local config: an explicit server enabled: false disables recording even if you pass enabled: true here, and recording only starts after remote config loads. Recording is blocked entirely for HIPAA locations. Recorded sessions are read back through the Data API and expire after 30 days.
Heatmaps
Capture click positions and scroll depth for heatmaps. Default: false (off). Pass true to enable with defaults, or an object for control:
flushIntervalMs(number) — maximum milliseconds between batches. Default:5000.maxBufferPoints(number) — hard cap on points per interval. Points past it are dropped (and counted in$heatmap_droppedon the event) rather than triggering an early send, so a page emits at most one$heatmapevent per interval no matter how much clicking happens on it. Default:200.
This is not the same thing as autocapture. Autocapture records which element was clicked — its text, href, classes. This records where on the page, plus a structural description of the clicked element so heatmaps stay correct on pages that change after load: tag, a stable id, up to two classes, its position among same-tag siblings, an identifier-style data-* attribute, and a link's path. It never reads element text or query strings. Enable either, both, or neither.
Points ride the normal event pipeline as a batched $heatmap event, so consent gating, before_send, and opt-out apply exactly as they do to any other event. Clicks on position fixed/sticky elements are flagged so a heatmap renderer can place them correctly instead of streaking one sticky nav down the whole page. Scroll depth is measured once per page per session, when the visitor leaves it.
Heatmap capture is normally turned on per client from the server (via remote config — PUT /client/v1/settings/heatmaps), which is how an agency enables it on a site whose install snippet it can't edit. The server value wins over your local config. It is blocked entirely for HIPAA locations, and it is not retroactive: turning it on collects from that moment, with no backfill of past traffic.
A/B experiments
Detect that a third-party split-testing tool has bucketed this visitor and attach the assignment to the session. Default: true (on). Supported platforms: Convert.com, PostHog experiments and Mida. Pass false to disable, or an object for control:
trackExposures(boolean) — emit the$experiment_viewedevent. Default:true.pollWindowMs(number) — how long after init to keep re-reading the testing tool's cookie, in milliseconds. The tool usually buckets within a second; the window exists because it runs after the SDK on a normal page load. Default:10000.dataLayerName(string) — the dataLayer global to observe. Default:'dataLayer'.
Nothing needs tagging on the page. Every event after detection carries two super properties — $experiments (an array of arms) and $ab_platform (convert, posthog, mida, or a +-joined list such as convert+mida when several tools run on one page) — and each assignment produces one $experiment_viewed event per session, with experiment_id, variation_id, and variation_name / experiment_name where the tool exposes them.
An arm reads "<experimentId>:<variationId>" for Convert.com, "posthog:<flagKey>:<variant>" for PostHog and "mida:<testId>:<variant name>" for Mida (for example mida:36816:Variant 1 or mida:36816:Control). Convert arms carry no platform prefix, so filters written against Convert assignments keep working unchanged.
Convert.com assignments are read from its own cookie, which holds the authoritative experiment-to-variation mapping and is already populated for visitors who arrived through a split-URL redirect; its dataLayer announcement is observed as well, to catch bucketing that happens later in a single-page app and to pick up variation names.
PostHog assignments are read from posthog.js's own persisted state (ph_<projectToken>_posthog__flags for the flags, ph_<projectToken>_posthog for the visitor id and any local overrides), refreshed through the public posthog.onFeatureFlags subscription when flags load or reload. A redirect-style split test needs nothing extra: the flag is already stored by the time the variant page loads, so the assignment is attached before that page's first pageview. A flag counts as an experiment when PostHog reports it as experiment-linked, and otherwise when it is multivariate: boolean feature flags are rollouts, not tests, and are excluded, so a kill switch does not become an arm on every event. Flags you have overridden locally (overrideFeatureFlags(), or the PostHog toolbar) are skipped as QA. The SDK never calls getFeatureFlag() or isFeatureEnabled() — those would write $feature_flag_called events into your PostHog project.
Mida assignments are read from Mida's own stored assignment (_variant_result, in localStorage, or sessionStorage when Mida runs in cookie-banner mode) and its cached test list, which supplies the test name and drops tests that have stopped or are serving a winner to everyone. Mida's variant names are the variation ids, and personalization campaigns are not counted as experiments. Nothing of Mida's is patched or called.
Sessions the SDK identifies as bots record no assignment — a crawler executing a testing tool would otherwise count as an exposure in whichever arm it landed in.
On a page with no testing tool this costs one cookie read and one localStorage scan: no properties are published, and your dataLayer is not touched or created. Observers are only attached once a testing tool has actually been detected.
Sessions in the tool's visual editor or with a forced variation (Convert's convert_action, _conv_eforce, visualEditor parameters; Mida's test-preview, test-variant, editor parameters) are treated as QA and record no assignment — counting them would inflate whichever variation the tester picked.
This is the one feature where the server override can only turn things off. PUT /client/v1/settings/experiments with false disables detection (and un-publishes $experiments), but enabling it there takes effect late: the SDK sends its first $pageview before remote config loads, and for a split-URL test that pageview is the exposure. Leave the default in place on sites you want measured. Detection is blocked entirely for HIPAA locations.
Conversion forwarding
Forward Mythic conversion events to the visitor's testing tool so its own experiment readout gets credited — the client maintains the conversion once, in Mythic, instead of tagging goals in both systems. Default: false (off). Pass true or an object:
goals(object, required to do anything) — maps Mythic event names to the tool goals to notify:{ goals: { order_completed: [{ platform: 'convert', goalId: '<dashboard goal id>' }], signup: [{ platform: 'mida', name: 'signup_completed' }], purchase: [{ platform: 'growthbook', name: 'purchase' }] } }oncePerSession(boolean) — forward each goal at most once per session. Default:true.maxPerSession(number) — hard cap on forwards per session. Default:10.
Platform support: Convert.com (goalId is the dashboard goal id; queued through Convert's _conv_q so it works whether Convert loads before or after us), Mida (name is the event name of a Mida event goal; queued as a track command on Mida's mdq queue, so it works whether Mida loads before or after us), GrowthBook (.track(name)), and a generic custom platform that dispatches a mythic:ab_conversion CustomEvent on window for tools without a native adapter. VWO is not wired yet — its programmatic goal API is unverified, and guessed API shapes produce silent no-ops.
Forwarding rides the normal capture pipeline: consent gating, opt-out, HIPAA mode, and before_send all apply. A tool that loads after the conversion still receives it (Convert and Mida replay queued commands on init). An absent or failing tool does not consume the once-per-session slot — the next matching event retries.
This one is server-toggleable in both directions: unlike A/B detection, nothing here needs to beat the first pageview. Enable or disable it per location with PUT /client/v1/settings/conversions.
Geolocation
Enrich events with IP-based geolocation data. Default: enabled at city level. Pass an object for control: { enabled: true, level: 'country' | 'region' | 'city', cache_duration: 86400000, api_endpoint: '...' }. cache_duration is in milliseconds (default 86400000, 24 hours). Set api_endpoint: false to skip the external lookup API, or set the whole option to false to disable geolocation.
Cross-domain tracking
Track users across domains by decorating links with session IDs. Opt-in only. Default: false. Pass { enabled: true, domains: ['app.example.com', 'docs.example.com'] }.
Rate limiting
Client-side rate limiting. Example: { events_per_second: 10, events_burst_limit: 50 }.
Properties and forms
Properties merged into every event from initialization. Equivalent to calling set() at startup. Default: {}.
CSS selector for forms tracked by auto_form_identify. Default: 'form, .c-form, [data-form]'.
Field names to strip from captured form/network data (passwords, tokens, card numbers, etc.). Your list is used in place of the built-in defaults.
Maximum size, in characters, of captured network/form payloads. Default: 6000.
Maximum length for individual string property values. Default: 65535.
Completely disable tracking. Default: false.
Disable localStorage and cookies, keeping data in memory only. Default: false.