Before you begin
- Theme and layout already set; see Apply your branding if you have not configured
docs.jsonyet - A published docs URL for verification (merge to your default branch, open a branch preview, or use a custom domain). Local
docs previewdoes not load analytics scripts - For Plausible only: a vanity subdomain or custom domain mapped to your docs. Plausible requires a resolved hostname
Add a top-level scripts object to docs.json. docs.page injects the matching tags on published pages only, not during local preview. For how injection works, GTM versus GA precedence, and preview suppression, see Analytics.
| Provider | Use when |
|---|---|
| Google Tag Manager | You manage tags in GTM and want one container for GA and other scripts |
| Google Analytics (GA4) | You want a direct GA4 integration without Tag Manager |
| Plausible | You use Plausible and have a custom domain or vanity subdomain on your docs |
When both googleTagManager and googleAnalytics are set, docs.page loads GTM only and skips direct GA injection. Route GA through your GTM container instead. Plausible loads only when the request resolves to a configured custom domain or vanity subdomain, not on the default docs.page/{owner}/{repo} path alone.
Pick one provider approach
Choose a row from the table above and gather the container ID, measurement ID, or Plausible site for that provider.
Declare scripts in docs.json
Add a
scriptsobject at the top level ofdocs.json. Use one of the shapes below.json{ "scripts": { "googleTagManager": "GTM-XXXXXXX" } }Replace
GTM-XXXXXXXwith your container ID from Google Tag Manager.For field types, optional keys, and additional examples, see docs.json: scripts.
Publish so the live site picks up config
Commit and push
docs.json, then merge to your default branch or share a branch preview URL. See Publish.Analytics tags render on published pages (production, branch previews, and custom domains), not in local preview mode.
Do not rely on docs preview to confirm analytics. Preview request mode suppresses all script injection so local editing does not send events to production dashboards.
Open a live docs URL (not the local preview shell) and confirm the provider script loads.
- Open your published site: production URL, branch preview (
https://docs.page/{owner}/{repo}~{ref}), or custom domain. - Inspect the page in DevTools: open Network, reload, and filter for:
- GTM:
gtm.jsfromgoogletagmanager.com - GA4 (direct):
gtag/jswhengoogleAnalyticsis set andgoogleTagManageris absent - Plausible:
script.jsfromplausible.ioor your self-hosted URL
- GTM:
- Confirm events in the provider dashboard: GTM Preview or Tag Assistant for Tag Manager; GA4 Realtime for direct GA; Plausible dashboard for page views on your mapped domain.
For Google Analytics, set title in frontmatter on every page. GA reads page_title from the document <title>. Without a per-page title, every route shares your site name from docs.json (or "Documentation") as the page title, even though URLs still differ. Body # headings do not set the document title. See Per-page titles in Google Analytics.
On the default docs.page/{owner}/{repo} path with no custom domain, GTM and GA still load when configured. Plausible stays inactive until a domain is resolved.
| Symptom | Likely cause | Fix |
|---|---|---|
| No analytics scripts in local preview | Expected (preview mode suppresses scripts) | Verify on a published or branch-preview URL |
| GA4 script missing but GTM is configured | GTM takes precedence over direct GA | Add GA as a tag inside GTM, or remove googleTagManager to use direct GA |
| GA shows one page title for every route | Pages missing frontmatter title | Add title to each page's YAML frontmatter (body # headings do not count); see Page frontmatter |
| Plausible script never loads | No custom domain or vanity subdomain on the request | Use a vanity subdomain or request a custom domain, then open the site on that hostname |
| Plausible loads but no page views | data-domain must match the hostname readers use | Confirm the domain in Plausible matches your docs domain exactly |
| Scripts present but no dashboard data | Provider misconfiguration or ad blockers | Check container or measurement ID spelling; test in a clean browser profile |
| Changes not reflected after push | Cached bundle or wrong branch | Confirm docs.json is on the branch docs.page serves; hard-reload the live page |
- Analytics: how docs.page injects scripts, GTM versus GA, and preview suppression
- docs.json: scripts: full
scriptsfield reference - Vanity subdomains or Custom domain: resolved hostname for Plausible
- Local preview: why preview stays script-free
