docs / install / website

Install the website tag

One script tag sends page views, outbound clicks, engagement time and your own events. It sets no cookies and stores nothing in the browser.

The script tag

Paste this in the <head> of every page, with your site key from Settings → Sites and keys:

<script async src="https://app.knockstat.com/ks.js" data-site="kst_xxxx"></script>

That is all. It sends a page view on load and on every in-page navigation, clicks on links to other sites, and time on page. About 2.2 KB gzipped. Without data-site the script does nothing.

Events go to https://app.knockstat.com/v1/e, the address next to the script.

Options

Set options as data-* attributes on the same tag.

AttributeDefaultMeaning
data-siterequiredSite key, kst_....
data-apiv1/e next to the script’s srcBeacon URL. Needed only for a self-hosted ingest.
data-auto-pageviews="false"onTurns off automatic page views. Call knockstat.pageview() yourself.
data-outbound-links="false"onTurns off $outbound_click events.
data-engagement="false"onTurns off $engagement events (time on page).
data-allow-localhostoffSends from localhost, 127.x.x.x, [::1] and file: pages, which are skipped otherwise. Presence is enough; no value needed.
data-distinct-idanonymousThe logged-in user’s id, rendered by your server on every page. An empty value means anonymous. See Identify users.

Custom events

Name what a person did and attach properties:

knockstat.track("signup", { plan: "pro", seats: 3 });

Calls made before the script has loaded can go through a queue; the same line works before and after loading:

<script>
  window.knockstat = window.knockstat || [];
  knockstat.push(["track", "signup", { plan: "pro" }]);
</script>

Rules, checked in the browser before sending (a bad event is dropped with a warning in the console, never an exception):

  • The name is 1 to 200 characters, has no control characters and does not start with $. Names starting with $ are reserved.
  • At most 64 properties. A key is 1 to 128 characters. A value is a string (at most 1,024 characters), a number, a boolean or null. Objects and arrays are dropped.
  • An event body over 16 KiB is dropped.

The script sends these events by itself:

EventWhen
$pageviewOn load, and on in-page navigation when the path or query changes. Carries the referrer, screen size and any utm_* parameters in the URL.
$outbound_clickA click on a link to another site. Carries the link’s URL as $url.
$engagementThe page is hidden or closed, or before the next in-page view. Carries $engaged_ms, the milliseconds the page was visible.
$identifyThe user id changes to a new value.

Custom events appear in the dashboard’s Events view and feed the Insights, Funnels, Flows and Retention reports.

Identify users

Without an id, a visitor is a hash that changes every day, so the same person is a new visitor tomorrow. To follow people across days (Retention needs it), tell knockstat who they are with your own id. Use an opaque id such as a database key rather than an email address.

  • Multi-page sites: every page load starts anonymous, so render the id on every page for a logged-in user: <script async src="https://app.knockstat.com/ks.js" data-site="kst_xxxx" data-distinct-id="user-123"></script>. Leave it empty for anonymous visitors.
  • Single-page apps: call knockstat.identify("user-123") once after login and knockstat.reset() on logout. The id lasts until the page is reloaded; nothing is stored.

An id is at most 200 characters. When it changes to a new value the script sends one $identify event, which ties that day’s anonymous events to the user.

Single-page apps

The script hooks history.pushState, replaceState and popstate, and sends one page view each time the path or query changes. Routers that use the History API (React Router, Next.js, Vue Router in history mode, and most others) need nothing more. A change to the #hash alone is not a page view.

For a router that changes the URL without the History API, turn automatic page views off and report each route yourself:

<script async src="https://app.knockstat.com/ks.js" data-site="kst_xxxx" data-auto-pageviews="false"></script>
<script>
  // after each route change:
  knockstat.pageview();
</script>

Allowed origins

A site key is public, so anyone could send events with it. Limit where they may come from: under Settings → Sites and keys → Edit, list the origins your pages are served from, one per line, as scheme://host[:port] with no path or trailing slash.

https://example.com
https://www.example.com

Matching is exact, so https://example.com and https://www.example.com are two entries. With the list empty, any origin is accepted. A beacon from an origin not on the list is dropped, but still answered 204, so the browser shows no error: if nothing arrives, check this list first.

Localhost and testing

The script sends nothing from localhost, 127.x.x.x, [::1] or file: pages, and logs a console message saying so. To test locally, add data-allow-localhost to the tag, and add your local origin (for example http://localhost:3000) to the site’s allowed origins if you set a list. Remove both before you ship, or send test traffic to a separate site.

Ad blockers

Some content blockers block analytics scripts or their requests, and a visitor with one sends nothing. knockstat does not try to get around them. If those visits matter, count them from your server’s access log with the log agent, which does not depend on the browser.

Privacy: what is collected

  • No cookies, and nothing in the browser. The script uses no cookies, localStorage, sessionStorage or IndexedDB.
  • No fingerprinting. Screen size is sent as a property, never combined into an id.
  • Visitors are a daily hash. Ingest hashes the site, the visitor’s IP address and user agent with a salt that rotates daily. The same person gets a different id each day, so cross-day tracking is impossible by design, unless you identify them.
  • IP addresses are never stored. Ingest uses the address in memory to look up the country and make the hash, then drops it.
  • Each event carries the page’s host and path including its query string, the referrer, screen width and height, and the utm_* parameters. Ingest reads the browser’s user agent to set device, browser, OS and a bot flag. Keep personal data out of your URLs.
  • Your own properties and ids are sent only when your code calls track, identify or sets data-distinct-id.

This describes what knockstat collects; whether you need a notice or consent where you operate is for you to decide.

Stuck? Email [email protected].