Sending an event from JavaScript
One function, on the global window.aa. The first argument is the event name;
everything else is optional.
window.aa('Signup'); If you call it before the script has loaded, the calls are lost unless you added the loader stub described in the install guide. The stub queues them and replays them in order the moment the real script arrives, so the safe pattern is to include it on any site whose own code sends events during page load.
Attaching properties
Pass props to describe the event. Values may be strings, numbers or booleans.
window.aa('Signup', {
props: {
plan: 'growth',
billing: 'annual',
referred: true,
},
}); Never put anything personal in a property. A property is stored as you send it, and an email address or a user id in one turns a cookieless, non-identifying dataset into personal data — which puts your consent obligations straight back where they were. If you find yourself wanting a user id here, the honest answer is that this is the wrong product for that question.
Knowing whether it was sent
Pass a callback and you get told what happened. This is the only way to see
that an event was deliberately suppressed rather than lost, which makes it the fastest way
to debug an install that looks silent.
window.aa('Signup', {
callback: (result) => {
// { status: 202, ignored: null } sent
// { status: undefined, ignored: 'local' } suppressed, and why
console.log(result);
},
}); ignored is null on a successful send and otherwise names the
reason: local for a local address, self-excluded for a browser
carrying the self-exclusion flag, opted-out for a visitor who has opted out,
and excluded or not-included for a path filtered by
your path rules. A network failure reports
error.
Declaring events in your HTML
Most events are a click on a button or a link, and writing a click handler for each one is
tedious. The tagged-events build lets you declare them in the markup instead.
Load it, and no JavaScript of yours is involved at all.
<script defer data-domain="example.com"
src="https://cdn.absolutelyanalytics.com/aa.tagged-events.js"></script> <button data-aa-name="Signup" data-aa-plan="growth">
Start the trial
</button>
That fires an event named Signup with the property plan set to
growth. The rule is simple: data-aa-name is the event name, and
every other data-aa-* attribute becomes a property whose key is the attribute
name with data-aa- removed.
Property keys arrive lowercase, because HTML lowercases attribute names before your script
ever sees them. data-aa-planTier becomes the property plantier,
not planTier. Use hyphens — data-aa-plan-tier gives you the key
plan-tier, which is at least readable.
The class-based form
Some systems will not let you add arbitrary attributes to an element — a page builder, a CMS field, a component library with a locked-down prop list — but almost all of them let you add a class. The same events can be declared as classes.
<button class="aa-event-name--Signup aa-event-plan--growth">
Start the trial
</button> -- and = are interchangeable separators, so
aa-event-name=Signup is the same thing. Because a class cannot contain a
space, a + in the value becomes a space: aa-event-name--Newsletter+signup
fires Newsletter signup. Nothing else is decoded, so a value that needs a
literal + has to use the attribute form instead.
What counts as a click
- A left click and a middle click both fire. A right click does not — opening a context menu is not a conversion.
-
A form
submitfires, so tagging the<form>itself is the right way to measure a submission rather than tagging its button. - The script looks at the clicked element and up to three ancestors above it. Tag a wrapper and a click on the icon inside it still counts.
- An inner tag wins over an outer one for the same key, so a shared wrapper can supply defaults that individual children override.
- Nothing fires without a name. Properties on their own are inert, which is usually the cause when a "tagged event is not working".
If you also use session replay or heatmaps, note that their masking attributes share the
data-aa- prefix. Putting data-aa-mask on a tagged element, or
within three ancestors of one, will also record it as an event property. Keep masking
attributes off elements you have tagged.
Events you do not have to write
Two categories are common enough that they ship as builds rather than as instructions.
Outbound links
The outbound-links build fires an event named
Outbound Link: Click whenever a visitor clicks a link to another host, with the
destination in a url property. Anything that is not http or
https is ignored, so mailto: and tel: links do not
fire. A different subdomain counts as outbound.
File downloads
The file-downloads build fires File Download, again with the
destination in url, when a visitor clicks a link whose extension looks like a
file. It does not check the host, so a download from your own domain counts — and a link to
a PDF on someone else's domain fires both events if you have both builds loaded.
<script defer data-domain="example.com"
src="https://cdn.absolutelyanalytics.com/aa.outbound-links.file-downloads.js"></script> Turning an event into a goal
An event on its own appears in your events report. Making it a goal is what gives you a conversion rate and lets you see which sources, campaigns and countries actually convert. Goals come in two kinds:
- Event goals match on the event name —
Signup, exactly as you sent it. - Pathname goals match a page by path pattern, so
/thank-youor/checkout/**becomes a conversion with no code at all.*matches within one path segment and**crosses/.
An event goal can also name a currency, which is what turns conversions into money — see revenue tracking.
Once a goal exists you can filter and group by it through the
Stats API using the event:goal dimension, which
is also the thing the conversion_rate metric requires.
Scroll depth and engaged time
The engagement build measures two more things about a page: how far down it
anyone got, and how long they spent actually looking at it. Engaged time only accrues while
the tab is visible and focused, so a page left open in a background tab for an hour
contributes nothing.
Both are sent as part of a small periodic beacon rather than by polling, and that beacon is deliberately marked non-interactive so that it can never turn a bounce into a non-bounce. Your bounce rate does not move because you loaded this build.
Honest limitation: the scroll_depth and time_on_page metrics in
the Stats API return null today, with a warning saying so. The data is being
collected; the aggregate is not yet queryable. Scroll behaviour is currently readable
through the scroll maps, on Growth and above.
Common questions
Do custom events count against my plan allowance?
Yes. Your allowance counts pageviews and custom events together. Bots and AI crawlers are filtered out before counting, so you are never billed for them.
That is the same unit both incumbents meter on, and we are not going to describe it as generous. If you instrument a checkout flow heavily, work out the event volume before you pick a rung — the pricing page has the ladder.
Why is my tagged event not firing?
Four things, in the order they go wrong. One: you are on the base build, which does not contain the tagged-events parser — the attributes are ignored entirely, silently. Two: you set properties but no name; an event with no name never fires. Three: the element carrying the name is more than three ancestors above the thing that was clicked. Four: it was a right click, which is not a click as far as the script is concerned.
Can I see a breakdown by my custom properties?
Sending them works on any plan. Querying by them is a Business-tier capability, in the dashboard and in the Stats API alike. That is the incumbent's gating reproduced, and it is worth knowing before you instrument around it rather than after.
Does tracking a link slow the click down?
No, and this is deliberate. The script never cancels a navigation to squeeze a request in first. The event is sent with a keepalive request that survives the page being torn down, so the link behaves exactly as it would with no analytics on the page. The trade is that on a genuinely broken network the odd click will be lost, which we consider the right way round.
What is the difference between an event and a goal?
An event is a thing that happened. A goal is an event you have told the dashboard to treat as a conversion, so it gets a conversion rate and shows up against sources, campaigns and countries. Goals come in two kinds: one that matches an event by name, and one that matches a page by path pattern — a thank-you page makes a fine goal without writing any JavaScript at all.