Tag JS API
Once the tag loads it exposes window.axo (window.vibeTag is a permanent alias). There is no pre-load queue: check that window.axo exists, or make calls after the load event. Personalization zones are authored declaratively with data-vt-* attributes.
Install
One deferred, first-party script before </head>. See Getting Started for the full install (Shopify, anti-flicker) and Site Speed for the load model.
<script src="https://axoapp.ai/tag.js?site=YOUR_SITE_ID" defer></script>Identify a visitor
// Call after login, checkout, or a form submit.
axo.identify({
email: "customer@example.com",
external_id: "usr_12345",
// any additional traits become profile attributes:
plan: "pro"
});Conversions & cart
// SPA / custom-flow escape hatch — fire the primary goal manually.
axo.convert(149.00); // optional revenue value
// Pass cart state so /api/convert can attach line items:
axo.setCart([
{ sku: "SKU-1", qty: 2, price: 24.0 },
{ sku: "SKU-2", qty: 1, price: 101.0 }
]);Custom events
Pair a custom event with a custom event conversion goal (Admin → Account → Conversion goals) to optimize for outcomes the tag cannot see on its own.
// Report a business fact only your code knows. A custom_event goal whose
// event_type matches fires exactly like a built-in goal.
axo.event("quote_started", { plan: "pro", seats: 12 });Read session state
axo.getSessionId(); // "sess_…" — current session UUID
axo.getVisitorId(); // "vis_…" — persistent, first-party cookie
axo.getSegment(); // "deliberator" — current primary segment
axo.lastRender(); // RenderSnapshot — per-zone outcome, for QA
// Fired once the visitor has been scored (detail: { segment_id, confidence }).
window.addEventListener('vt:segment_ready', (e) => console.log(e.detail));Single-page apps & hydrated frameworks
The tag runs after your page has rendered, so client-side rendering and hydration (React, Vue, Svelte, Hydrogen, Next.js, React Router) need no special setup. It hooks history.pushState / replaceState / popstate, and on every pathname change it records a new pageview, re-checks URL goals, re-attaches form tracking, and re-runs personalization against the freshly mounted DOM. Query-string-only changes do not count as a navigation. Because the tag swaps content in the DOM, a framework re-render that replaces a personalized node restores the original markup in that node — inspect axo.lastRender() when a variant appears to revert, and prefer zones whose container the framework does not re-create on state changes.
Method reference
| Method | Type | Description |
|---|---|---|
| axo.identify(traits) required | traits: object | Attach a known identity (email, external_id, arbitrary traits) to the current anonymous session. Merges cross-device sessions. No-op in preview and on passive-mode sites. |
| axo.convert(value?) optional | value?: number | Fire a conversion for the primary goal. The escape hatch for SPAs where no goal URL is navigated to. If value is omitted it is read from a [data-vt-revenue] element. No-op in preview or when consent has been denied. |
| axo.event(type, properties?) optional | type: string, properties?: object | Report a site-defined event (lower_snake_case, 2–64 chars; built-in names like form_submit are reserved). Lands in the event stream and fires any custom_event goal with a matching event_type. Properties are shallow primitives. No-op in preview or when consent has been denied. |
| axo.setCart(items) optional | items: LineItem[] | Persist cart state so the next convert attaches line_items (powers CAPI content_ids + the co-purchase recommender). |
| axo.getSessionId() optional | → string | The active session ID (UUID). |
| axo.getVisitorId() optional | → string | The persistent visitor ID (survives sessions, first-party cookie). |
| axo.getSegment() optional | → string | The current visitor's primary segment ID. |
| axo.getResumedContext() optional | → object | null | Context from a triggered-email token redemption (fire_id, cart resume URL, …) when the visitor lands via a ?vt_token= link. |
| axo.lastRender() optional | → RenderSnapshot | The last personalize pass, per zone (applied / holdout / no_variant / not_found / render_error) — for QA and DevTools. |
Authoring attributes
These data-vt-* attributes are part of the public authoring surface — add them to your markup so the tag can find zones and read commerce context without JS.
| Attribute | Type | Description |
|---|---|---|
| data-vt-zone optional | string | Marks an element as a named personalization zone (the DOM slot AXO can swap or fill). |
| data-vt-revenue optional | number | On a goal page, the conversion revenue to record. |
| data-vt-category optional | string | Tags the current page/product category for behavioral scoring and reco context. |
| data-vt-line-item optional | container | Marks a cart/line-item element; on the same element, data-vt-product-id / -sku / -url / -name / -quantity / -price supply its fields (a zero-config alternative to axo.setCart). |
| data-vt-breadcrumb optional | string | Supplies breadcrumb context for taxonomy and page-type detection. |
Consent
By default the tag runs in implicit-consent mode. To honor a visitor's refusal, set window.vt_consent = false (or the vt_consent cookie to denied) from your CMP, or enable AXO's built-in banner — see Privacy, Consent & Compliance. While consent is denied, behavioral events, convert, and event no-op; sites in passive mode additionally block identify so no PII leaves the browser.