Diagnose and fix tracking issues specific to Grav's flat-file architecture, Twig templating system, and caching mechanisms.
Quick Diagnostics
1. Check Browser Console
// Open browser console (F12)
// Check if GA4 loaded
console.log(typeof gtag); // Should be 'function'
console.log(window.dataLayer); // Should be array
// Check if GTM loaded
console.log(typeof google_tag_manager); // Should be 'object'
// Check if Meta Pixel loaded
console.log(typeof fbq); // Should be 'function'
2. Check Page Source
# View source and search for tracking codes
# Right-click → View Page Source → Ctrl+F
# Search for:
- "gtag" (for GA4)
- "GTM-" (for GTM)
- "fbq" (for Meta Pixel)
3. Check Grav Cache
# Clear Grav cache
bin/grav clear-cache
# Or via Admin Panel
Admin → Configuration → Clear Cache
Grav-Specific Issues
1. Cache Preventing Code Updates
Symptom: Tracking code doesn't appear even after adding to templates.
Cause: Grav's caching system serving old HTML.
Solution:
# Clear all Grav caches
bin/grav clear-cache
# Clear specific caches
bin/grav clear-cache --all
bin/grav clear-cache --assets-only
bin/grav clear-cache --images-only
bin/grav clear-cache --cache-only
# Temporarily disable cache during development
# user/config/system.yaml
cache:
enabled: false # Re-enable for production
twig:
cache: false
auto_reload: true
2. Twig Syntax Errors
Symptom: Tracking code not rendering in HTML.
Cause: Twig template errors preventing code output.
Diagnosis:
# Enable Twig debugging
# user/config/system.yaml
debugger:
enabled: true
provider: debugbar
censored: false
twig:
debug: true
Common Issues:
{# Bad - Unescaped quotes #}
gtag('config', 'G-XXXXXXXXXX', {
'page_title': '{{ page.title }}' {# This can break if title has quotes #}
});
{# Good - Properly escaped #}
gtag('config', 'G-XXXXXXXXXX', {
'page_title': '{{ page.title|e("js") }}'
});
{# Bad - Wrong variable reference #}
{% if grav.config.plugins.analytics.enabled %}
{# Good - Correct path #}
{% if grav.config.plugins['google-analytics'].enabled %}
3. Plugin Conflicts
Symptom: Tracking works on some pages but not others.
Cause: Plugin interference or disabled on certain pages.
Solution:
# List all enabled plugins
bin/gpm list
# Disable suspected plugin
bin/gpm uninstall plugin-name
# Or via config
# user/config/plugins/problematic-plugin.yaml
enabled: false
Check if tracking plugin disabled in frontmatter:
# pages/example.md
---
title: Example Page
google_analytics: false # This might disable tracking
---
4. Admin Panel Exclusion
Symptom: Tracking works on frontend but not in admin.
Cause: Most tracking should be excluded from admin (this is normal).
Verify:
// In your plugin or template
if ($this->isAdmin()) {
return; // Don't load tracking in admin
}
{# Exclude admin routes #}
{% if not grav.uri.path starts with '/admin' %}
{# Tracking code here #}
{% endif %}
5. Asset Pipeline Issues
Symptom: JavaScript tracking code not loading.
Cause: Grav's asset pipeline breaking inline scripts.
Solution:
# user/config/system.yaml
assets:
js_pipeline: false # Temporarily disable to test
js_minify: false
Or exclude tracking scripts from pipeline:
{{ assets.addInlineJs('
gtag("config", "G-XXXXXXXXXX");
', {'group': 'bottom', 'pipeline': false})|raw }}
GA4-Specific Issues
GA4 Not Loading
Check Installation:
{# Verify GA4 code in templates/partials/head.html.twig #}
{% set ga_id = grav.config.site.google_analytics_id %}
{% if ga_id %}
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id={{ ga_id }}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{{ ga_id }}');
</script>
{% endif %}
Check Configuration:
# user/config/site.yaml
google_analytics_id: 'G-XXXXXXXXXX' # Verify ID is correct
Events Not Tracking
Test Event Manually:
// In browser console
gtag('event', 'test_event', {
'event_category': 'Test',
'event_label': 'Manual Test'
});
// Then check GA4 Realtime reports
Enable Debug Mode:
<script>
gtag('config', '{{ ga_id }}', {
'debug_mode': true
});
</script>
GTM-Specific Issues
GTM Not Loading
Check Container ID:
{# Verify GTM ID format: GTM-XXXXXXX #}
{% set gtm_id = grav.config.site.gtm_id %}
{% if gtm_id %}
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){...})(window,document,'script','dataLayer','{{ gtm_id }}');</script>
{% endif %}
Check Both Parts Installed:
<!-- Head section - Script -->
<script>(function(w,d,s,l,i){...})</script>
<!-- Body section - Noscript -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"...></iframe></noscript>
Data Layer Not Populating
Check Initialization Order:
<!-- WRONG ORDER - GTM loads before data -->
<script>(function(w,d,s,l,i){...})</script> <!-- GTM -->
<script>
window.dataLayer.push({...}); <!-- Data layer -->
</script>
<!-- CORRECT ORDER - Data before GTM -->
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({...}); <!-- Data layer first -->
</script>
<script>(function(w,d,s,l,i){...})</script> <!-- Then GTM -->
Debug Data Layer:
// View data layer
console.table(window.dataLayer);
// Monitor pushes
var originalPush = window.dataLayer.push;
window.dataLayer.push = function() {
console.log('DataLayer push:', arguments[0]);
return originalPush.apply(window.dataLayer, arguments);
};
GTM Preview Mode Not Connecting
Disable Cache:
# user/config/system.yaml
cache:
enabled: false
Check Environment:
{# Only load GTM in production #}
{% if grav.config.system.environment == 'production' %}
{# GTM code #}
{% endif %}
{# Change to test #}
{% if grav.config.system.environment != 'development' %}
{# GTM code #}
{% endif %}
Meta Pixel-Specific Issues
Pixel Not Loading
Check Installation:
{# Verify pixel code in template #}
{% set pixel_id = grav.config.site.meta_pixel_id %}
{% if pixel_id %}
<!-- Meta Pixel Code -->
<script>
!function(f,b,e,v,n,t,s){...}(window, document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '{{ pixel_id }}');
fbq('track', 'PageView');
</script>
{% endif %}
Check Configuration:
# user/config/site.yaml
meta_pixel_id: '1234567890123456' # Verify 16-digit ID
Events Not Firing
Test Event Manually:
// In browser console
fbq('track', 'ViewContent', {
content_name: 'Test Event'
});
// Check Meta Events Manager → Test Events
Enable Debug Mode:
Install Meta Pixel Helper Chrome extension.
Browser & Extension Issues
Ad Blockers
Test:
- Open site in incognito/private mode
- Disable ad blocker extensions
- Check if tracking works
Solutions:
- Cannot bypass ad blockers (by design)
- Consider server-side tracking for critical data
- Educate users on privacy settings
Content Security Policy
Symptom: Console shows CSP errors.
Fix:
# user/config/system.yaml
security:
content_security_policy:
enabled: true
directives:
script-src:
- 'self'
- 'unsafe-inline'
- 'https://www.googletagmanager.com'
- 'https://www.google-analytics.com'
- 'https://connect.facebook.net'
Environment-Specific Issues
Development vs Production
Problem: Tracking disabled in development.
Check Environment:
# Check current environment
bin/grav config system.environment
# Output: development, staging, or production
Conditional Loading:
{# Load tracking only in production #}
{% if grav.config.system.environment == 'production' %}
{# Tracking codes #}
{% endif %}
{# Or load everywhere except development #}
{% if grav.config.system.environment != 'development' %}
{# Tracking codes #}
{% endif %}
Testing Checklist
Clear Cache
bin/grav clear-cacheCheck Browser Console
- No JavaScript errors
- Tracking functions defined
- Data layer exists
Check Page Source
- Tracking code present
- IDs correct
- Scripts loading
Test in Incognito
- Eliminates extension conflicts
- Fresh cache
Use Tracking Tools
- GA4 DebugView
- GTM Preview Mode
- Meta Pixel Helper
Check Grav Config
# Verify in user/config/site.yaml google_analytics_id: 'G-XXXXXXXXXX' gtm_id: 'GTM-XXXXXXX' meta_pixel_id: '1234567890123456'Check Template Paths
{# Verify tracking code in correct template #} # user/themes/your-theme/templates/partials/base.html.twig # or # user/themes/your-theme/templates/partials/head.html.twig
Still Not Working?
Enable Full Debugging
# user/config/system.yaml
debugger:
enabled: true
provider: debugbar
censored: false
twig: true
twig:
debug: true
auto_reload: true
errors:
display: 1
log: true
Check Grav Logs
# View error logs
tail -f logs/grav.log
# Check for template errors
grep "twig" logs/grav.log
Get Help
Grav Community
Check Documentation
Next Steps
For general tracking troubleshooting, see Events Not Firing Guide.