Going further
Goals & events
Pageviews are automatic. Everything else — signups, trials, demo bookings — is a goal you fire yourself, and each one can be measured by the revenue it eventually produces.
Firing a goal
window.numberhill.goal("signup");
// with metadata
window.numberhill.goal("trial_started", { plan: "pro", seats: 3 });Without writing JavaScript
Any click on an element carrying data-numberhill-goal fires automatically — the script delegates from document, so it works for elements added later.
<button data-numberhill-goal="pricing_cta">Start free trial</button>Outbound links and downloads
These need no tagging at all. A click on a link to another host is recorded as an outbound event, and a link to a file — by extension, or carrying a download attribute — as a download. Both appear in customer journeys, which is usually where they matter: a journey that ends at a click through to your checkout provider reads very differently from one that simply stops.
Only the destination is recorded, never anything about the page it leads to. To exclude a link, or a whole region of the page, add data-numberhill-ignore — it is honoured on the link itself or on any ancestor.
<!-- not recorded, nor is anything inside it -->
<footer data-numberhill-ignore>
<a href="https://status.example.com">Status</a>
</footer>Identifying users
Once someone signs up you can attach traits to the visitor, which is what turns an anonymous row in the live view into a name in the customer journey.
window.numberhill.identify({
email: "[email protected]",
name: "Maya K.",
plan: "pro",
});Same visitor, whole history
Identify doesn't create a new person — it labels the existing visitor ID, so their earlier anonymous pageviews stay attached to the journey.Automatically, from your forms
If you'd rather not add the call yourself, add data-autoidentify to the script tag. Every form submission is then scanned for an email field, and the address found there is sent as identify({ email }) — signups, contact forms and newsletter boxes all start naming visitors with no code of your own.
<script defer data-website-id="YOUR_SITE_ID" data-autoidentify
src="https://numberhill.com/js/numberhill.js"></script>Only an email address is ever read — never a password and never any other field. Mark a form or a single input with data-numberhill-ignore to skip it entirely.
It's off unless you turn it on
This reads something the visitor typed, so it is your decision, not ours. Before switching it on, make sure you have a lawful basis for it and that your privacy policy says you collect email addresses submitted through your forms. On a store with a consent banner, a script embedded in your theme is not gated by it automatically — gate the tag yourself if your region requires consent before analytics.On Shopify, the standard storefront forms are all caught: the newsletter footer and contact page (contact[email]) and the account create and login forms (customer[email]). Checkout is not — /checkouts/… is Shopify-hosted and takes no theme scripts, so no visitor is identified there. You lose nothing by it: the orders/paid webhook carries the customer's email and it is attached to their journey on arrival, which is what already names your buyers today. What auto-identify adds on a store is the people who filled in a form and never bought.
The window.numberhill API
numberhill.visitorId()— the current visitor ID, for checkout metadata.numberhill.goal(name, meta?)— record a conversion event.numberhill.identify(traits)— attach who this visitor is.
Guard your calls
If the script is blocked,window.numberhill is undefined. Optional chaining — window.numberhill?.goal("signup") — keeps analytics from ever breaking a flow.Funnels
Funnels are ordered lists of steps built from the events you already send — a pageview path, a goal name, or a payment. Define them in the dashboard; no extra instrumentation needed once the goals exist.
Visited site pageview
Viewed pricing pageview:/pricing
Signed up signup
Started trial trial_started
Paid payment