GTM + GA4 Content Group
Tracking Playbook
Step-by-step instructions for setting up content group tracking, goal actions (PDF downloads, form submissions, CTA clicks), and GA4 conversions using Google Tag Manager.
0 Architecture Overview
Before touching GTM, understand the flow. Every event you set up follows this same pipeline:
user action
detects the action
GA4 Event tag
receives event
marked in GA4
GTM has three core building blocks:
1 Variables — Set These Up First
Variables are the foundation. You need these before building any triggers or tags. Go to: Variables tab in GTM left sidebar.
1a. Enable Built-in Variables
Click Configure (top right of Built-in Variables panel) and enable all of these:
| Variable | Used For |
|---|---|
| Page URL | Detecting content groups from URL path |
| Page Path | Cleaner URL matching (no domain) |
| Click URL | PDF download tracking, link clicks |
| Click Text | Button/CTA label capture |
| Click Classes | Targeting specific CSS classes |
| Click Element | DOM element inspection |
| Form ID | Identifying which form was submitted |
| Form Classes | Targeting forms by CSS class |
| Scroll Depth Threshold | Tracking how far down users scroll |
1b. Create a Custom JS Variable — Content Group Detector
This is the core variable. It reads the URL and returns which content group the page belongs to. Create it once, use it everywhere.
function() { var path = window.location.pathname.toLowerCase(); // Add/remove groups to match your URL structure if (path.indexOf('/brands/') !== -1) return 'Brands'; if (path.indexOf('/stories/') !== -1) return 'Stories'; if (path.indexOf('/products/') !== -1) return 'Products'; if (path.indexOf('/sustainability/') !== -1) return 'Sustainability'; if (path.indexOf('/reports/') !== -1) return 'Reports'; if (path.indexOf('/news/') !== -1) return 'News'; if (path === '/') return 'Homepage'; return 'Other'; }
1c. Create URL Contains Variable (reusable filter)
Optional but useful — a lookup variable you can use in triggers to match URL patterns without writing regex each time.
| Field | Value |
|---|---|
| Input Variable | {{Page Path}} |
| Pattern | /brands/ → Output: brands |
| Pattern | /stories/ → Output: stories |
| Default Value | other |
CG - for content group variables, TRG - for triggers, TAG - for tags. Example: TAG - GA4 PDF Download, TRG - Brands Page View. Keeps everything scannable when your container has 50+ items.
2 Content Group Page View Triggers
These triggers fire on page views for specific URL sections. You'll attach them to tags that send a content_group parameter to GA4 on every page load within that section.
Create a Trigger per Content Group
| Field | Operator | Value |
|---|---|---|
| Page Path | contains | /brands/ |
TRG - Page View Brands → SaveRepeat for each content group, just change the path in step 3. You'll end up with triggers like:
| Trigger Name | Condition |
|---|---|
| TRG - Page View Brands | Page Path contains /brands/ |
| TRG - Page View Stories | Page Path contains /stories/ |
| TRG - Page View Products | Page Path contains /products/ |
| TRG - Page View Sustainability | Page Path contains /sustainability/ |
| TRG - Page View Reports | Page Path contains /reports/ |
3 PDF Download Tracking
Track when a visitor clicks a link to download a PDF file. GTM's built-in click tracking listens for any link click and you filter by the .pdf extension in the URL.
Step 1 — Create the Trigger
| Setting | Value | Why |
|---|---|---|
| Wait for Tags | ✓ Check this | Gives GTM time to fire before the browser navigates away |
| Check Validation | ✓ Check this | Only fires on actual link clicks, not JS-triggered |
| Fires On | Some Link Clicks | — |
| Condition Variable | {{Click URL}} | — |
| Operator | contains | — |
| Value | Catches .pdf, .PDF, embedded PDFs |
{{Page Path}} contains /reports/. This fires the event only when a PDF is downloaded while on a Reports section page — useful for attributing the download to its content group.
Step 2 — Create the GA4 Event Tag
| Field | Value | Notes |
|---|---|---|
| Configuration Tag | Your GA4 Config Tag | Select your existing GA4 base tag |
| Event Name | file_download | GA4 recommended event name — pre-built reports support it |
| Event Parameters | ||
| file_name | {{Click URL}} |
Full URL of the downloaded file |
| file_extension | pdf |
Static value |
| link_text | {{Click Text}} |
The anchor text of the link |
| content_group | {{CG - Content Group}} |
Which section the download came from |
| page_path | {{Page Path}} |
Exact page the download was triggered from |
| Triggering | ||
| Trigger | TRG - PDF Download Click | The trigger you just created |
4 Form Submission Tracking
Track contact forms, inquiry forms, newsletter signups, and any other form submissions. GTM can listen for the native form submit event.
Step 1 — Create the Form Submit Trigger
| Setting | Value | Why |
|---|---|---|
| Wait for Tags | ✓ Check this | Ensures the tag fires before form navigates away |
| Check Validation | ✓ Check this | Only fires on valid form submissions that pass browser validation |
| Fires On | Some Forms | — |
| Condition | {{Form ID}} equals contact-form | Target a specific form by its HTML id attribute |
<form> tag and its id attribute. If there is no ID, you can use Form Classes instead, or ask a developer to add an ID to the form.
Step 2 — Create the GA4 Event Tag
| Field | Value |
|---|---|
| Event Name | generate_lead |
| Event Parameters | |
| form_id | {{Form ID}} |
| form_name | Contact Form (static label) |
| content_group | {{CG - Content Group}} |
| page_path | {{Page Path}} |
| Triggering | |
| Trigger | TRG - Form Submit Contact |
Option B — Thank You Page Trigger (most reliable)
If the form redirects to a /thank-you/ page after submission, this is the most bulletproof method — no JS dependency.
| Condition | Operator | Value |
|---|---|---|
| {{Page Path}} | contains | /thank-you/ |
5 CTA / Button Click Tracking
Track clicks on specific buttons, "Download", "Request Demo", "Contact Us" CTAs, and similar actions within your content group pages.
Step 1 — Create a Click Trigger
| Setting | Value |
|---|---|
| Fires On | Some Clicks |
| Option A — Target by CSS class | |
| {{Click Classes}} | contains cta-download |
| Option B — Target by button text | |
| {{Click Text}} | contains Download |
| Option C — Target by data attribute | |
| {{Click Element}} | matches CSS selector [data-track="download-cta"] |
{{Page Path}} contains /brands/. This way the "Download" click event only fires when on a Brands section page, not anywhere on the site.
Step 2 — GA4 Event Tag for CTA Click
| Field | Value |
|---|---|
| Event Name | cta_click |
| Event Parameters | |
| cta_text | {{Click Text}} |
| cta_url | {{Click URL}} |
| content_group | {{CG - Content Group}} |
| page_path | {{Page Path}} |
6 Scroll Depth Tracking
Useful for measuring engagement within long-form pages like Brand profiles, Stories/articles, and Sustainability reports. GTM has a built-in scroll trigger.
| Setting | Value |
|---|---|
| Scroll Depth Type | Vertical Scroll Depths |
| Percentages | 25, 50, 75, 90 |
| Fires On | Some Pages |
| Condition | {{Page Path}} contains /stories/ |
| Field | Value |
|---|---|
| Event Name | scroll_depth |
| scroll_threshold | {{Scroll Depth Threshold}} |
| content_group | {{CG - Content Group}} |
| page_path | {{Page Path}} |
7 Sending Events to GA4 — The Tag Template
Every event tag follows the same anatomy. Here's the canonical template to reference when building any new one.
// ① Always required Configuration Tag: TAG - GA4 Config // your base GA4 tag // ② Event name — choose the right one: file_download // PDF / file downloads (GA4 built-in) generate_lead // form submissions, contact requests cta_click // button / CTA click (custom) scroll_depth // scroll milestones (custom) video_start // video plays (GA4 built-in) // ③ Parameters to always include on every event: content_group: {{CG - Content Group}} // Brands, Stories, etc. page_path: {{Page Path}} // exact page page_title: {{Page Title}} // page <title>
GA4 Configuration Tag — Add content_group globally
To send content_group on every page view (not just specific events), add it to your GA4 Config tag too:
| Tab | Field | Value |
|---|---|---|
| Configuration | Measurement ID | G-XXXXXXXXXX |
| Fields to Set | content_group | {{CG - Content Group}} |
| content_group2 | {{Page Path}} (optional second level) |
8 Marking Events as Conversions in GA4
Once GTM is publishing events to GA4, you need to mark specific events as conversion goals inside GA4.
file_download or generate_lead in the list → toggle the Mark as conversion switch to ONRecommended Conversions to Set
| Event Name | What it Tracks | Priority |
|---|---|---|
| generate_lead | Form submissions | High |
| file_download | PDF / document downloads | High |
| cta_click | Button / CTA engagement | Medium |
| scroll_depth | Content engagement (50%+ read) | Low / Micro |
9 Reports & Audience Segmentation
Now you can break down all metrics by content group in GA4.
Explorations — Content Group Performance
Create Audiences per Content Group
Go to Admin → Audiences → New Audience → Create custom audience.
| Audience Name | Condition |
|---|---|
| Visited Brands Section | content_group exactly matches Brands |
| Downloaded Annual Report | event = file_download AND content_group = Reports |
| High-Engagement Stories Readers | event = scroll_depth AND scroll_threshold ≥ 75 AND content_group = Stories |
| Submitted Contact Form from Brands | event = generate_lead AND content_group = Brands |
✓ Pre-publish Checklist
Run through this before hitting Submit in GTM every time you set up a new tracking configuration.
In GTM Preview Mode
- Open Preview → enter your site URL → Navigate to a /brands/ page and confirm the
TRG - Page View Brandstrigger fired - Check the Variables tab in the preview panel and confirm
{{CG - Content Group}}returnsBrands - Click a PDF link — confirm
TRG - PDF Download Clickfired andfile_downloadevent tag fired - Submit a test form — confirm form submission trigger fired
- In the event details panel, confirm all parameters are populated: content_group, page_path, etc.
- Check no duplicate tags fired (same event fired twice)
In GA4 DebugView
- Admin → DebugView — confirm events appear in real-time stream
- Click each event to expand — verify all custom parameters are present with correct values
- Confirm content_group shows the correct group name, not "Other"
- Check for any malformed values (undefined, null, empty string)
Before Going Live
- Set GTM container version notes before Submit (document what you added)
- Confirm GA4 has received test events in Events report (takes up to 24h in standard reports, real-time in DebugView)
- If marking conversions: wait 24h after first event fires before toggling in GA4
! Troubleshooting
You didn't hit Submit in GTM. Preview mode uses a preview cookie — it doesn't affect real users. Always Submit after testing.
Your URL structure doesn't match what's in the Custom JS variable. In GTM Preview → check the Variables panel → inspect what {{Page Path}} actually returns on that page. Update the indexOf() checks in the variable to match exactly.
Add a second condition to the trigger: {{Page Path}} contains /reports/. Multiple conditions are AND'd together in GTM.
The form likely uses AJAX. In GTM Preview, open the form page → submit it → check if any Form Submission event appears in the events panel. If not, it's a JavaScript-powered form. Ask developers to add dataLayer.push({event: 'form_submit', form_id: '...'}) on success, then use a Custom Event trigger in GTM instead.
Standard GA4 reports have up to 48h processing delay. Use DebugView (Admin → DebugView) for real-time verification. Also confirm your Measurement ID in the GA4 Config tag is correct.
GA4 requires custom parameters to be registered as Custom Dimensions before they appear in Explore and standard reports. Go to Admin → Custom Definitions → Custom Dimensions → Create. Map: Dimension Name = "Content Group", Event parameter = content_group, Scope = Event.