Skip to content

Compass Web SDK: Integration Guide

Audience: Front-end and site developers integrating a publisher site with the Compass Web SDK.

The Compass Web SDK — published as @arcxp/compass-sdk and exposed in the browser as the global ArcCompass — is Arc XP’s first-party, client-side library for collecting reader interaction events (page views, video progress, clicks, and more) and posting them to the event collector. These events train the recommendation models.

It ships as a single bundled JavaScript file for <script> inclusion, and also as an npm ESM module for build-pipeline consumers (React / Next). The target is a roughly one-hour integration: paste a snippet, call init() once, resolve consent, and call track() for each event.

Quickstart

<script>
(function (w, d) {
w.ArcCompass = w.ArcCompass || { q: [] };
["init", "setConsent", "setUserId", "track", "flush"].forEach(function (m) {
w.ArcCompass[m] = w.ArcCompass[m] || function () { w.ArcCompass.q.push([m, [].slice.call(arguments)]); };
});
var s = d.createElement("script");
s.async = true;
s.src = "https://arc-rec.app-recommend.aws.arc.pub/arc-rec/v1/compass-sdk.iife.min.js";
d.head.appendChild(s);
})(window, document);
window.ArcCompass.init({
// Events collector base path for your org. The SDK appends `/events/batch`.
domain: "https://<org-id>-config-prod.api.arc-cdn.net/collect-web/v1",
apiKey: "<arc-delivery-token>",
});
// Single collect-for-personalization gate: pass true once your CMP reports
// consent. Nothing is sent or persisted until then.
window.ArcCompass.setConsent(true);
window.ArcCompass.track("page_view");
</script>

The rest of this guide walks through each step.

1. Provision a delivery token

Provision a delivery token through the Arc XP Delivery API — see Provisioning tokens through the Delivery API. The SDK sends this token as the X-API-Key header on every request.

Use a key scoped to the browser events collection (the collect-web API). That key can post events but cannot reach the content catalog, so it is safe to embed in page JavaScript.

2. Add the snippet

Place this block in <head>, before any code that calls ArcCompass.*:

<script>
(function (w, d) {
w.ArcCompass = w.ArcCompass || { q: [] };
["init", "setConsent", "setUserId", "track", "flush"].forEach(function (m) {
w.ArcCompass[m] = w.ArcCompass[m] || function () { w.ArcCompass.q.push([m, [].slice.call(arguments)]); };
});
var s = d.createElement("script");
s.async = true;
s.src = "https://arc-rec.app-recommend.aws.arc.pub/arc-rec/v1/compass-sdk.iife.min.js";
d.head.appendChild(s);
})(window, document);
</script>

The snippet defines a tiny stub on window.ArcCompass so calls made before the bundle loads queue up and replay in order.

The …/arc-rec/v1/… URL is major-pinned, so you receive backwards-compatible fixes automatically. For production, add Subresource Integrity (integrity + crossorigin) as shown in Distribution, which also covers exact-version pinning, the npm (ESM) install, and the self-host fallback.

3. Initialize the SDK

ArcCompass.init({
domain: "https://<org-id>-config-prod.api.arc-cdn.net/collect-web/v1",
apiKey: "<arc-delivery-token>",
});

domain is the browser events collector base path for your org: the shared <org-id>-config-prod.api.arc-cdn.net hostname followed by the collect-web/v1 prefix. The SDK appends /events/batch, so events post to https://<org-id>-config-prod.api.arc-cdn.net/collect-web/v1/events/batch. Arc provides the exact base URL during onboarding.

Translate whatever your CMP returns into the SDK’s single yes/no gate:

ArcCompass.setConsent(true); // collect-for-personalization granted

Events that fired before this call are flushed once consent resolves. Nothing is sent or persisted until then. See Consent & Identity for the full state machine.

5. Add the content and site meta tags

Add these tags to each page’s <head> so the SDK can attribute events to the right content and Site:

<!-- Required. The content item this page represents; it must match the ID the
content was ingested under. -->
<meta name="arc-compass:item-id" content="ARTICLE-ABC123" />
<!-- Optional. The Site this page belongs to — multi-site tenants only. -->
<meta name="arc-compass:site-id" content="the-daily" />

item-id must be present for automatic page_view capture to fire. You can override either value for a single event with track(type, { itemId, siteId }). See Events & Reliability for the full resolution order.

6. Track events

ArcCompass.track("video_progress", { itemId: "VIDEO123", eventValue: 0.75 });

page_view is captured automatically on load and on SPA route changes — you do not need to call track("page_view") yourself unless you disable auto capture (autoPageView: false). item_id and the optional site_id come from the meta tags you set above; pass itemId or siteId to track() to override them for a single event. See Events & Reliability.

7. (Optional) Set a known user ID after login

ArcCompass.setUserId("user-abc-123");
// Pass null on logout to revert to the persistent anonymous ID.
ArcCompass.setUserId(null);

A stable, host-managed ID is what makes personalization work across devices. See Consent & Identity.

Configuration reference

ArcCompass.init(options) accepts the following options. Only domain and apiKey are required.

OptionTypeDefaultDescription
domainstring— (required)Events collector base path for your org, e.g. https://<org-id>-config-prod.api.arc-cdn.net/collect-web/v1. No trailing slash. The SDK appends /events/batch.
apiKeystring— (required)Arc-provisioned delivery token scoped to the browser events (collect-web) collection. Sent as X-API-Key.
cookieDomainstringinferred eTLD+1 (e.g. .host.com)Cookie Domain attribute for the anonymous-ID cookie. Set explicitly for multi-subdomain sites.
batch.maxEventsnumber20Flush when the buffer reaches this many events.
batch.flushIntervalMsnumber2000Flush this many milliseconds after the last flush.
queue.maxBufferednumber500Hard cap on in-memory queued events. Oldest are dropped on overflow with a console.warn.
autoPageViewbooleantrueFire page_view automatically on load and SPA route changes, reading item_id from the <meta name="arc-compass:item-id"> tag (and the optional site_id from <meta name="arc-compass:site-id">). Set false to call track('page_view', { itemId }) yourself.
debugbooleanfalseLog lifecycle and transport diagnostics.
onError(e: ArcCompassErrorInfo) => void—Called when the SDK abandons a batch (a terminal 4xx/429, or a 5xx/network failure that exhausts retries). Use it to forward otherwise-silent data loss to your observability. See Error visibility.

Error visibility

The SDK is fire-and-forget: track() never throws, and a batch that the collector rejects (or that never gets through) is dropped rather than surfaced to the page. To make those drops observable, wire onError to your tooling — it fires only for terminal transport failures, off the user’s interaction path:

ArcCompass.init({
domain: "https://<org-id>-config-prod.api.arc-cdn.net/collect-web/v1",
apiKey: "<collect-web token>",
onError: (e) => {
// e: { message, reason: "rejected" | "exhausted", status?, droppedEvents, eventTypes, cause? }
Sentry.captureException(e.cause ?? new Error(e.message), { extra: e });
// or: datadogRum.addError(e.cause ?? new Error(e.message), e);
},
});

reason: "rejected" is a 4xx/429 the collector refused (fix the payload or key — retrying won’t help); reason: "exhausted" means repeated 5xx/network failures used up the retry budget. status is absent for network/CORS errors (no response). Per-event issues (an unresolved item_id, a coerced event_value) are logged only under debug, not through onError.

When cookieDomain is omitted, the SDK falls back to the last two labels of location.hostname (e.g. www.example.com → .example.com). This is correct for most single-suffix TLDs but cannot handle multi-segment public suffixes (e.g. .co.uk, .com.au, GitHub Pages) — set cookieDomain explicitly in those cases.

Browser support

The SDK assumes baseline support for fetch with keepalive: true, crypto.randomUUID (with a fallback when absent), visibilitychange, and localStorage / sessionStorage / cookies.

Tested matrix:

  • Chrome / Edge / Chromium ≥ 90
  • Safari / WebKit ≥ 14
  • Firefox ≥ 88

The SDK is browser-only. The IIFE bundle is safe to include in a server-rendered page — it no-ops on import when window is undefined.

See also