Tracker.js
tracker.js is the browser-side part of Agent Analytics. Use it when you want page views, custom events, and client-side experiments without shipping a heavy SDK.
The API reference now treats GET /tracker.js as the script endpoint only. The setup and feature guide lives here.
Base snippet
Section titled “Base snippet”Add this before </body>:
<script defer src="https://api.agentanalytics.sh/tracker.js" data-project="my-site" data-token="aat_..."></script>Required attributes:
data-project: your project namedata-token: the public project token (aat_*)
The tracker automatically collects page URL, pathname, referrer, browser, OS, device, language, timezone, UTM params, session count, and first-touch attribution. No cookies are required.
Automated traffic that reaches the tracker is filtered out of your normal analytics. Use Bot Traffic if you want to inspect those automated requests separately.
If your agent can edit code, ask it to add the snippet for you. If not, use First Project in 5 Minutes to create the project, get the snippet, and verify the first page view.
Website analysis recommendations assume these automatic fields already exist. A good implementation_hint should use the smallest tracker capability that unlocks the decision: declarative attributes for simple intent, window.aa.track(...) for computed client state, and server-side tracking for durable outcomes like account creation.
Common options
Section titled “Common options”| Attribute | What it does |
|---|---|
data-link-domains="example.com" | Link anonymous identity across sibling domains or subdomains |
data-do-not-track="true" | Respect the browser Do Not Track signal |
data-heartbeat="15" | Measure active time on page while the tab is visible |
data-track-outgoing="true" | Track external link clicks as outgoing_link |
data-track-clicks="true" | Track <a> and <button> clicks as $click |
data-track-errors="true" | Capture uncaught JS errors and promise rejections as $error |
data-track-performance="true" | Add Navigation Timing metrics to page_view |
data-track-vitals="true" | Add Core Web Vitals to page_view |
data-track-downloads="true" | Track download link clicks as $download |
data-track-forms="true" | Track form submissions as $form_submit |
data-track-404="true" | Track 404 pages as $404 |
data-track-scroll-depth="true" | Add max scroll depth to page_view |
data-require-consent="true" | Buffer events until consent is granted |
Example:
<script defer src="https://api.agentanalytics.sh/tracker.js" data-project="my-site" data-token="aat_..." data-track-outgoing="true" data-track-performance="true" data-track-vitals="true" data-track-errors="true" data-track-scroll-depth="true" data-heartbeat="15"></script>Declarative events
Section titled “Declarative events”For simple click tracking, you usually do not need custom JavaScript. Add data-aa-event directly in HTML:
<button data-aa-event="signup_cta_clicked" data-aa-event-plan="pro"> Sign up for Pro</button>That fires a signup_cta_clicked event with { plan: "pro" }.
This is usually the easiest path for agents too. They can add attributes to existing markup instead of wiring onclick handlers or editing application code.
Reserve signup for the durable moment when an account is actually created. If a button only starts the flow, use an intermediate event like signup_started or signup_cta_clicked instead of treating the click itself as the completed signup.
Impressions
Section titled “Impressions”Track whether a section was actually seen:
<section data-aa-impression="pricing_table" data-aa-impression-plan="pro"> ...</section>When the element becomes visible, the tracker sends an $impression event.
window.aa API
Section titled “window.aa API”Use the JavaScript API when the event depends on runtime state:
window.aa?.track('checkout_started', { plan: 'pro' });window.aa?.identify('user_123');window.aa?.set({ plan: 'pro', team: 'acme' });Useful methods:
aa.track(event, properties): send a custom eventaa.page(name): manually send a page viewaa.identify(id): link anonymous behavior to a known user IDaa.set(properties): attach global properties to future eventsaa.experiment(name, variants): assign variants deterministically client-sideaa.grantConsent()/aa.revokeConsent(): manage consent mode
Authenticated apps: signup, login, and identify
Section titled “Authenticated apps: signup, login, and identify”For apps with accounts, the cleanest post-auth browser step is:
window.aa?.identify(account.id);window.aa?.set({ plan: account.plan, team: account.team });Call aa.identify(account.id) immediately after auth succeeds and before aa.set(...) or any other post-auth browser events. That stitches the current browser activity onto the same canonical user ID that your server should use.
Recommended event boundaries:
- Fire
signupexactly once when the account is created. Prefer the server-side account-creation path for this. - Fire
loginwhen an existing account finishes auth. Prefer the server-side auth callback or session-creation path for this too. - Use client-side events like
signup_started,signup_cta_clicked, orcheckout_startedfor earlier UI steps that happen before the account exists.
That separation keeps funnels honest and makes browser events and server auth events land on the same user_id.
SPA routing and virtual pages
Section titled “SPA routing and virtual pages”Agent Analytics automatically tracks page_view when the browser URL changes through history.pushState(), history.replaceState(), popstate, or hashchange. That covers most client-side routers, including hash-based SPAs.
If your UI changes without changing the path, query string, or hash, the tracker does not try to guess that a new screen appeared. In that case, send a manual page_view.
Preferred implementation order:
- Real URL changes
- Hash routing
- Manual virtual
page_view
Use aa.page(name) when the current browser URL already matches the screen you want to label. It sends a page_view with a page property, but path and url still come from the current browser location.
For true virtual pages with no URL change, send a manual page_view and override the route fields yourself:
window.aa?.track('page_view', { page: 'Checkout Step 2', path: '/checkout/step-2', url: `${location.origin}/checkout/step-2`});Do not combine manual page tracking with router-driven transitions that Agent Analytics already auto-tracks, or you will double-count the same screen change.
If you want a prompt-first workflow for deciding between router tracking and manual virtual pages, use SPA and Virtual Page Tracking.
Common recipes
Section titled “Common recipes”Cross-domain identity
Section titled “Cross-domain identity”<script defer src="https://api.agentanalytics.sh/tracker.js" data-project="my-site" data-token="aat_..." data-link-domains="example.com,app.example.com,docs.example.com"></script>Privacy and consent
Section titled “Privacy and consent”<script defer src="https://api.agentanalytics.sh/tracker.js" data-project="my-site" data-token="aat_..." data-do-not-track="true" data-require-consent="true"></script>window.aa?.grantConsent();window.aa?.revokeConsent();When consent is granted, buffered events are flushed automatically. If the buffer contains more than 100 events, the tracker splits it into multiple /track/batch requests of 100 events or fewer.
Experiments
Section titled “Experiments”<h1 data-aa-experiment="hero_text" data-aa-variant-b="Try it free today!"> Start your free trial</h1>If you want the full prompt-first workflow for creating, wiring, QAing, and reading an experiment through your agent, use AI Agent Experiment Tracking.
Local development
Section titled “Local development”On localhost, the tracker switches to dev mode and logs activity to the browser console instead of sending production data. That keeps local testing out of your real analytics.