Install
-
Create a property at app.snipform.io for the domain you are tracking and copy its property key.
-
Add the script to every page, before
</body>or in<head>withdefer:<script src="https://cdn.snipform.io/api/analytics/signals.js?site=YOUR_PROPERTY_KEY" defer></script> -
Open the page. The property’s live view in the dashboard shows the session within a few seconds.
The script reads its configuration from its own src, so the query string is the configuration. There is no init call and nothing to configure in JavaScript.
Script parameters
Section titled “Script parameters”| Parameter | Required | Effect |
|---|---|---|
site (alias p) | yes | The property key. Without it the script loads and does nothing. |
debug=true | no | Logs every lifecycle step, ping and write to the console, prefixed [Signals]. |
shopify=true | no | Turns on the Shopify cart bridge. See Shopify. |
<script src="https://cdn.snipform.io/api/analytics/signals.js?site=YOUR_PROPERTY_KEY&debug=true" defer></script>Rolling or pinned
Section titled “Rolling or pinned”| URL | Behaviour |
|---|---|
https://cdn.snipform.io/api/analytics/signals.js | Rolling. Always the current release (1.4.1 today), cached for one hour. |
https://cdn.snipform.io/api/analytics/signals.v1.4.1.js | Pinned. Immutable, cached forever. |
Use the rolling URL unless you have a change-control reason not to. Releases never change the public API described in these docs without a major version.
Content Security Policy
Section titled “Content Security Policy”If you send a CSP, allow the two hosts the tracker talks to:
Content-Security-Policy: script-src 'self' https://cdn.snipform.io; connect-src 'self' https://api.snipform.ioKnowing when it is ready
Section titled “Knowing when it is ready”The session id is resolved by the server on the first request, so it is not available synchronously at script load. Two ways to wait for it:
const sessionId = await signals.ready;window.addEventListener('signals:ready', (e) => { console.log(e.detail.userId); // the session id});signals.sessionId is the same value as a plain getter, null until ready. (signals.userId is a legacy alias for the same value; it has always been the session id, never a user identity.)
Calling signals() before the tracker is ready logs a warning and resolves { success: false, error: 'Not initialized' }. It does not queue. If an event can fire before the page has settled, await signals.ready first.
What the first request sends
Section titled “What the first request sends”GET https://api.snipform.io/v2/signal/load with these headers. Titles, URLs and referrers are URI-encoded because header values must be ISO-8859-1.
| Header | Value |
|---|---|
X-SNIP-ID | property key |
X-SNIP-PAGE | location.href |
X-SNIP-TITLE | document.title |
X-SNIP-SRC | document.referrer |
X-SNIP-STATUS | HTTP status of the page, 200 |
X-SNIP-DIM | viewport as WIDTHxHEIGHT |
X-SNIP-LIB | script version |
The response is { success, session_id, view_id }. If success is false (unknown key, domain not registered, account paused) the tracker stops for that page and logs the message when debug=true.
Loading twice
Section titled “Loading twice”The script guards against double inclusion with window.__snipformSignals. A second tag on the same page logs Script already loaded, skipping duplicate and does nothing, so a tag in a shared layout plus one in a component is harmless.
Verifying
Section titled “Verifying”- Dashboard live view shows the session and the page.
signals.sessionIdin the console returns a string.- With
debug=true, the console showsInitialized v1.4.1, thenView loaded: <view id>, Session: <session id>. - The network tab shows the
loadrequest with a 200, thenpingrequests as you scroll and switch tabs.
If the load returns 200 but success: false, the message tells you why: the key was not found, the page’s domain does not match the property’s registered base domain (example.local is not a valid domain), or the property’s signal is not active. Subdomains of the registered domain are accepted; unrelated hosts, including a local dev server, are not - verify on a host under the property’s domain.