Signals Docs
Concepts

Auto-discovery

How the tag inventories your site's interactive elements.

The tag scans every page for interactive elements - a[href], button, input[type=submit|button], [role=button] and form - and ships a compact inventory to Signals. The dashboard uses it as the pick-list for creating events (manually or via AI suggestions), so you never write a CSS selector by hand.

What gets collected

Per element, up to 200 per scan:

  • type - button, link or form
  • selector - a best-effort stable CSS selector (see below)
  • text - visible label, capped at 80 characters
  • href - for links (same-origin links are stored as paths)
  • event_hint - a data-signals-event annotation if the element already has one

Hidden elements and anything inside a data-signals-no-capture subtree are skipped. Element content like form input values is never collected.

Selector strategy

Selectors are chosen for stability, in order of preference:

  1. #id - when the element has a valid id
  2. tag[data-testid="…"], tag[data-signals-event="…"] or tag[name="…"] - when unique
  3. A short class/tag path with :nth-of-type, at most 5 levels deep, stopping as soon as it uniquely matches

When scans happen

The first scan runs after load (debounced 2.5s so hydration settles). A MutationObserver re-schedules scans on DOM changes, covering SPA navigations and lazy-rendered sections.

Each page's inventory is content-hashed and remembered in localStorage - a scan is only sent when the page actually changed. The backend applies a second server-side hash guard per (key, page) with a 6-hour TTL, so the backend sees a page's inventory roughly once per change, not once per visitor.

On this page