Docs

Install the tag

One script on every page, before </head>. Your website's key is in the dashboard under Setup, filled in.

A website

Anything where links reload the page:

<script src="https://app.tracetells.com/d.js?k=YOUR_KEY" data-key="YOUR_KEY" defer></script>

A single-page app

React, Vue, Svelte, Angular and the rest. History API, Navigation API and hash-router navigations are followed on their own. Numeric, UUID and long-hash segments become :id; name other dynamic paths with data-routes:

<script src="https://app.tracetells.com/d.js?k=YOUR_KEY" data-key="YOUR_KEY"
        data-routes="/products/:slug, /docs/*" defer></script>

A tag manager, a bundler or type="module"

Where the tag can't carry attributes, configure it in code. The one-line stub queues calls made before the script loads, so trace.track() is safe at any time:

<script>window.trace=window.trace||{q:[]};["track","identify","page","init"].forEach(function(m){trace[m]=trace[m]||function(){trace.q.push([m,arguments])}})</script>
<script>trace.init({ key: "YOUR_KEY", routes: ["/products/:slug"] });</script>
<script src="https://app.tracetells.com/d.js?k=YOUR_KEY" async></script>

Your own events

trace.track("signed_up", { plan: "free" })

Or without JavaScript: data-trace-event="signed_up" on a button, link or form. Declare each event in trace.json so Trace can tell you when one stops arriving.

Signed-in people

Call trace.identify(id) on every page while someone is signed in, with an id that isn't an email, ideally a keyed hash of your user's id. They then count once across days, which is what DAU, MAU and retention need. Following someone across days is per-person tracking even with a hash: say so in your privacy policy, and leave it out where it doesn't fit.

Options

OptionWhat it does
keyYour website's write key (required)
routesPatterns that group dynamic URLs: :param matches one segment, a trailing * the rest
sampleShare of visitors to record, e.g. 0.25
pageviewsauto (default), or manual and you call trace.page()
consolefalse stops recording console.error calls
consentLeave it out to stay cookieless, or required to wait for your consent tool

The API: trace.track(name, props), trace.identify(id), trace.page(route?), trace.flush(), trace.consent(true | false).

When your site already asks for consent

Add data-consent="required". Before an answer nothing is stored, listened to or sent. Your consent tool calls trace.consent(true) or trace.consent(false). After a yes, the collector keeps a visitor id in localStorage so returning visitors are recognised across days. Global Privacy Control counts as no.

Overlay links

From a page's story in the dashboard, Show it on my page opens your page with #trace-overlay=… in its address. On that page load the collector sends nothing and loads overlay.js from your Trace server, which removes the token from the address bar and draws the page's aggregated story on top. If your site has a Content Security Policy that allows the collector's server for scripts and requests, the overlay works too. Visitors never load it.

Performance

8.4 KB on the wire, about 3 µs of work per click and no layout reads on the hot path. It takes notes while the page is busy and sends them when the browser is idle. If it ever fails, your site carries on as if it weren't there.