Skip to content

Quick start

This page gets a pageview from your site into the leadmaps collector at collect.leadmaps.nl in under five minutes. It assumes you already have a leadmaps workspace and an API key. If you do not, sign up at app.leadmaps.nl and grab a key from Settings → API keys.

Terminal window
npm install @leadmaps/tracking
# or
pnpm add @leadmaps/tracking
# or
yarn add @leadmaps/tracking

The package is ESM-only and has zero runtime dependencies.

Place this as early in your bootstrap as you can. leadmaps does no blocking work, but the earlier init runs the more accurate the first pageview’s referrer attribution will be.

import { grantConsent, init } from '@leadmaps/tracking';
init({
apiKey: 'YOUR_API_KEY',
siteId: '11111111-1111-4111-8111-111111111111',
host: 'https://collect.leadmaps.nl',
mode: 'cookied',
autoCapture: true,
});
yourConsentBanner.onAccept((record) => grantConsent(record.id));

That single call:

  1. Records the current page as a pageview event.
  2. Listens for pushState / replaceState / popstate and emits a new pageview on every SPA navigation.
  3. Creates a stable first-party browser id after consent, so return visits do not inflate Unique visitors.
  4. Honours navigator.doNotTrack === '1' by default. A DNT-blocked init never installs listeners and every subsequent send is a no-op.

The example deliberately sets mode: 'cookied' for stable return-visitor measurement. The id is not read or created until consent is granted. Omit mode for a cookieless id that rotates daily, or choose anonymous privacy mode for no browser storage and no browser fingerprinting. Those modes trade cross-day continuity for less identification.

import { track } from '@leadmaps/tracking';
track('checkout_completed', {
order_id: 'ord_42',
total_cents: 4900,
currency: 'USD',
});

track() calls before init are dropped silently. There is no global queue that fills up before bootstrap.

import { identify } from '@leadmaps/tracking';
identify('user_42', { plan: 'pro' });

Calling identify() for the first time binds the current anonymous id to the known user id. If a different user id was previously bound, leadmaps emits a merge event before the new identify so cross-device timelines stay consistent.

Terminal window
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://api.leadmaps.nl/sites/site_marketing/pageviews?from=2026-05-01&to=2026-05-02"

Response:

{
"count": 1,
"by_day": [{ "date": "2026-05-02", "count": 1 }]
}

You now have a working pipeline. From here: