There are three main methods to install GA4 on your MODX website, each with different capabilities and ease of management.
Method Comparison
| Method | Difficulty | Customization | Maintenance | Recommended For |
|---|---|---|---|---|
| Template Code | Easy | High | Manual | Direct control, custom implementations |
| Plugin/Extra | Medium | Medium | Auto-updates | Standard setup, easier management |
| Google Tag Manager | Medium | Highest | Via GTM | Most sites (recommended) |
Method 1: Template-Based Implementation (Most Control)
Add GA4 directly to your MODX templates for complete control over implementation.
Setup Steps
Access Template Manager
- Log into MODX Manager
- Go to Elements → Templates
- Click on your base template (usually the main template used across your site)
Add GA4 gtag.js to Template Head
Find the
</head>tag in your template and add above it:<!-- Google Analytics 4 --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXXX', { 'send_page_view': true, 'page_title': '[[*pagetitle]]', 'page_path': '[[*uri]]', 'content_group': '[[*template:ne=`0`:then=`[[+template_name]]`:else=`Default`]]' }); </script>Replace
G-XXXXXXXXXXwith your GA4 Measurement ID.Add MODX-Specific Parameters
Enhance tracking with MODX resource data:
<script> gtag('config', 'G-XXXXXXXXXX', { 'send_page_view': true, 'page_title': '[[*pagetitle]]', 'page_path': '[[*uri]]', 'user_id': '[[!+modx.user.id:notempty=`[[!+modx.user.id]]`]]', 'custom_map': { 'dimension1': 'resource_id', 'dimension2': 'template_name', 'dimension3': 'parent_id' }, 'resource_id': '[[*id]]', 'template_name': '[[*template:gt=`0`:then=`[[*template]]`:else=`Default`]]', 'parent_id': '[[*parent]]' }); </script>Create Reusable Chunk (Optional)
For easier management across multiple templates:
a. Go to Elements → Chunks → Create New Chunk
b. Name it:
ga4_trackingc. Add the GA4 code from step 2 or 3
d. In your templates, use:
<head> [[$ga4_tracking]] </head>Save and Clear Cache
- Click Save
- Clear MODX cache: Manage → Clear Cache
- Visit your site and verify in GA4 Realtime report
Template Implementation Benefits
Advantages:
- Complete control over code placement
- Easy to customize per template
- No plugin dependencies
- Can use any MODX tags and snippets
- Direct access to resource properties
Disadvantages:
- Must update each template individually
- No automatic updates
- Requires template editing for changes
Multiple Templates Implementation
If your site uses multiple templates:
Option A: Add to Each Template
- Copy GA4 code to all templates
- Customize per template if needed
Option B: Use Base Template Include
<!-- In child template -->
[[*parent_template_code]]
[[$ga4_tracking]]
Option C: Use @INHERIT Binding
<!-- Set TV with GA4 code -->
[[*ga4_code@INHERIT]]
Method 2: Plugin-Based Implementation
Use MODX Extras to install analytics plugins that manage GA4 automatically.
Using Analytics Extras
Install via Package Manager
- Go to Extras → Installer
- Click Download Extras
- Search for "Google Analytics" or "Analytics"
- Select and install appropriate package
Popular Analytics Extras
Analytics (by MODX Community)
- Simple GA4 integration
- System settings for configuration
- Auto-injects on all pages
GoogleAnalytics4
- Dedicated GA4 support
- Enhanced ecommerce ready
- Custom event tracking
Configure Plugin
- Go to System → System Settings
- Search for analytics settings
- Enter your GA4 Measurement ID
- Configure additional options
- Save settings
Verify Installation
- Clear cache
- Visit site
- Check GA4 Realtime report
Custom Plugin Implementation
Create a custom plugin to inject GA4 on all pages:
Create New Plugin
- Go to Elements → Plugins
- Click Create New Plugin
- Name:
GA4 Tracking
Plugin Code
<?php /** * GA4 Tracking Plugin * * Events: OnWebPagePrerender */ $measurementId = 'G-XXXXXXXXXX'; // Replace with your Measurement ID $ga4Code = <<<HTML <!-- Google Analytics 4 --> <script async src="https://www.googletagmanager.com/gtag/js?id={$measurementId}"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', '{$measurementId}', { 'send_page_view': true, 'page_title': '{$modx->resource->get('pagetitle')}', 'page_path': '{$modx->resource->get('uri')}', 'resource_id': '{$modx->resource->get('id')}' }); </script> HTML; // Inject before </head> $modx->resource->_output = str_replace('</head>', $ga4Code . '</head>', $modx->resource->_output);Set System Events
- In plugin editor, click System Events tab
- Check:
OnWebPagePrerender - Save plugin
Enable Plugin
- Ensure plugin is enabled
- Clear cache
- Test on your site
Plugin Benefits
Advantages:
- Centralized management
- Updates affect all pages automatically
- No template editing required
- Can use system settings for configuration
Disadvantages:
- Limited customization per template
- Plugin conflicts possible
- Slightly impacts page generation time
- Requires PHP knowledge for custom plugins
Method 3: Google Tag Manager (Recommended)
GTM provides the most flexibility and is recommended for most MODX sites.
Why Use GTM?
- Easier to manage: Update tracking without editing templates
- Better organization: All tags in one place
- Advanced features: Custom events, triggers, variables
- Better performance: Single container load for multiple tags
- Non-technical updates: Marketers can update without touching MODX
- Works with MODX: Access resource data via data layer
Setup Steps
Install GTM on MODX
See Install Google Tag Manager for full GTM installation guide.
Create GA4 Tag in GTM
Once GTM is installed:
a. In GTM, go to Tags → New
b. Click Tag Configuration → Google Analytics: GA4 Configuration
c. Enter your Measurement ID (G-XXXXXXXXXX)
d. Configuration Settings (optional):
- Add custom parameters for MODX resource data
- Configure user properties
- Set up custom dimensions
e. Triggering: Select All Pages
f. Save and name it "GA4 - Configuration"
Add MODX Data Layer Variables
In GTM, create variables to capture MODX data:
Resource ID:
- Type: Data Layer Variable
- Data Layer Variable Name:
modx.resourceId - Name:
DLV - Resource ID
Page Title:
- Type: Data Layer Variable
- Data Layer Variable Name:
modx.pageTitle - Name:
DLV - Page Title
Template:
- Type: Data Layer Variable
- Data Layer Variable Name:
modx.template - Name:
DLV - Template
Configure GA4 Fields
In GA4 Configuration tag, add Fields to Set:
page_title = {{DLV - Page Title}} resource_id = {{DLV - Resource ID}} template = {{DLV - Template}}Publish Container
- Click Submit in GTM
- Add version name and description
- Click Publish
Test
- Use GTM Preview mode to verify tags fire
- Check GA4 Realtime reports
- Verify MODX variables populate correctly
GTM + MODX Data Layer
See MODX Data Layer Structure for detailed implementation of data layer with MODX resource data.
Advanced Configuration
User ID Tracking (Logged-in Users)
Track logged-in MODX users:
<script>
gtag('config', 'G-XXXXXXXXXX', {
'user_id': '[[!+modx.user.id:notempty=`[[!+modx.user.id]]`]]'
});
</script>
Important: Hash user IDs before sending to comply with privacy policies.
Custom Dimensions
Set up custom dimensions for MODX-specific data:
In GA4:
- Admin → Custom Definitions → Custom Dimensions
- Create dimensions:
resource_id- Resource IDtemplate- Template nameparent_id- Parent resource IDcontext- MODX context
In tracking code:
gtag('config', 'G-XXXXXXXXXX', {
'custom_map': {
'dimension1': 'resource_id',
'dimension2': 'template',
'dimension3': 'parent_id',
'dimension4': 'context'
},
'resource_id': '[[*id]]',
'template': '[[*template]]',
'parent_id': '[[*parent]]',
'context': '[[++context_key]]'
});
Template Variables (TVs) Tracking
Track custom TV values:
<script>
gtag('event', 'page_view', {
'product_category': '[[*product_category]]',
'author': '[[*author]]',
'publish_date': '[[*publishedon:strtotime:date=`%Y-%m-%d`]]'
});
</script>
Multi-Context Tracking
If using multiple contexts (e.g., web, mobile, api):
<script>
gtag('config', 'G-XXXXXXXXXX', {
'site_context': '[[!++context_key]]',
'site_name': '[[++site_name]]'
});
</script>
Content Grouping
Group resources by template or parent:
gtag('config', 'G-XXXXXXXXXX', {
'content_group': '[[*parent:gt=`0`:then=`[[*parent:is=`1`:then=`Top Level`:else=`Sub Pages`]]`:else=`Homepage`]]'
});
Verification & Testing
1. Check GA4 Realtime Reports
- Open GA4 → Reports → Realtime
- Navigate your MODX site
- Verify events appear within 30 seconds
- Check that MODX resource data appears correctly
2. Use GA4 DebugView
Enable debug mode to see detailed event data:
gtag('config', 'G-XXXXXXXXXX', {
'debug_mode': true
});
In GA4:
- Go to Admin → DebugView
- View events in real-time with full parameters
- Verify MODX-specific parameters appear
3. Browser Console Testing
// Check if gtag is loaded
console.log(typeof gtag); // Should be "function"
// Check data layer
console.log(window.dataLayer);
// Check for errors
// Open Console (F12) and look for red errors
4. Test Different Resource Types
Test across different MODX resources:
- Homepage (resource ID 1)
- Content pages (different templates)
- Custom templates (special layouts)
- Search results (if applicable)
- Form pages (contact, registration)
Troubleshooting
Events Not Firing
See Events Not Firing Troubleshooting for detailed debugging steps.
Quick checks:
- Verify Measurement ID is correct (starts with
G-) - Check browser console for JavaScript errors
- Ensure ad blockers are disabled for testing
- Clear MODX cache after changes
- Verify template is properly saved
Cache Issues
Problem: Changes to tracking code not appearing.
Fix:
- Clear MODX cache: Manage → Clear Cache
- Clear browser cache (Ctrl+Shift+Delete)
- Use incognito/private browsing for testing
Template Variables Not Populating
Problem: TV values show as placeholders in GA4.
Fix:
// Check if TV exists and has value
[[*tv_name:notempty=`[[*tv_name]]`:default=`No Value`]]
Plugin Not Firing
Problem: Plugin-based GA4 not appearing.
Checklist:
- Plugin is enabled
- System event
OnWebPagePrerenderis checked - No plugin errors in MODX error log
- Cache is cleared
MODX Tags Not Parsing
Problem: MODX placeholders appear as literal text in GA4.
Cause: Using cached chunks or incorrect syntax.
Fix:
// Use uncached tags if needed
[[!*pagetitle]]
// Ensure proper MODX tag syntax
[[*id]] // Correct
{*id} // Wrong
Next Steps
- Configure GA4 Events - Track custom MODX events
- Install GTM - For easier tag management
- MODX Data Layer - Structure data for GTM
For general GA4 concepts, see Google Analytics 4 Guide.