TL;DR: A goal counts a specific visitor action and attributes it back to a traffic source, campaign, or cohort. You can create four types: URL pattern (counts automatically when a visitor views a matching page — supports the * wildcard and is matched retroactively against historical pageviews), event name (counts when your site sends a custom event with that name), outbound link, and file download. Add a goal from the dashboard Goal card — click Add goals — or at /dashboard/goals. Ecommerce stores typically track purchases and checkouts; SaaS products typically track signups, trials, and subscription starts. For a SaaS funnel, fire one-line events from your app: window.admaxxer('Signup'), window.admaxxer('Trial Started'), window.admaxxer('Trial Converted'), window.admaxxer('payment', { value: 49, currency: 'USD' }), and window.admaxxer.identify('user@email.com') to stitch the anonymous visitor to the paying customer. Goals come from two sources — your own first-party pixel and your billing provider — reconciled, so the funnel stays populated even if a billing message is missed. Goals appear on your dashboard Goal tab with conversions, unique visitors, and an optional value.
A goal is a single action you want to count and attribute back to a traffic source, campaign, or cohort. Where a page view just says "someone landed here," a goal says "someone did the thing that matters" — completed a checkout, started a trial, downloaded your pricing PDF, or booked a call.
You define what counts. Once a goal exists, Admaxxer matches it against your visitor activity and shows you how many times it happened, how many unique people did it, and — if you add a value — how much it was worth. Goals that are based on page addresses are even matched retroactively, so a URL goal you add today starts with the history you already have, not from zero.
A goal you track doesn't rely on one fragile signal. It's built from two sources that back each other up:
It stays populated even if a billing message is missed. Because your pixel fires the event the moment it happens — independent of your billing provider — your funnel keeps filling in even if a billing notification is ever delayed or dropped. The two sources reinforce each other, so a single hiccup never leaves you blind. This is the difference between guessing and knowing: an ad platform tells you what it thinks it drove; your first-party pixel — stitched to the paying customer with identify() — tells you what actually happened, reconciled against the real money.
Pick the type that matches how the action happens on your site.
* as a wildcard to match anything. No extra code, and it counts your existing history. Example: /checkout/thank-you*.Signup.calendly.com. (Conversion counting coming soon.).pdf. (Conversion counting coming soon.)URL goals count themselves. A URL-pattern goal needs no extra code — it's matched against the pages your visitors already view, including pages they viewed before you created the goal. Use * as a wildcard, e.g. /checkout/thank-you* matches /checkout/thank-you, /checkout/thank-you?order=123, and so on.
There are two ways in, and they land in the same place:
Goals belong to a website. If you track more than one site, pick the right one from the website selector at the top of the goals page before you create the goal.
For a store, the actions that matter are about revenue: completed orders, started checkouts, added-to-cart. A couple of goals cover most of it.
| Goal name | Type | Match value |
|---|---|---|
| Purchase completed | URL pattern | /checkout/thank-you* |
| Purchase (event) | Event name | purchase |
| Checkout started | URL pattern | /checkout* |
| Sizing guide downloaded | File download | .pdf |
For a SaaS product, the actions that matter are about activation and revenue: signups, trials, and subscription starts. These are usually event-name goals because they happen inside your app, not at a fixed URL — though a welcome page works well as a URL goal.
| Goal name | Type | Match value |
|---|---|---|
| Signup | Event name | Signup |
| Trial started | Event name | Trial Started |
| Paid / subscription started | Event name | Trial Converted |
| Welcome screen reached | URL pattern | /welcome |
Stores and SaaS apps track different things — and that's the point. Ecommerce goals lean on purchases and checkouts; SaaS goals lean on signups, trials, and subscription starts. Keep your goals matched to what your product actually does and your reports stay clean.
Three one-liners cover the whole SaaS funnel. Fire each at the moment the action happens. The event names are case-sensitive and must match your goal exactly — copy them as-is:
// 1. Account created — always fire this from your app.
window.admaxxer('Signup');
// 2. Free trial begins.
window.admaxxer('Trial Started');
// 3. Trial turns into a paid subscription (the headline event).
window.admaxxer('Trial Converted');
To record the money on a payment, send a payment event with a value and currency. Your billing provider stays the system of record for recurring revenue — this gives your pixel an immediate, first-party read of the same dollars:
window.admaxxer('payment', { value: 49, currency: 'USD' });
Call identify() with the user's email the moment they sign up or log in. This stitches the anonymous visitor — the one who clicked your ad — to the user who pays you. From then on, the signup, the trial, and the subscription all attribute back to the exact ad, campaign, and channel that drove them. It's the difference between a platform claiming credit and your own data proving it:
window.admaxxer.identify('user@email.com');
Card-required trials: if your trial requires a card up front, your billing provider already sees the trial — it fires Trial Started and Trial Converted for you, so you should NOT also fire them from the pixel (you'd double-count). Always fire Signup yourself — there's no billing equivalent. For a no-card / in-app trial, fire all three from the pixel as shown above. Want this wired for you, pre-filled with your real site details? See the full SaaS analytics setup guide — it also covers the SSR-safe install for Next.js, Remix, and SvelteKit.
This is the one thing worth getting right. There are two families of goal:
So if you created an event goal called Signup and it's sitting at zero, the fix is usually to make your site send a Signup event at the moment someone signs up. Here's how.
Once the Admaxxer tracking snippet is on your site, window.admaxxer is a function you can call. Fire your event from the moment the action happens — one line:
window.admaxxer('Signup');
The name you pass must match your goal's event name exactly. You can attach a few extra details as a second argument if you want to slice on them later:
window.admaxxer('Trial Converted', {
plan: 'pro',
source: 'pricing',
});
For an ecommerce store, fire a purchase event when the order is confirmed:
window.admaxxer('purchase');
If the snippet might not be loaded yet, guard the call so it never errors: typeof window.admaxxer === 'function' && window.admaxxer('Signup'). Prefer no code at all? Add data-admx-goal="Signup" to a button and it fires on click. For every option — clickable elements, single-page apps, and sending events from your own backend — see the custom goals developer reference.
Your goals appear on the dashboard Goal tab, each with its conversions (how many times it happened), unique visitors (how many different people did it), and an optional value when you've set one. Open the goals page to see the full list, edit a goal, or expand a goal for its conversion trend over time. From there you can chain goals into a conversion funnel to see where people drop off between steps.
Almost always it means your site isn't sending that event yet. Event-name goals only count when your site fires a custom event with the exact same name. Make your site send the event (window.admaxxer('Your Event Name') or a data-admx-goal attribute) at the moment the action happens, then check again. URL-pattern goals don't have this problem — they count automatically from pageviews.
URL-pattern and event-name goals do — both are matched against the data you've already collected within the date range you're viewing, so they can show conversions from before you created the goal. Outbound-link and file-download goals can be created today; conversion counting for those two types is coming soon.
A URL goal counts when a visitor views a page whose address matches your pattern — no extra code needed. An event goal counts when your site sends a named custom event. Use a URL goal when your conversion lands on a real page (a thank-you or welcome page); use an event goal for actions that happen in-app without a dedicated URL.
Put * where the address can vary. /checkout/thank-you* matches /checkout/thank-you, /checkout/thank-you?order=123, and /checkout/thank-you/abc. /blog/* matches every page under /blog. This lets one goal cover many addresses.
Yes. When you create or edit a goal you can set an optional value — for example the average revenue a conversion is worth. Admaxxer totals it across conversions so you can see the value a goal is driving, not just the count.
No — they care about different actions. A store tracks purchases and checkouts; a SaaS product tracks signups, trials, and subscription starts. Match your goals to what your product actually does.
Fire a one-line event at each step from your app: window.admaxxer('Signup') when an account is created, window.admaxxer('Trial Started') when a free trial begins, and window.admaxxer('Trial Converted') when it turns into a paid subscription. The names are case-sensitive and must match your goal exactly. To record the money on a payment, send window.admaxxer('payment', { value: 49, currency: 'USD' }). For a no-card / in-app trial, fire all three yourself; if your trial requires a card up front, your billing provider fires Trial Started and Trial Converted for you, so only fire Signup from the pixel.
Call window.admaxxer.identify('user@email.com') the moment a user signs up or logs in. It stitches the anonymous visitor — the person who originally clicked your ad — to the user who pays you. From then on, the signup, trial, and subscription all attribute back to the exact ad, campaign, and channel that drove them. This is what makes the attribution first-party and trustworthy: instead of a platform claiming credit, your own data proves which source actually produced the paying customer.
Both, reconciled. Your first-party pixel records each funnel action the instant it happens and ties it to the channel that drove the visitor; your billing provider confirms the exact money for paid conversions and recurring revenue. Admaxxer reconciles the two so the count and the revenue line up — and because the pixel fires independently of billing, your funnel keeps filling in even if a billing notification is ever delayed or dropped. The two sources reinforce each other rather than relying on one.
Custom goals (developer reference) · SaaS analytics setup · Conversion funnels · Install the tracking snippet · Metric glossary