Skip to content

Install the tracking script

Install a product snippet, declare a consent banner where used, and link visitor identity across your domains.

Copy the product’s snippet from Install into your site’s <head> and deploy it. The snippet loads the tracking script and connects its events to your product. Use the loader variant if your site calls lt(…): it queues calls made before the script is ready.

For the first-event walkthrough, see Track your first visitor. This guide covers the variant, consent declaration, automatic collection, delivery, and identity across your domains.

Before you start: you need access to a product with Tracking installed and permission to edit your site’s <head> through HTML, a template, or a tag manager. One product snippet works across its pages and domains.

Choose a variant

  1. Open Install and choose a variant from the table below.
  2. Copy it into the <head> of every page you want to track. If the page uses the Lepsto consent banner, add the banner declaration before deploying.
  3. Deploy or publish the site, then load a page to send a page_view.
Variant
Defines window.lt before the script loads
Use it when
Loader snippet (Recommended)
Yes — early lt(…) calls are queued and recorded
Your code calls lt(…) or may call it before the script loads
Minimal variant (behind the advanced toggle)
No — an early lt(…) call throws a ReferenceError in your page and the event is lost
You never call lt(…) yourself, or every call of yours certainly runs after load

Both variants collect the same automatic events. Replace the deployed snippet when you change variants.

Verify it works: open Live and look for the new page_view. On the Install checklist, the page’s hostname should change to Script seen. If the event is missing, follow Tracking troubleshooting.

The loader below shows the structure. Use your product’s generated version rather than copying the placeholder address.

<script>
  /* Lepsto Tracking — paste into <head>.
     Load unconditionally. Do NOT wrap this in a consent check: the tracker
     detects the visitor's consent itself and falls back to a cookieless,
     no-identifier mode when statistics consent is declined or not yet given.
     Gating this tag hides declining and undecided visitors completely. */
  !(function (w, d) {
    w.lt=w.lt||function () { (w.lt.q=w.lt.q||[]).push(Array.prototype.slice.call(arguments)); };
    var s = d.createElement('script');
    s.async=1;
    s.src = 'https://<tracking host>/<product id>/tracking/script/lt.v1.js';
    var f = d.getElementsByTagName('script')[0];
    f.parentNode.insertBefore(s, f);
  })(window, document);
</script>

Replace <tracking host> and <product id> only if adapting this example; the snippet from Install already contains both. The host is the shared Lepsto edge until you claim your own tracking host.

The loader creates an asynchronous script tag and defines window.lt immediately. That temporary function queues calls; the tracking script processes them once it loads.

The minimal variant loads the same file with a single tag:

<!-- Load Tracking unconditionally. On pages with the Lepsto consent banner,
     add data-consent="banner" as shown below. -->
<script async src="https://<tracking host>/<product id>/tracking/script/lt.v1.js"></script>

On pages that use the Lepsto consent banner, declare it so an undecided visitor starts cookieless even if Tracking loads before the banner.

  1. Put the banner tag first in <head>, above Tracking, without async or defer.
  2. In the loader, add this line after s.src = …;:
s.setAttribute('data-consent', 'banner');

For the minimal variant, add the attribute to the tracking tag:

<script async data-consent="banner" src="https://<tracking host>/<product id>/tracking/script/lt.v1.js"></script>
  1. Replace and deploy the snippet. You can instead request tracking_snippets_get with consentBanner: true; both returned variants include the declaration. The option defaults to false and accepts only a boolean. The Install page snippet does not include the declaration by default.

The attribute accepts banner regardless of case or surrounding spaces; other values behave like an absent declaration. A readable saved decision takes priority; the canonical cookie is lepsto_consent. Older saved decisions remain readable and are migrated automatically by the banner. An accepted visitor starts in full mode; an undecided visitor starts cookieless and can move to full mode on the same page after accepting. If the banner never loads, that page stays cookieless. Existing window.LepstoConsent and window.LesslyConsent signals remain supported.

Set the declaration only where the Lepsto consent banner runs. A page without a banner cannot supply a decision and would leave visitors cookieless. Load Tracking unconditionally in either case; the declaration does not gate the tag. See Tracking and consent for all recorded-decision and consent-change behavior.

What the script URL carries

The script URL identifies the tracking host, product, and version:

https://<tracking host>/<product id>/tracking/script/lt.v1.js

The address supplies these settings for every page using the snippet:

  • The tracking host is the shared Lepsto edge, public.lepsto.com, by default. Claim a host on a domain of your own on the Tracking domain page and the snippet is regenerated to point at it, so the script becomes first-party on your site — see Register the domains you track.
  • The product id is what identifies whose data this is. There is nothing to fill in.
  • The version is part of the filename. A future version ships as a new filename, so a snippet already pasted on your site keeps working untouched. Fixes inside the current version reach your visitors on their own: the file is cached at the edge for ten minutes and then revalidated, so you never re-paste the snippet to pick up a new build.
  • The collector address is derived from it. Everything from /script/ onwards is replaced with /collect. Nothing else is configured.

Two attributes you will not normally set

Use these optional overrides only when the derived collector or cookie domain does not meet your development or testing needs.

Attribute
What it does
data-collect="https://…/collect"
Sends events to a different endpoint than the one derived from the script URL. For local development and testing. The address has to go through your product’s public Lepsto address; a proxy of your own that calls the API directly is not supported.
data-cookie-domain="acme.com"
Sets the cookie domain explicitly instead of letting the script work it out.

Carry one identity across several of your domains

In full mode, a first-party cookie recognizes the visitor. Subdomains such as acme.com, www.acme.com, and app.acme.com share it automatically. Separate root domains such as acme.com and acme-app.io cannot share that cookie; without linking, the browser starts a new anonymous identity on the second domain. These are example Acme domains; replace them with domains you own.

Configure a link domain group to carry the anonymous visitor id when someone follows a link between your root domains.

  1. Declare the group. It is one list per product — your marketing site, your app, a second brand of yours. Only add domains you own: anything in the group can receive a visitor id. The list is the link domains described in Register the domains you track.
  2. Copy the snippet from the Install page again. The group is carried as a data-link-domains attribute on the script tag.
  3. Replace the snippet on every site in the group — including the ones you did not change — and deploy each of them.

Deploy the changed snippet everywhere in the group. The script reads the group from the pasted HTML, not from a live configuration request. An added domain receives no id until the change is deployed; a removed domain can still receive ids from pages with the old snippet.

What the script does with the group

On the way out. Before navigating, the script adds _lt_id to a clicked link only when its destination is in the group and cannot already share the current cookie. Links outside the group and links that share the cookie stay unchanged.

On the way in. The receiving script checks the incoming id in this order:

  1. Removes _lt_id from the address bar immediately, before anything else, so it is not left in the URL, in a bookmark or in a referrer.
  2. Refuses the value if it is more than about two minutes old. A decorated link that was shared or bookmarked cannot hand someone else’s identity over later.
  3. Adopts the id only if this browser has no visitor id on this domain yet. An established visitor is never overwritten.

The link carries only the anonymous visitor id, with no personal data. Linking requires a clicked link: typing the second domain or arriving from search cannot transfer the id. Those visits can join later when the person identifies themselves.

Cookieless visits have no visitor id to transfer. When statistics consent is declined or still unanswered, links remain undecorated and the script does not adopt an incoming _lt_id.

What the script captures on its own

With statistics consent granted, or on a site with no consent banner, the script captures the following automatically. Cookieless events contain less information and no identity; see Tracking and consent.

  • Page views. A page_view on load, and another on every route change in a single-page app — pushState, replaceState and the browser’s back and forward buttons all count. Navigating to the URL that is already open is not counted twice.
  • Page and device context. The URL, referrer and page title of each event, plus screen size, language and time zone.

Forms are not scanned: field values and submissions do not identify anyone. Call lt('identify', …) yourself or send identity through a backend event. See Identify a visitor.

Record other activity with lt('track', …).

How a visitor is recognized

Full mode uses two first-party cookies. Cookieless mode creates neither cookie nor any visitor or session identifier.

Cookie
What it holds
Lifetime
_lt_aid
The anonymous visitor id
400 days, refreshed on every event
_lt_sid
The session id
30 minutes of inactivity, on a sliding window; a new session starts on the next event after that

The script probes for the broadest cookie domain the browser accepts. This lets app.acme.com and docs.acme.com share an identity without a domain list. No cookie domain is set on localhost or bare IP addresses.

Events carry these ids in their bodies; Lepsto does not receive them as browser cookies. Tracking uses no fingerprinting or third-party cookies. If cookies are blocked while tracking is in full mode, an in-memory id lasts for the page’s lifetime.

How events are sent

The script buffers events in memory and sends them through browser beacons, falling back to fetch with keepalive. It sends a batch every 5 seconds, when the page becomes hidden or is left, or when the buffer reaches 20 events or roughly 60 KB.

The script loads asynchronously and sends without waiting for a response. Its error handling keeps analytics failures from throwing into your page, but events can be lost. A collector 204 does not confirm storage. If the current plan or billing state prevents storage, events are dropped and cannot be recovered from the browser; Dashboard, Live, and Reports show Events not stored this month. See Tracking troubleshooting.

Where the script cannot run

You need control over a page’s HTML to install the script. A hosted checkout that does not allow it will not appear in the install checklist. Send its activity from your backend with a public access key.

Next steps

Was this page helpful?
Esc

Start typing to search the docs.

↑↓navigate↵select