Set up tracking and consent
From the client's accounts to a live site whose tags fire with the visitor's consent, with one test run on staging in between. Written against 2.18.0.
- You need access to the client's Google Tag Manager, GA4 and, where used, Meta, LinkedIn, Pinterest and Google Ads accounts, plus a developer login on the site.
- You get one GTM container with the platform tags, Consent Mode v2 with the policy the client chose, the two server-side conversions, and the checks that keep it working.
- Pages Tracking and Consent, Google Tag Manager, Settings, Health Checks
1. Decide the consent policy with the client
Evolve implements Google Consent Mode v2 with two categories, analytics and marketing. Three settings on the Consent card of Settings > Tracking decide how they start and who asks the visitor:
| Decision | Setting |
|---|---|
Granted until the visitor declines (opt-out, the Swiss default under the DSG) or denied until the visitor accepts (opt-in, as the GDPR requires) | Consent policy |
| Show the Evolve cookie banner | Cookie banner |
| The client runs a consent platform (Cookiebot, Usercentrics) in the GTM container instead | Consent via CMP |
The panel refuses opt-in with neither the banner nor the CMP option on, because nobody could grant consent. With the banner off and opt-out, everything is granted and nobody can decline. That is a decision for the site owner, not a default to leave unexamined. Record the choice in the project notes.
Check: view the source of any page. The inline consent script near the top of <head> calls gtag('consent', 'default', ...) with granted or denied matching the policy. It renders on every environment.
2. Collect the IDs
| Platform | Where to find the ID |
|---|---|
| GA4 | Analytics Admin > Data Streams > Web, "Measurement ID" (G-...) |
| Meta pixel | Events Manager > Data Sources, the pixel's ID |
| Campaign Manager > Analyze > Insight Tag, partner ID; conversions under Conversion Tracking | |
| Ads > Conversions > Pinterest Tag, tag ID | |
| Google Ads | Goals > Conversions, each action's conversion ID and label |
For the server-side conversions you also need the GA4 Measurement Protocol API secret (Analytics Admin > Data Streams > Web > Measurement Protocol API secrets) and the Meta Conversions API access token (Events Manager > Settings of the pixel).
3. Build the container
- Create a Web container for the site in GTM.
- Import
vendor/racerfish/evolve/theme/gtm_container.jsonunder Admin > Import Container, into a new workspace, merge. It brings the tags, triggers and variables for GA4, the Meta pixel, LinkedIn Insight, Pinterest and Google Ads, wired to the events the theme pushes. - Edit the platform variables with the IDs from step 2. Delete the tags of platforms the client does not use.
- Keep the consent checks on the tags. Evolve sets the Consent Mode default before GTM loads and the banner updates it; the tags wait for that.
Do not publish yet; step 5 previews the workspace first.
4. Put the IDs on the site
In the panel under Settings > Tracking:
| Card | Fields |
|---|---|
GTM container, GA4 measurement ID, conversion data (settings store); ANALYTICS_API_SECRET (.env, secret, masked) | |
| Facebook / Meta | pixel ID (settings store); FACEBOOK_CONVERSIONS_API_KEY (.env, secret, masked), FACEBOOK_TEST_EVENT_CODE (.env) for the test run |
| Server-side tracking | server-side events stay on or inherit; drivers without credentials disable themselves |
| Pinterest, LinkedIn, Hotjar | tag ID, partner and lead conversion IDs, site ID where used |
The public IDs go into the settings store, the secrets and the debugging switches into the .env of the environment the panel runs on. A database copy carries the stored IDs to staging; that is harmless, because a staging site renders no GTM snippet and sends no conversions. On a site whose .env still carries GTM_ID and friends, the panel shows those as placeholders and an import hint; run php artisan evolve:settings:import once so the store holds them.
Check: GET /api/health-check carries a tracking block with every ID, whether the secrets are set, and sources saying where each value came from.
5. Test run on staging
- In Settings, Developers tab, switch Tracking emit on (
TRACKING_EMIT=true). The staging site now renders the GTM snippet and sends conversions as live would. - Set
TRACKING_DEBUG=trueunder Server-side tracking. GA4 events go to the validation endpoint instead of the live property and every delivery is logged. SetFACEBOOK_TEST_EVENT_CODEso Meta events land in the Test Events view. - Open GTM Preview mode (Tag Assistant) against the staging URL. The consent default appears first in the
dataLayer, thenpage_view. - If the banner is on, decline, then accept. The theme calls
gtag('consent', 'update', ...)and pushesconsent_analyticsandconsent_marketing; the tags fire after the accept, not before. - Submit a form. Preview shows
form_submitandgenerate_leadfrom the browser; the log shows the GA4 validation response and, in Meta's Test Events view, the server copy with the same event ID. - Switch Tracking emit off again and clear
TRACKING_DEBUGand the test event code. The tracking health check warns as long as a staging site is left emitting.
Check: curl -s https://staging.client.ch/ | grep -c gtm.js is 0 again after step 6.
6. Publish and verify on live
Publish the container. On the live site, the environment type lets tracking emit on its own; TRACKING_EMIT stays unset.
curl -s https://client.ch/ | grep -c gtm.js # 1
curl -s https://client.ch/api/health-check | jq .tracking- GA4 DebugView shows
generate_leadonce from the browser and once from the server with the same event ID when both paths are on. /evolve/healthshows the tracking check green. It fails on live when GTM or GA4 is missing or malformed orTRACKING_EMIT=falsesilences the site.- Fleet reads the
trackingblock of/api/health-checkand compares it across environments.
7. Keep it working
- Leads carry the visitor's first landing page, referrer and UTM parameters from the
footprintscookie, independent of the tags, so attribution in the panel keeps working when a visitor declines. - For a site that deliberately has no tracking, set
HEALTH_CHECK_TRACKING=falseinstead of living with a failing check. - The ID of a new platform goes into the container's variable and, where Evolve uses it server-side (GA4, Meta), into Settings > Tracking as well.
Done when
- The consent default on every page matches the policy the client chose, and the banner, where on, updates it.
- Live renders the GTM snippet, staging does not.
- A form submission on live arrives in GA4 from the browser and the server with the same event ID.
- The tracking health check is green on live and silent on staging.