Skip to content

Overview ​

The project's Metrics page is a lightweight traffic counter, similar to a pageview/hit counter in web analytics. It's built from hits — tiny events that carry no payload beyond a session id and, optionally, a name:

  • Pageview hits are sent automatically by the hit counter integration — one when the page loads and one per SPA navigation. They drive the Views / Visits / Visitors metrics.
  • Custom hits are ones you send yourself with Buglapse.hit(name) — "signup", "purchase", "add-to-cart". Each name gets its own row in the metrics table and never counts as a page view.

Looking for numeric values attached to spans (span.metric())? Those are a separate mechanism and live on the trace page — see Attaching metrics to a span.

Enabling pageview hits ​

The hit counter is opt-in. With the CDN script tag, turn on the Hit counter toggle on the project's Settings → Loader Script tab — it takes effect on your site's next page load, with no change to the embed.

With the npm package, add the integration yourself:

ts
import { init } from '@buglapse/browser'
import { hitIntegration } from '@buglapse/browser/integrations'

init({
    dsn: '{dsn}',
    integrations: [hitIntegration()],
})

Once registered it sends:

  • one hit immediately, for the page that just loaded;
  • one hit on every history.pushState() call and every popstate (back/forward) — i.e. every SPA route change, whatever router you use.

history.replaceState() is deliberately not counted: routers use it to normalize the URL in place (query-string updates, redirects), which isn't a new page view.

Sending custom hits ​

Call hit(name) for any event you want counted — a sign-up, a purchase, a click on a CTA:

ts
Buglapse.hit('signup')

checkoutButton.addEventListener('click', () => {
    Buglapse.hit('checkout-started')
})
ts
import { hit } from '@buglapse/browser'

hit('purchase')

Custom hits don't need the hit counter integration — hit() works on its own. They go out under the same session id as pageview hits, and if called before init() (e.g. while the CDN script is still loading) they're queued and sent once the client is ready. A hit only counts occurrences; it carries no value. To attach extra detail, use tags or context (see Context) — every hit is stamped with them like any other event.

Keep the set of names small and fixed: each distinct name becomes its own row, so don't build names from ids or user input (hit('purchase'), not hit('purchase-' + orderId)).

Visits and visitors ​

Every hit carries a session id that groups hits into visits:

  • It's stored in localStorage, so it survives reloads and new tabs on the same site.
  • It rolls over after 30 minutes of inactivity — the next hit after that starts a new visit.
  • If localStorage is unavailable (private mode, blocked storage), each hit gets a fresh id and counts as its own visit.

Read the current id with getSessionId() (Buglapse.getSessionId() on the script tag) — e.g. to pass it to your backend so its own hits land in the same visit (see Node → Metrics). It works before init() and without the hit counter integration; like a hit, reading it counts as activity and starts a new visit if the last one expired.

This session id is independent from tracing — it's not the trace id and has nothing to do with how spans are grouped.

From those sessions the Metrics page computes:

  • Views — number of pageview hits.
  • Visits — number of distinct sessions.
  • Visitors — distinct people across those visits: the identified user when you've called Buglapse.setUser() (see Identifying users), otherwise the session.

Filtering and sampling ​

Hits go through the same server-side filters as every other event on the project's Settings → Filters tab: disabled ingestion, IP / environment / release discard lists, and the crawler filter (which drops hits from bots, headless browsers, Lighthouse, uptime monitors, ...). The Hits sample rate on that tab keeps a random share of hits; lower it on high-traffic sites to save quota, keeping in mind that the numbers on the Metrics page then reflect the sampled share, not the full traffic.

Each stored hit counts as one event against the organization's monthly event quota.

Viewing on the dashboard ​

Open Metrics in the project sidebar:

  • The range switcher picks today, yesterday, week (last 7 days), or month (last 30 days); today/yesterday are bucketed by hour, week/month by day.
  • The search bar filters the chart and table by environment:, session:, name:, and the visitor's browser: / os: / device: — e.g. environment:production browser:Safari (see Search for the full syntax).
  • The table under the chart lists Views / Visits / Visitors and every custom hit with its total for the period; tick a row's checkbox to plot it on the chart (Views / Visits / Visitors are on by default), so you can compare any mix of them.
  • Custom hit names are grouped by dot notation: checkout.started and checkout.paid sit under a collapsible checkout group. A group row's total — and its line, shown as checkout.* — is the sum of every hit under that prefix.