Install the tracker
Step-by-step installation manual for the WebmasterID browser tracker. Static HTML, Next.js (App + Pages Router), React/Vite, Astro, WordPress. Verification checklist + troubleshooting included.
Last updated: v1.5.2 · 2026-05-10
1. Prerequisites
- A WebmasterID site created in the dashboard (Sites page → Add a new site). After creation you have a public
site_idthat starts withwm_. - Access to the website's codebase (or theme/CMS header).
- A consent decision for jurisdictions where analytics requires it (GDPR/ePrivacy in the EU, similar elsewhere). See /docs/privacy for the consent-first loading pattern.
2. The universal script tag
This is the only thing you ever need to install. Paste it into the site-wide <head> and replace wm_xxxxxxxxxxxxxxxx with the public site_id from the dashboard.
<script id="webmasterid-tracker" defer src="https://webmasterid.com/tracker.iife.min.js" data-wmid="wm_xxxxxxxxxxxxxxxx" data-endpoint="https://webmasterid-ingest-api.vercel.app/api/events" ></script>
- Replace
wm_xxxxxxxxxxxxxxxxwith thesite_idshown for the site row on/sites. - Do NOT change the
srcURL unless WebmasterID documents a new CDN URL. The version is pinned at the URL level. - Do NOT remove
data-endpoint. The tracker needs it to POST events. - Do NOT add any server-side secret material to the browser snippet. The browser snippet uses ONLY the public site id and the public ingest endpoint. Server-side secrets stay server-side.
- The
deferattribute ensures the tracker never blocks rendering. - The
id="webmasterid-tracker"is used by Verify Install to spot the tag inside HTML quickly. It's optional but recommended.
3. Exact placement by framework
3.1 Static HTML
- Open the base HTML file (
index.htmlfor a single page, or the layout/template that wraps every page). - Paste the snippet immediately before the closing
</head>tag. - Save the file.
- Deploy normally (commit + push, or upload).
- Verify (see §5).
3.2 Next.js — App Router
Edit app/layout.tsx (or the root layout your app actually uses). Use Next's built-in next/script so the tag is included in the streamed HTML and respects route transitions.
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
{/* preserve your existing <title>, metadata, canonical, etc. */}
<Script
id="webmasterid-tracker"
src="https://webmasterid.com/tracker.iife.min.js"
strategy="afterInteractive"
data-wmid="wm_xxxxxxxxxxxxxxxx"
data-endpoint="https://webmasterid-ingest-api.vercel.app/api/events"
/>
</head>
<body>{children}</body>
</html>
);
}- Place it in the ROOT layout so every route is covered.
- Do NOT place the snippet only on a single page — visits to other routes won't be recorded.
- Preserve any existing
metadata,canonical,sitemap.ts,robots.ts, andhreflanglogic unchanged. The tracker is additive.
3.3 Next.js — Pages Router
Edit pages/_document.tsx so the tag is rendered into the streamed HTML for every page.
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html lang="en">
<Head>
{/* preserve your existing <Head> contents */}
<script
id="webmasterid-tracker"
defer
src="https://webmasterid.com/tracker.iife.min.js"
data-wmid="wm_xxxxxxxxxxxxxxxx"
data-endpoint="https://webmasterid-ingest-api.vercel.app/api/events"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}_document.tsxrenders globally — the right place for a tag that must appear on every page.- Do not duplicate the snippet inside
_app.tsxor any page-level<Head>.
3.4 React + Vite
- Open
index.htmlat the project root. - Paste the snippet immediately before
</head>. - Run
npm run build(or your build command) and deploy the resultingdist/output.
3.5 Astro
Edit your shared base layout — typically src/layouts/Layout.astro (or whatever you named the layout that every page uses).
---
// src/layouts/Layout.astro (or your shared layout)
---
<html lang="en">
<head>
<!-- preserve existing title, meta, canonical, etc. -->
<script
is:inline
id="webmasterid-tracker"
defer
src="https://webmasterid.com/tracker.iife.min.js"
data-wmid="wm_xxxxxxxxxxxxxxxx"
data-endpoint="https://webmasterid-ingest-api.vercel.app/api/events"
></script>
</head>
<body>
<slot />
</body>
</html>is:inlinestops Astro from bundling the tag — it should ship as-is.- Verify every page actually uses this layout. Pages with a different layout won't collect events.
3.6 WordPress / manual CMS
- In WP-Admin, open Appearance → Theme File Editor (or edit through your child theme directly).
- Open
header.phpand paste the snippet immediately before the closing</head>tag. - Save. Open the site in a private window and view the page source to confirm the tag is present.
- If you use a security plugin (Wordfence, etc.) that has a "header injection" or "custom code" area, paste there instead so theme updates don't overwrite the snippet.
- Do NOT add the tag only to a single post or page. The tag belongs in the site-wide header.
- Many GDPR-aware WP setups gate analytics behind a consent banner. Use that gating mechanism instead of pasting the snippet directly into the header — see §4.
4. Consent / GDPR note
WebmasterID does not set tracking cookies or fingerprint visitors, but analytics still requires consent in many jurisdictions (EU/EEA, UK, parts of Brazil, parts of California depending on interpretation). The simplest pattern:
- Load the WebmasterID tracker only AFTER the visitor has consented to analytics.
- Visitors who select "necessary only" should not load the tracker at all.
- Do not use consent state as a visitor identifier (don't put a consent token into a UTM parameter or a CTA id).
- See /docs/privacy for the full consent-first pattern, and link to your own privacy / cookie notice from the consent UI.
5. Verification checklist
After you deploy, work through this checklist in order:
- Open the site in a fresh private/incognito browser window so ad-blockers and consent state from previous sessions don't confuse the test.
- Open DevTools → Elements. Search the HTML for
data-wmid. The value should be your publicwm_id. - Switch to Network and reload. Look for two requests:
tracker.iife.min.js— should return HTTP 200.- A POST to
/api/eventsonwebmasterid-ingest-api.vercel.app— should return HTTP 202.
- On the dashboard, open
/sitesand click Verify install on the site row. The expected status isinstalled_and_receiving_events(or, on a brand-new install with no real visit yet,snippet_found_no_events_yet— visit the site once in a real browser and re-verify). - Open
/events. You should see your freshpage_viewwithin a few seconds.
6. Expected result
- Verify Install status =
installed_and_receiving_events. - The first
page_viewappears in/eventswithin seconds. - No console errors from WebmasterID code.
- No duplicate event bursts (one page-view per real navigation).
- Lighthouse score unchanged (the tracker is ~6 KB and deferred).
7. Troubleshooting
snippet_missing
Verify Install fetched the homepage but did not find data-wmid="wm_…" for the operator's site.
- Did the deploy actually ship? Re-deploy and re-verify.
- Is the snippet in the SHARED layout, not just one page?
- Is a CDN / framework caching the old HTML? Bust the cache (a force-purge from your CDN dashboard or a fresh deploy).
installed_with_different_site_id
A WebmasterID snippet IS on the page, but it uses a different wm_ id than the row you clicked Verify Install from.
- Check whether you have a duplicate domain in your account (the v1.2.4 amber badge on
/siteshighlights this). The Verify Install response includes the found id; if you also own that id, the operator UI names it directly. - If the deployed id is correct, click Verify Install on that row instead.
- If the deployed id is wrong, edit the snippet to use the correct id and re-deploy.
snippet_found_no_events_yet
The snippet is on the page but no page_view has landed in the last 24 hours.
- Open the site in a real browser (not a headless probe) and confirm the
/api/eventsPOST returns 202. - Check whether an ad-blocker (uBlock Origin, AdGuard) is suppressing the tracker.
- Confirm the test browser does not have Do Not Track or GPC enabled if your ingest respects them.
- Check that the consent banner has actually granted analytics consent.
events_received_snippet_not_visible
Events ARE arriving but the homepage probe didn't find the snippet markup.
- The tracker may be installed via a framework wrapper that emits the script through an inline JSON payload (Next.js RSC, etc.). The detector is tolerant but not infallible — open page source manually and confirm.
- The tracker may be only on some routes. The fix is to move it to the site-wide layout.
- The deployed canonical hostname may differ from what's stored in
/sites. Edit the site's domain to match.
fetch_failed
The probe couldn't reach the homepage at all.
- Is the site behind authentication (staging environment, basic-auth gate)? Verify Install only follows public http(s) URLs.
- Did Cloudflare / your WAF challenge the probe's
WebmasterID-InstallCheck/1.0User-Agent? Either allow it, or visit a page in a real browser to seed events and rely on the recent event signal instead. - Is the site genuinely down? Try opening it in a browser.
Ad-blocker blocking events
- Some ad-blocker rules ban any request to known ingest hostnames. That's an ad-blocker policy decision, not something WebmasterID overrides — and we don't want to override it.
- For internal QA, test in a clean browser profile or use
Incognitowith extensions disabled.
Wrong domain (www vs apex)
- Verify Install probes both apex and
wwwvariants automatically (v1.2.3). The result includes every URL it attempted with a coarse status. - If your canonical is
www.acme.combut/sitesshowsacme.com, edit the site domain to match — it doesn't affect the snippet, only the probe target.
Archived site still receiving events
- Archive is a dashboard-side filter (v1.2.5). It hides the site from default selectors, but the deployed tracker keeps sending events. To fully stop tracking, remove the snippet from the live site or restore the row.
- See
/diagnostics→ Site archive state for the owner-scoped active/archived/total counts.
8. Security warnings
- Never embed any server-side secret in browser code. The browser tracker uses only the public
wm_site id and the public ingest endpoint. Anything that ends up in a server-side ingest path lives behind your server, not in HTML. - Do NOT remove
data-endpoint. The tracker won't POST events without it. - Do NOT load the tracker from a fork or mirror. The pinned URL on the WebmasterID CDN is the only audited source.
- Do NOT proxy events through your own server unless you know why. The ingest endpoint is intentionally public and CORS-safe.
9. SEO preservation
- The tracker is additive. It never removes existing meta, canonical, OpenGraph, JSON-LD, robots, sitemap, or hreflang tags.
- When editing layout files, keep all SEO-related elements intact. If a coding assistant reorganises your
<head>, review the diff before merging. - The tracker is
deferred — it never blocks render, and Lighthouse scores stay unaffected.