Web analytics

Count visitors without cookies, track custom events with properties and see which signed-in users come back, with one script tag.

The Logdash tracker counts visitors, pageviews and sessions, where visitors come from and what they browse with, without cookies. Track the actions that matter as custom events, break them down by properties, and identify signed-in users to see who comes back.

Add the script

In Logdash, open your domain, go to Analytics, enter your website address and press Start tracking. Paste the snippet it shows into the <head> of every page. The site ID in it is public and safe to ship in your HTML.

<script
  defer
  src="https://logdash.io/sdk/web.js"
  data-site="your-site-id"
  data-endpoint="https://api.logdash.io/web_events"
></script>

From then on, the tracker sends:

  • a pageview on load and whenever the path changes through pushState, replaceState, back and forward, or a page restored from the back-forward cache. Single-page apps need no extra code.
  • a pageleave when the visitor leaves the page, for session time and exit pages.
  • a browser_error for uncaught errors and unhandled promise rejections, without the error message or stack trace.
  • the custom events you track, described below.

Events are sent in small batches about a second after they happen, and right away when the page is hidden. The tracker exposes its API as window.logdash. Call it with ?., because the object does not exist before the deferred script has loaded or in browsers where the tracker does not start.

Serve it from your own domain

Ad blockers often block analytics served from another domain. Serve the script and the events from your own domain instead, with two routes that forward to Logdash:

  • GET /_ld/script.js forwards to https://logdash.io/sdk/web.js. Serve it as application/javascript and cache successful responses.
  • POST /_ld/events forwards to https://api.logdash.io/web_events and passes the status code back. Accept JSON bodies of up to 32 KB, and do not cache the responses.

On the events route, forward the browser's Origin and User-Agent headers, and set x-logdash-client-ip to the visitor's IP address. Without an Origin the API answers 403. Without the IP address every visitor shares your server's address, and visitors are undercounted. Never forward cookies, authorization headers or ingest keys on either route, and keep the target URLs fixed so the routes cannot become an open proxy.

<script
  defer
  src="/_ld/script.js"
  data-site="your-site-id"
  data-endpoint="/_ld/events"
></script>

Prefer not to write the routes yourself? The AI prompt tab of the setup gives your coding agent a prompt that adds both routes and the script tag to your codebase, and checks them end to end.

Track custom events

Call track for the actions you want to count, such as signup_completed. Event names match [a-z][a-z0-9_]{0,63}. To break an event down in the dashboard, pass a flat object of properties as the second argument.

window.logdash?.track('video_played', {
  quality: '1080p',
  autoplay: true,
  chapter: 2,
});
  • An event carries at most 10 properties. Keys match [a-z][a-z0-9_]{0,39}.
  • Values are strings, numbers or booleans. They are stored as strings, trimmed and cut to 100 characters, so 2 and true become "2" and "true".
  • A value that contains @ or a control character is dropped, so an email address is never stored by mistake.
  • Invalid properties are dropped with one console warning per page load, and the event is still sent. The API checks every request against the same rules.
  • Only custom events carry properties. pageview, pageleave and browser_error never do.
  • Each property keeps up to 500 distinct values per site within your retention period, and later values are counted as (other). A site can use up to 50 property keys, and properties with further keys are dropped.

Never put emails, names, user IDs, purchase details or other personal data in event names or properties. Properties describe what happened, such as a quality, a theme or a variant, never who did it. Use identify for the signed-in user.

Custom events appear in the Goals card of the dashboard. Open one to see its trend and a breakdown by each property, with the same date range and filters as the other reports. Clicking a value keeps only the events with that value, and narrows the other reports to the visitors who sent it.

Identify signed-in users

Anonymous visitors get a new ID every day, so retention and returning visitors are measured for identified users only. Once your app knows who is signed in, pass their user ID to identify. The identity lives in memory only, so call it on every page load, and call it with null when the user signs out.

On every page load, once the user is known
window.logdash?.identify(user.id);
On sign-out
window.logdash?.identify(null);

The script is deferred, so your app can know the user before it has loaded. If window.logdash is still undefined at that point, call identify from the load event of the script element.

  • id is a string or a number. null, undefined or an empty string clears the identity, and events tracked after that are sent without a user ID.
  • A value that contains @ or is longer than 256 characters is ignored with a console warning and leaves the identity as it was, so an email address is never sent by mistake.
  • The tracker hashes the ID in the browser, so the raw ID never leaves it. Hashing needs crypto.subtle, which browsers offer only in secure contexts such as HTTPS pages. Without it, identify does nothing.
  • Events of the page load that are still waiting to be sent when the hash is ready get the user ID too, so the first pageview is attributed when identify follows within about a second.

Pass a stable internal ID, never an email address or a name.

Let visitors opt out

The tracker does not start in browsers that send Do Not Track or Global Privacy Control, or in automated browsers that set navigator.webdriver. If your site has privacy settings, add an analytics toggle that calls optOut and optIn:

window.logdash?.optOut();
window.logdash?.optIn();
  • optOut() stops tracking at once: it drops queued events and removes its timers, listeners and history hooks. It writes localStorage['logdash:opt-out'] = '1' so the choice survives reloads.
  • optIn() removes that flag and starts tracking again with a fresh pageview. window.logdash exists while a visitor is opted out, so optIn() stays reachable.
  • stop() still works as an alias of optOut().

Plan limits

Your plan sets how long events are kept, counted from the time of each event.

Web analytics retention

HobbyBuilderPro
90 days180 days365 days

Privacy

The tracker sets no cookies, IP addresses are never stored, and anonymous visitors are counted with an ID that changes every day. Web analytics privacy describes what Logdash stores and for how long, and gives you text for your privacy policy.