Skip to content
Twilight React Playground
ثيم رائدaren

GoogleTagBody

componentAdvancedbrowserlive demo

Loads a Google Tag Manager container on the page and filters sensitive fields out of dataLayer pushes; the engine mounts the store's automatically.

import { GoogleTagBody, LazyGoogleTagBody, GoogleTagBodyProps } from '@salla.sa/twilight-theme-engine/tracking';

In plain words

Google Tag Manager (GTM) is how merchants add analytics and ad tracking. GoogleTagBody adds GTM's loader for a container id, and draws nothing itself.

When the merchant has set a container in Salla, the engine already renders this on every page. You would add one yourself only for a container of your own. LazyGoogleTagBody is the same component, loaded when it first renders.

Signature

function GoogleTagBody(props: GoogleTagBodyProps): null
const LazyGoogleTagBody: React.LazyExoticComponent<typeof GoogleTagBody>

interface GoogleTagBodyProps {
  gtmIds?: string[];   // only the first id is used; none: nothing happens
}

Try it live

This demo store has a Google Tag Manager container, so the engine already mounted GoogleTagBody on this page. Inspect what it added.Try this: push the event, then read the entry: the wrapper the loader installs deletes form_data (and data, config, request, headers…) from pushed objects.
Real requests to the demo store
Storefront canvas · ar · RTL
Runs in the browser…
What a theme writes
import { GoogleTagBody } from '@salla.sa/twilight-theme-engine/tracking';

// TwilightProvider already mounts one for the store's own container (store.settings.keys.gtm).
// Render your own only for a container the store settings do not name.
export function ThemeAnalytics() {
  return <GoogleTagBody gtmIds={['GTM-XXXXXXX']} />;
}

Example

app/components/ThemeAnalytics.tsx
import { GoogleTagBody } from '@salla.sa/twilight-theme-engine/tracking';

// The store's own container is loaded already. This adds a second one.
export function ThemeAnalytics() {
  return <GoogleTagBody gtmIds={['GTM-XXXXXXX']} />;
}

How it behaves

  • In an effect it appends <script id="gtm-script"> to <head> (the standard GTM snippet) and a <noscript> iframe at the start of <body>, and removes both on unmount.

  • The script then replaces window.dataLayer with a Proxy that deletes form_data, data, gateway, config, request and headers from every object pushed to it.

  • The default body:start handler renders it with gtmIds={store.settings.keys.gtm} when that list is not empty (priority 100). This demo store has one.

Gotchas

  • <TwilightProvider gtm={false}> (packages/theme-engine/docs/gtm-integration.md, "Disable Automatic GTM") does not stop the store's container: the prop is declared and never read. Rendering your own GoogleTagBody with the store's id loads the container twice.

  • The only way to stop the store's container is hookRegistry.clear('body:start'), which also removes the Sift snippet, the store-closed bar and any body:start handler your theme registered earlier. Register the ones you keep again after clearing.

  • The <noscript> fallback is created by JavaScript after hydration, so a visitor without JavaScript never gets it, which is the only case it exists for.

  • Every instance's script gets the id gtm-script, and unmounting removes the first element with that id, which may belong to another instance.

Related

Source and docs