Analytics, consent, and the CSP
Where do I put my GA4/GTM/Meta ID, and why is nothing showing up?
The one precedence answer (dashboard beats config), how consent gating changes what you see, and why the CSP opens itself only for what you enable.
Typical effort: 5 minutes
The recipe — paste this to your AI
# Recipe — analytics (GA4 / GTM / Meta Pixel): the ONE precedence answer Three docs used to give three partial answers; this is the whole story in one place. ## The precedence chain (highest wins) 1. **Dashboard → Settings → Analytics** (per-org, stored in your Genesis org). LIVE: takes effect on the site within minutes, **no deploy**. This is where your IDs should live. 2. **`site.config.ts → analytics`** (build-time fallback, in your repo). Used only when the dashboard setting is absent — e.g. before the site is connected to an org, or for a fully static deployment. Same IDs in both places is harmless; the dashboard value wins. ## What happens automatically once an ID is set (either way) - The tracking scripts inject on every page — no page edits, no `<script>` pasting. - The **Content-Security-Policy opens only for the providers you set** and stays fully closed otherwise. Do not hand-edit the CSP for analytics; it wires itself. - **Consent gating is enforced**: third-party trackers fire only after the visitor's consent state allows them (the banner posts explicit grant/deny). An ID being configured does NOT mean every visitor is tracked — that's a feature, not a bug, and it is why a freshly-set pixel can show fewer hits than raw traffic. ## First-party tracking is separate (and needs no IDs) `site.config.ts → tracking` reports visits to your OWN backend for revenue attribution — no third-party pixel involved. It arms itself when the site knows your org (`NEXT_PUBLIC_CONTACT_ORG_ID` — see `.env.example`), and its consent posture is enforced server-side per organization. ## Verifying it works 1. Set the ID in the dashboard, wait a few minutes, open the LIVE site. 2. Accept the consent banner, then check the network tab for the provider's request (`gtag/js`, `gtm.js`, or `fbevents.js`). 3. No request? Check, in order: consent state (did you accept?), the dashboard save, then whether the site is actually connected to that org (`DEPLOY.md` Gotcha 5). ## Why "the setting is saved but nothing happens" usually isn't the setting The ID is per-org DATA; the code that reads it and injects the tag is a FRAMEWORK feature that reaches your site through template releases. If the dashboard value is saved and the consent state is granted but no tag ever loads, your clone is likely behind — merge the latest template release (`UPGRADING.md`).
Source of truth
This recipe ships inside the template as docs/prompts/set-up-analytics.md — this page renders that exact file. The repository is always the newest version: https://github.com/srisenmay/bringthefront-template. Clone the template and you get every recipe locally, versioned with the release you are on.