Skip to content

Server-defined tracking rules

Tracking rules let an app owner or admin describe a useful browser interaction in the console. The optional rules SDK downloads the enabled set, installs bounded listeners, and emits an event when a rule matches. Updating a rule does not require rebuilding the tracked application.

A rule says:

  1. Where? Find an element by ID, class, CSS selector, text, or XPath.
  2. When? Watch click, double-click, mouse, submit, keyboard, or first-visible behavior.
  3. What? Emit a stable event name.
  4. Only here? Optionally limit it to one relative page path.
  5. Bring anything? Optionally read up to three small properties from other elements.

That is it. No séance with a tag manager required.

Supported selector types are id, class, css, text, and xpath. Text matching is normalized and bounded; XPath and broad text scans have result limits so one ambitious rule does not adopt the main thread.

Supported interaction events include:

  • click, dblclick, mousedown, and mouseup
  • submit
  • keyup and keypress
  • view, which uses one shared IntersectionObserver and records the first match

Keyboard rules can emit on Enter, Escape, period, or Space. They can also wait until the target reaches a configured character count, or debounce until typing has stopped for a configured number of seconds. The SDK caps a debounce at 60 seconds and clears timers during stop().

page_path is optional. When present it is an exact relative pathname beginning with /, such as /pricing. Without it, the rule can match on every page.

A rule can define up to three custom properties. Each property has a key, selector, and selector type. The SDK reads an element’s primitive value when available, otherwise its trimmed textContent; a missing element produces null. Captured strings are bounded to 512 characters. If an application needs computed context instead, the synchronous enrichRule callback can add up to three primitive fields. Invalid enrichment never suppresses the base event.

Rule tracking is a separate, tree-shakeable SDK entrypoint:

import { trackRules } from "@owleye/analytics/rules";
const rules = trackRules("your-tracking-id", {
server: "https://api.owleye.dev",
});
// During application teardown:
rules.stop();

The SDK fetches enabled rules from GET /v1/rules?site_id={trackingId} without browser credentials. It uses delegated DOM listeners where possible, aborts an in-flight fetch on teardown, and does not store a rule identity in cookies or browser storage.

GET /v1/sites/{siteId}/rules
POST /v1/sites/{siteId}/rules
GET /v1/sites/{siteId}/rules/{ruleId}
PUT /v1/sites/{siteId}/rules/{ruleId}
DELETE /v1/sites/{siteId}/rules/{ruleId}

App members can read the rule set. Creating, updating, pausing, or deleting rules requires owner or admin access. The list response includes the rule’s lifetime tracked-event count. Demo rules are readable but immutable.

  • Rule events use the normal cookie-free ingestion path.
  • Sampling is applied per match without planting a stable browser sampling ID.
  • Optional captured text and custom properties should be treated as data collection decisions. Choose selectors that avoid names, email addresses, tokens, and free-form sensitive input.
  • The SDK keeps listeners, observers, weak element references, and timers bounded and releases them when stopped.