TRACKING
Custom events
Track signups, checkouts, or any action with window.attrifast.track() — then turn event names into goals to measure conversion by channel.
Once the tracker is installed, a small global API is available for tracking anything beyond pageviews.
Track an event
window.attrifast.track('signup');
Call it at the moment the action actually completes — inside a click handler or after a successful API response, not on page load. Each call records one event.
The API is available after the tracker initializes (on DOMContentLoaded). Calls from user-interaction handlers are always safe; if you need to fire an event earlier or from framework lifecycle code, guard the call:
window.attrifast?.track('signup');
track() accepts an optional second argument for event properties, but properties are not queryable or visible anywhere today — don't rely on them. If you need to segment, encode the variant into the event name itself: signup_pro vs signup_free.
Manual pageviews
SPA route changes (History API) are tracked automatically — you don't need to call anything on navigation. window.attrifast.pageview() records a pageview manually and restarts engagement timing; use it for view changes the History API doesn't cover (e.g. a modal step you count as a page).
You can suppress the initial page-load pageview with data-auto-pageview="false" on the snippet:
<script defer data-tracking-id="YOUR_TRACKING_ID" data-auto-pageview="false" src="https://api.attrifast.com/af.js"></script>
SPA route-change tracking stays on even with data-auto-pageview="false" — there's no fully-manual mode yet. Don't call pageview() on route changes, or every navigation will be counted twice.
Delivery semantics
- Fire-and-forget.
track()returns nothing and never throws for network problems; delivery usessendBeaconwithfetch/XHR fallbacks. - The collect endpoint replies
204and drops bad data silently — a wrong tracking ID or an unregistered domain won't error in your console. If events don't show up, check those two first. - Quota: each pageview and each custom event counts as one event against your monthly plan quota (Pro: 100,000/month — engagement heartbeats are free). Over quota, requests return
429. - Bots never count. The tracker doesn't initialize for bot-like browsers (including
navigator.webdriver), so events won't fire from Playwright/Puppeteer/Lighthouse runs — by design.
Where events show up
Custom events surface through goals: create a goal with type "Custom event" and the exact event name, and the dashboard Goals panel shows conversions and conversion rate for it — retroactively, including events recorded before the goal existed. There's no raw event feed in the UI yet.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
Cannot read properties of undefined (reading 'track') | The call ran before the tracker initialized (or in a bot-like browser where it never does). Fire from interaction handlers, or use window.attrifast?.track(…). |
Events return 204 but nothing appears | Silent server-side drop: the data-tracking-id doesn't match your website, or the page's domain isn't the registered one. Verify both. |
429 "Subscription required…" or "Monthly event limit exceeded…" | Free plan (collection requires a subscription or trial) or quota reached. Usage resets each calendar month — check it on the billing page. |
| Events fire in Playwright/Lighthouse but never show up | Bot filtering on both ends — by design. Test in a regular browser session. |
| Goal conversions look inflated | Conversions count every occurrence, not unique visitors. Fire track() once per completed action, not per click. |