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
| Option | What it does |
|---|---|
key | Your website's write key (required) |
routes | Patterns that group dynamic URLs: :param matches one segment, a trailing * the rest |
sample | Share of visitors to record, e.g. 0.25 |
pageviews | auto (default), or manual and you call trace.page() |
console | false stops recording console.error calls |
consent | Leave 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.