umami.track() in code, or a data-umami-event attribute in HTML.
Track from code
umami exists once the tracker has run. The tag is defer, so code that can run earlier should check for it. A call made before the tracker loads is not queued: it is lost.
lib/analytics.ts
umami.track() with no arguments records a page view for the current URL. You only need it if you turned automatic page views off.
Track clicks with attributes
Give any element adata-umami-event attribute. Each data-umami-event-<key> attribute on the same element becomes a property of the event data.
connect-wallet with the data { "wallet": "freighter" }. Attribute values are always strings.
- Clicks inside the element count. The tracker looks for the nearest ancestor with
data-umami-event, so a click on an icon inside the button is tracked. - Links wait for the event. For an
<a>that opens in the same tab, the tracker holds the navigation, sends the event, then follows the link. Links withtarget="_blank", middle clicks and clicks with Ctrl, Shift or Cmd are not delayed. - Attributes need automatic tracking. The click listener is installed together with automatic page views. With
data-auto-track="false"on the tracker tag, attributes do nothing and onlyumami.track()works. To stop automatic page views but keep attribute tracking, setdata-auto-pageview="false"instead.
Event data rules
Name events for the report
The Custom events panel lists event names with their counts for the selected range, top eight across your project’s websites. Choose names you want to read there.- Use a short verb phrase in lowercase with hyphens:
connect-wallet,swap-submitted,signup-completed. - Name what happened, not where it happened. Put the place in the data:
{ "location": "header" }. - Keep ids out of names.
swap-8f3acreates one row per swap and buries the rest of the list.
What not to put in events
Never send:- Contact details and account ids: email addresses, names, phone numbers, usernames, ids from your own database.
- Stellar identifiers tied to a visitor: account (
G…) and muxed (M…) addresses, federation addresses, and transaction hashes from the visitor’s own activity. An address is pseudonymous, but it links to everything that account has done on chain. - Secrets: secret keys, seed phrases, API keys, session tokens, JWTs.
- Free text a visitor typed: search terms, form fields, messages.
freighter), the network (mainnet), an asset pair (XLM/USDC), an amount band (100-1k).
Do not identify visitors
The tracker also carries Umami’sumami.identify() and the data-distinct-id attribute. Do not use either. Lumenstat counts a visitor with a hash that includes a random salt, and the salt is replaced every UTC day and deleted after 48 hours, so no one can link a visitor across days. A distinct id is whatever value you pass, stored with the visitor’s session and its events. When it stays the same from one day to the next, it re-links exactly what the daily salt is there to separate.
Page URLs and titles are stored too
Every page view stores the page path with its#fragment, the referrer’s domain and path, and the page title, each up to 500 characters. Query strings are removed except utm_* tags. If your routes or titles contain a visitor’s address, such as /account/GABC…, it is stored with each view.
Rewrite those values in the browser before they are sent. Define a function on window and name it in data-before-send. The tracker calls it with each payload and sends what it returns, or nothing if it returns null.
data-exclude-hash="true" drops them from every URL.
Events from a server are not counted
An event must come from the tracker running in a visitor’s browser. A request posted to the collect endpoint from your backend carries no browserOrigin, no Fetch Metadata headers and no proof of JavaScript, so it is flagged and never counted. To measure what happens on your servers, use API analytics.
Limits
- Visitors who block the tracker or run without JavaScript send no events.
- Events called before the tracker has loaded are dropped, not queued.
- The tracker does not report rejected events. Test a new event once and confirm it appears on the Website page before you rely on it.