Built with Chinaski

Google Tag Manager Integration

Google Tag Manager is the second of the two analytics slots in Settings → Integrations. Paste your container ID, rebuild the site, and every page carries Google’s standard GTM loader plus a guaranteed-safe consent gate — with no tags running before your visitor has actually interacted (or consented, if your cookie banner is on).

Setting it up

  1. In Google Tag Manager, create the container for the web type and note its ID — it looks like GTM-XXXXXXX.
  2. In Chinaski, go to Settings → Integrations → Analytics, paste the container ID into GTM container ID, save, and rebuild.

Done — from the next build on, the standard GTM bootstrapping script (gtm.js?id=<your-container>) is part of every built page’s <head>, initialized with the standard empty dataLayer. Tags, triggers, and variables all live in the container: the CMS merely loads it.

Leave the field blank and nothing is emitted — the shipped script-free site output stays as-is (and the “Injected into every page at build time” hint on the field is the whole contract).

How loading behaves

The injected loader is deliberately deferred, for privacy and page speed:

  • No load on idle visits: the container’s script fetches only once the visitor does something — clicks, scrolls, presses a key, or touches the screen. The listener is one-shot; after the first interaction everything proceeds normally.
  • Respects the cookie notice: with the site’s cookie banner active, the loader waits for cookie_consent=1 before contacting Google, and it also honors an explicit decline cookie even when the banner is disabled. Consent already given at page load starts the loader immediately.
  • Because the loader is in <head>, the dataLayer is created before any body script — container tags reading pushed data (a language name, a section name) work as usual.

Practical consequence worth knowing: “page view” hits for a container trigger fire on the first interaction (or immediately for consented return visitors), not on the initial HTML download. Tune your GA/GTM reporting expectations to that.

The GA4 relationship

One analytics loader per page, ever:

  • GTM ID filled → GTM is the tracker. The gtag.js loader is skipped even if a GA4 ID is also present — tracking duplication by two paths can’t happen. Manage your GA4 tags inside the container and leave the other field blank.
  • The fields exist as separate switches on purpose: GTM is for teams who manage tags in the container; GA4 direct is the quick route. Both blank = no Google script at all.

What you don’t need to worry about

  • No server round-trip. Traffic hits Google from the visitor’s browser only; the CMS never proxies, stores, or validates the payload.
  • No escaping needed from your side: the container ID is sanitized when written into the built page, and the loader never tracks anyone before an accepted consent event.
  • Other tags stay outside the loader. This field loads one container; anything else you might want (Meta, Plausible, custom JSON) belongs in the Snippets system — which also handles the case-order and privacy-server rules.

Air-gap mode

On an isolated host this panel turns off with an explanation banner (“External analytics scripts (GA4, GTM) are disabled and will not be emitted in builds”), the input becomes read-only, and the build itself drops the container ID from memory so no build, scheduled or manual, can call out to Google — consistent with CHINASKI_AIRGAP’s no-outbound guarantee. The stored ID stays in settings for when you re-enable.

Troubleshooting

  • No GTM script in the built page — the field is blank, air-gap mode is on, or you haven’t rebuilt since saving. Check the page source for gtm.js?id=.
  • Tags don’t fire even though the loader is present — remember the loader waits for first interaction (or consent). Test by clicking anywhere on the page and watching for gtm.js in the network tab.
  • GA4 loader loads but analytics go through GTM later — you’ve set both IDs; per the precedence rule, GTM wins. Move your GA4 tags into the container, or clear the GTM field and use the direct GA4 field instead.
  • Wrong-looking container ID — the field is free text. Paste exactly GTM- + your container ID; there’s no format check, and the only compensation is an innocuous missing-script request.

The short version

Paste the container ID in Settings → Integrations, rebuild, and every page quietly ships the GTM bootstrap — loaded only after first interaction (and after consent, if you run the cookie banner), with the GA4 field ignored while a container owns the tracking, and nothing in air-gap mode.