b.js reads exactly nine things: six attributes on the script tag, two globals and one function. Nothing else is looked at.
An option can be set perfectly and still have its value discarded on the server, because storing a declaration is a policy decision the operator makes and storing a measurement is not. The panel’s Settings › Beacon card renders this same table with that column filled in from your configuration, which is the only place it can be answered concretely.
| Option | Kind | What it does | Default | Accepted | Stored |
|---|---|---|---|---|---|
data-endpoint | attribute | The collector URL, when it is not a sibling of b.js |
the script’s own src with b.js swapped for collect.php |
Any URL. Set it only for a CDN or a different path | always — the script uses it itself |
data-hb | attribute | Heartbeat interval in milliseconds. A beat is sent only when engaged time actually advanced, so an idle tab produces one, not hundreds | 15000 |
Integer, clamped to 2 000–300 000. Anything else is ignored and the default used | always |
data-idle | attribute | How long after a real interaction a visitor still counts as engaged. This is the definition of the Engaged clock | 30000 |
Integer, clamped to 1 000–600 000 | always |
data-ident | attribute | An identity your site attaches. Never guessed. See identity | absent, and absent is not empty | Free text, truncated to 128 bytes. Control characters stripped, invalid UTF-8 repaired | beacon.store_identity — false by default, so this is discarded until you turn it on |
data-signed-in | attribute | Whether the visitor was signed in. Splits every number in the panel into signed-in and anonymous | absent — meaning not reported, never “no” | 1/0 or true/false. Anything else, including an attribute a template rendered blank, is read as not reported |
beacon.store_signed_in — true by default |
data-params | attribute | Query parameter names whose values are kept as search terms. Nothing else in the query string is read | absent — no parameter is collected | Comma separated. At most 8 names, each up to 40 characters of a-z 0-9 _ - . [ ]. Each value capped at 96 characters, dropped rather than truncated if longer |
beacon.query_params — empty by default, and the server’s list is authoritative |
window.LoghoundIdent | global | The same value as data-ident, for a template where adding an attribute to the tag is awkward but setting a variable above it is not |
unset | A string, set before b.js executes — with defer, anywhere in the document. The attribute wins if both are present |
beacon.store_identity |
window.LoghoundSignedIn | global | The same value as data-signed-in |
unset — not reported | A real boolean, or the same strings the attribute accepts. Set before b.js executes |
beacon.store_signed_in |
window.loghound.identify(ident, signedIn) | function | Attach either value after the page has loaded — a single-page application that signs somebody in without a navigation, which no attribute can express | never called | Both arguments optional and independent. Makes no request of its own: the values ride the heartbeat that is already scheduled. Safe to call with anything; it cannot throw into your code | both switches above |
data-hb and data-idle mirror beacon.heartbeat_ms and beacon.idle_timeout_ms in the configuration, and the settings page renders the snippet with your configured values already in it. The rest have no configuration counterpart on the page — your template supplies them per request — but whether Loghound stores what they carry is decided entirely on the server.
<script src="https://loghound.example.com/b.js?v=1"
data-hb="15000"
data-idle="30000"
data-signed-in="1"
data-params="q"
defer></script>And the server-side half that decides what is kept, in config/loghound.php:
'beacon' => [
'heartbeat_ms' => 15000,
'idle_timeout_ms' => 30000,
'store_identity' => false,
'store_signed_in' => true,
'query_params' => ['q'],
'allowed_hosts' => [],
],The option list, with each default, accepted range and the key that decides whether what it sends is stored, is a contract in the Loghound specification: it belongs in the documentation, in the settings card, and in the script, and the three must not be able to drift. A test in the repository derives the list from b.js mechanically and fails when either of the other two falls behind.
Somebody installing a beacon reads the settings card. An option that exists only in a JavaScript comment and a markdown file is undocumented for the person who needs it — and the card answers what no document can: whether this installation will keep what an option sends.