Custom events, session tags and request tracing
This page is for a web developer who wants to add context to what Noxtica records: named events from your own code, tags and a hashed identity on a session, and a trace header that links a browser request to your backend. A tenant administrator allow-lists what the domain accepts.
What it is
Availability depends on your plan, role and the modules enabled for your organisation. Events and tags ride on the behavior analytics and session replay lanes, which run when enabled for your organisation.
| API | Where you call it | What it does |
|---|---|---|
track(name, properties) | window.noxticaClient | Sends a custom app event. The domain’s allow-list decides what is kept. |
noxtica('event', name, value) | Command queue | Adds a replay timeline marker and sends an app event named name with a value property. |
noxtica('set', key, value) | Command queue | Tags the session with a key and one or more values. |
noxtica('identify', id, { hint }) | Command queue | Links the session to a hashed identity. The raw id never leaves the page. |
noxtica('metadata', callback, options) | Command queue | Hands your code the Noxtica session ids. |
noxtica('upgrade', reason) | Command queue | Asks replay to start now, within the policy. |
withRequestSpan(url, callback) and spanFetch(url, init) | window.noxticaClient | Add a W3C traceparent header to a request to an allow-listed origin. |
The command queue also takes pause, resume, stop, start and consent. The queue is documented in Client API, events and the command queue.
Three limits shape everything on this page:
- Events and tags are not delivered when the visitor has not consented to the
analyticscategory (events) orreplaycategory (tags and the replay timeline) in a consent-gated mode. - A visitor who sends Do Not Track or Global Privacy Control is excluded when the domain policy is Honor.
- Nothing here bypasses consent, sampling or the replay minimum duration.
Prerequisites
- Scripts. The core and extensions scripts load on the page. The tracker, replay and session API run from the extensions. See Install & Browser Runtime.
- Events. The domain’s Tracker switch and its App events switch are on, and the domain has an allow-list. The Admin role changes them.
- Tags and the timeline. Replay is armed for the domain. See Session replay: setup, masking and playback.
- Tracing. The domain lists the exact origins that may receive a trace header. The Admin role and a fresh step-up verification change the list.
- Consent. Your banner grants the categories the features need. See Consent modes, GPC and Google Consent Mode.
Steps
1. Define the command queue before the core script
<script>
window.noxtica = window.noxtica || function () {
(window.noxtica.q = window.noxtica.q || []).push(arguments);
};
</script>
The core replays queued calls in order once it starts, then replaces the stub with a live function. An unknown command name logs a warning and does nothing. A failing call reports through the noxtica:error event and never throws into your code.
2. Allow-list events and properties
Backoffice → Administration → Domains → open the domain → Configuration → Tracker policy. Switch on the domain’s Tracker and App events. The Tracker switch is also in the Tracker column of the Domains list.
Backoffice → Web Analytics & Privacy → Tracking Allowlists → Tracker app-event allowlists.
- Pick the domain.
- Choose Restrict to an allowlist under Event name allowlist and add names such as
checkout_completed. - Do the same under Property key allowlist for keys such as
plan. - Select Save allowlists and complete the step-up verification.
How the lists act:
| Mode | Behaviour |
|---|---|
| Accept all (legacy default) | Every name and property is accepted. Domains created before the allow-list existed start here. |
| Restrict to an allowlist | An event whose name is not listed is dropped on the server, and the rest of the batch is unaffected. A property key that is not listed is stripped, and the event is kept. |
| Deny-all | An empty restricted list. Every event is dropped. A newly created domain starts here. |
Each list holds up to 200 entries of up to 128 characters. A save over the limit is rejected, never truncated. The data of one event is limited to 1 KB.
3. Send events
// A custom event with properties. Throws a TypeError for an invalid shape.
window.noxticaClient.track('checkout_completed', { plan: 'pro' });
// A timeline marker plus an app event named 'coupon_applied'.
noxtica('event', 'coupon_applied', 'SPRING');
trackneeds a non-empty string name and a plain object forproperties.noxtica('event', name, value)takes a name up to 128 characters. The value is a string (cut at 256 characters), a finite number or a boolean. The event reaches the app-event lane astrack(name, { value }), so listvaluein the property allow-list to keep it.- The browser buffers up to 50 events and flushes about every 10 seconds.
- Timeline markers appear in the recording while the recorder is active.
4. Tag sessions
Allow the keys before you set tags. Backoffice → Web Analytics & Privacy → Capture Policies → Session replay policy → Session tag keys (allow-list): up to 32 keys. An empty list turns tags off for the domain.
noxtica('set', 'plan', 'pro');
noxtica('set', 'cohort', ['north', 'eu']);
| Rule | Limit |
|---|---|
| Key pattern | A-Z a-z 0-9 _ . : -, 1 to 64 characters |
| Value | A string, number or boolean, up to 255 characters |
| Values per key | Up to 128 distinct values |
| Keys per session | Up to 32 |
A call replaces the values of that key. An empty list removes the key. An invalid key throws a TypeError. A key that is not on the allow-list is dropped. Tags are free text. The server redacts values that look like email addresses or long digit runs, and you should not put personal data in a tag. Tags are attached to the recorded session and need an active recorder.
5. Identify a session without sending the raw id
noxtica('identify', 'user-8841', { hint: 'us' });
noxtica('identify', null); // clear the identity
The browser sends the SHA-256 of the trimmed id (lowercase hex) and a 2-character hint, such as us***. The id may be up to 256 characters. If the browser has no WebCrypto, which is the case on an insecure page, the call does nothing and the raw id is still never sent.
This is the session identity. It is separate from the account id that links a device to a verdict, which you set with window.noxticaClient.setAccountId(id). See Client API, events and the command queue.
6. Read the Noxtica session ids
noxtica('metadata', function (meta) {
// meta.sessionId, meta.replaySessionId (null until a recording starts),
// meta.pageId, meta.consent
myLogger.setContext({ noxticaReplay: meta.replaySessionId });
}, { wait: true, recall: true });
wait defers the call until a replay session id exists. recall calls it again whenever the id changes.
7. Start replay now, within the policy
const result = noxtica('upgrade', 'support-chat-opened');
The call returns started, already_recording, pending_consent or refused. The reason uses the tag-key pattern. It never grants consent, never overrides Do Not Track or sampling, and the minimum duration still applies.
8. Allow-list trace origins
Backoffice → Web Analytics & Privacy → Tracking Allowlists → RUM trace controls → Trace-origin allowlist. Add an exact origin: https://host with an optional port, with no path and no wildcard. An IP address is rejected, except loopback addresses for local development. The list holds up to 20 origins. Select Save trace controls.
9. Trace a request
const client = window.noxticaClient;
// Option A: you control the request.
await client.withRequestSpan('https://api.example.com/orders', async ({ headers, span }) => {
const res = await fetch('https://api.example.com/orders', { headers });
span.end(res.ok ? 'ok' : 'error');
});
// Option B: let Noxtica issue the request.
const { followed, response, span } = await client.spanFetch('https://api.example.com/orders');
- For an allow-listed origin,
headers.traceparentis set (tracestatemay be present). For any other origin the callback still runs with empty headers and a no-op span, and the request is not blocked. - There is no global fetch or XHR patch. You opt in per call.
- The ids are fresh W3C ids. No Noxtica session, tenant or user id enters the header.
- A span ends as
okwhen your callback finishes. A throwing callback ends it aserrorand the error is rethrown. An async callback is awaited for up to 5 seconds. spanFetchnever follows a redirect. On a 3xx it returnsfollowed: falseand an opaque response. Start a new call for the redirect target.
Your backend continues the trace by reading the traceparent header. If it exports OpenTelemetry data to Noxtica, see APM and the ingestion service (OTLP).
10. Tag releases
Pass release and buildId when you create the client. See Browser errors, console logs and source maps.
Verify it works
- In Backoffice → Session Insights → Behavior Analytics → Overview, the App events feature shows counts after a visit.
- In a replay of the session, the timeline shows your
eventmarkers, and the session shows your tags. - In the browser network panel, a request to an allow-listed origin carries a
traceparentheader. A request to another origin carries none. noxtica('metadata', console.log)printssessionId,pageIdandconsent.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| An event never appears | Its name is not on the allow-list, App events or Tracker is off, the visitor has not consented to analytics, or Do Not Track or Global Privacy Control is honored. | Check steps 2 and 3, and the consent state. |
| An event arrives without a property | The property key is not on the allow-list. | Add the key. For noxtica('event', ...) add value. |
track throws a TypeError | The name is empty or properties is not a plain object. | Pass a non-empty string and an object. |
A queued call logs noxtica:error | The key, value or reason failed validation. | Match the patterns in the table. |
| A tag is missing | The key is not in Session tag keys (allow-list), the list is empty, or no recorder is active. | Add the key, and arm replay. |
identify does nothing | The id is blank or over 256 characters, or the page has no WebCrypto. | Use a secure page and a valid id. |
No traceparent header | The origin is not allow-listed. The request still runs without a header. | Add the exact origin in step 8. |
upgrade returns pending_consent or refused | Consent has not been decided, or the recorder cannot start. | Grant the replay category. See the replay page. |
Related
- Client API, events and the command queue — the full client surface.
- Session replay: setup, masking and playback — tags and markers show up in recordings.
- Behavior analytics: heatmaps, journeys and funnels — funnels are built from your app events.
- APM and the ingestion service (OTLP) — backend traces.
- Single-page apps, frameworks and tag managers — call these APIs from a framework.