Goals and revenue
Goal recipes
These conversion tracking examples help you track signups, valid form submissions and other useful actions. JavaScript recipes assume the queue stub is installed.
Track signups after confirmation
const res = await fetch("/api/signup", { method: "POST", body: form });
if (res.ok) window.stickybeak("signup", { plan: "free" });
Fire after success, not on the button. If success has its own URL, use a page-visit goal instead.
Valid form submit
document.querySelectorAll("form[data-track]").forEach((form) => {
form.addEventListener("submit", () => {
window.stickybeak("form_submit", { form: form.dataset.track });
});
});
<form data-track="contact" action="/contact" method="post">…</form>
The submit event runs after browser validation. Never pass entered form values.
Calendly booking
window.addEventListener("message", (event) => {
if (event.origin === "https://calendly.com" && event.data?.event === "calendly.event_scheduled") {
window.stickybeak("demo_booked");
}
});
Clicks and downloads
<a href="/demo" data-goal="demo_click" data-goal-placement="pricing">Book a demo</a>
<a href="/files/price-list.pdf" data-goal="download" data-goal-file="price-list">Price list</a>
Outbound, email and phone links already have automatic events.
Read to the end
const end = document.querySelector("#article-end");
new IntersectionObserver((entries, observer) => {
if (entries[0].isIntersecting) {
window.stickybeak("article_read");
observer.disconnect();
}
}).observe(end);
First video play
document.querySelectorAll("video[data-track]").forEach((video) => {
video.addEventListener("play", () => {
window.stickybeak("video_play", { video: video.dataset.track });
}, { once: true });
});
Checkout started
<button data-goal="initiate_checkout" data-goal-plan="pro">Buy Pro</button>
Do not add revenue or amount until the purchase succeeds.
404 page
<script>window.stickybeak("page_not_found");</script>