Sentinel

Lightweight host-site usage tracking (pages, clicks, forms). Complements GuideAI; reuses auth and environment when present. Channel /beta/ · v0.1.3-1.

Install

<script src="https://cdn.getguide.ai/sentinel/beta/Sentinel.standalone.js"></script>
<script>
  Sentinel.init({
    authKey: '…', // required standalone; optional if GuideAI is already on the page
    // environment: 'development', // optional; reuses GuideAI environment when omitted
    // runtime: 'react', // default: 'vanilla' ('react' | 'jquery' | 'vanilla')
  });
</script>

Init options

PropDefaultNotes
authKey — Required standalone. Optional when GuideAI is already on the page (session reuse).
environment GuideAI / hostname production | development | local. Omitting reuses GuideAI environment when available; pass to overwrite.
runtime vanilla react for SPA / role=dialog extras; jquery to also hook host $ / jQuery.

Client defaults: 2s flush / 20 events · soft ~500 events per session. On 403 (customer disabled), capture stops.

With GuideAI on the page

When GuideAI is already embedded, Sentinel reuses its widget session and target environment — both authKey and environment are optional and can still be passed to overwrite.

GuideAI.embed({ authKey: '…', environment: 'development' });
Sentinel.init(); // reuses GuideAI session + environment

Runtime

Page context

Optional. Page context tagging is not required — Sentinel works without it. Host tags and Sentinel.context() only improve analytics insights (clearer areas, pages, components, and journey labels) when you use them.

Every navigation, dialog, and interaction event stamps a PII-safe payload.context. Raw Event.path still keeps IDs for analytics; scrubbed labels live only in context. Without host tags, values come from the auto path fallback.

Shape on each event

{
  "pathTemplate": "/customers/:id",
  "area": "customers",
  "page": "detail",
  "surface": "main",
  "nodeKey": "customers/detail",
  "label": "Viewed customer detail",
  "source": "auto",
  "tags": {},
  "component": "save"   // optional — interaction events only
}
FieldMeaning
pathTemplatePathname with id-like segments replaced by :id (always from the URL).
areaProduct area / section (e.g. customers, settings).
pageScreen within the area (e.g. list, detail, edit).
surfaceLayer on the page. Default main; dialogs use dialog:<token>.
nodeKeyStable Markov node: area/page or area/page#surface.
labelHuman-readable label from area/page/surface (never document.title).
sourceWhere area/page/surface/tags came from: api | dom | auto.
tagsOptional string map for host metadata (max 20 keys; values truncated).
componentOptional control id on click/form events when the element is tagged.

How values are chosen

Three layers merge field-by-field. Higher wins when set; unset fields fall through:

PrioritySourceHow to set
1 (highest) API — Sentinel.context() Call after SPA navigation. Sets area, page, surface, tags. Cleared automatically on every route_change.
2 DOM — data-sentinel JSON blob and/or flat data-sentinel-* attrs. Walks ancestors for area/page/surface/tags; component comes from the event target.
3 (fallback) Auto — URL path Scrubs the pathname, then derives area/page (e.g. /customers → list, /customers/:id → detail, …/edit → edit). surface defaults to main.

Host fields you can set

FieldAPIDOMNotes
areayesyesSlug-safe; sanitized to lowercase tokens.
pageyesyesSlug-safe.
surfaceyesyesOmit for main. Dialogs may use dialog:confirm (or inferred from aria).
tagsyesJSON onlyObject of string values. Flat attrs do not set tags.
component—yesOn the interactive element. Not set via Sentinel.context().

DOM tagging

<!-- JSON blob on a page region -->
<main data-sentinel='{"area":"customers","page":"detail","surface":"main","tags":{"workflow":"renewal"}}'>
  <!-- component tags the clicked/interacted element -->
  <button data-sentinel='{"component":"save"}'>Save</button>
</main>

<!-- or flat attrs (same fields; flat wins if both are set on one element) -->
<main data-sentinel-area="customers" data-sentinel-page="detail">
  <button data-sentinel-component="save">Save</button>
</main>

SPA: Sentinel.context()

// SPA: set labels after navigation (same tick as the route change)
Sentinel.context({
  area: 'customers',
  page: 'detail',
  surface: 'main',          // optional; default "main"
  tags: { workflow: 'renewal' },
});

Sentinel.context(null); // clear → fall back to DOM attrs / auto path

Host API context clears on every route_change. Call Sentinel.context(...) again in the same tick after navigation so later events keep your labels (source: "api").

Dwell and dialogs

Leave events (route_change, modal_close, session_end) also carry dwellMs (visible time only), fromNodeKey, and toNodeKey. Open dialogs become Markov nodes under the current page: area/page#dialog:<token>.

APIs

Widget API: {app|dev|localhost}/sentinel/api/widget
Session exchange: existing /api/widget/session

Last updated 2026-09-04 18:22 UTC. Bundle: Sentinel.standalone.js.