ProcessWire is a PHP CMS/CMF with a powerful API and direct PHP template files. Unlike CMS platforms that use a template engine (Twig, Smarty, FreeMarker), ProcessWire templates are pure PHP files. This gives you full control but also means analytics issues trace directly to PHP code, the ProCache module, or ProcessWire's hook system.
ProcessWire-Specific Debugging Approach
ProcessWire templates are plain PHP files in /site/templates/. Since there is no template engine abstraction, you can debug by reading the PHP files directly and checking the output.
Check Template File Output
# SSH into your ProcessWire server
# Find the active template for the homepage
grep -r "home" site/templates/ --include="*.php" -l
# Check if analytics code is in the main layout
grep -rn "gtag\|gtm\|analytics" site/templates/ --include="*.php"
# Verify the rendered output
curl -s http://your-pw-site.com/ | grep -iE "gtag|gtm|analytics" | head -5
Check ProcessWire Module Status
# Via ProcessWire admin: Modules > Site > check installed modules
# Or check the database directly:
# SELECT * FROM modules WHERE class LIKE '%analytics%' OR class LIKE '%track%';
# Check module files
ls site/modules/ | grep -i "analytics\|track\|google\|gtm"
Most Common ProcessWire Analytics Issues
1. ProCache Serving Pages Without Tracking Code
Symptoms: Analytics code visible in admin preview but missing on the live site. Tracking appears after ProCache is disabled.
Root cause: ProCache (ProcessWire's full-page cache module) serves static HTML files directly via .htaccess, completely bypassing PHP. If analytics code was added after ProCache cached the pages, the cached files contain the old HTML.
Fix:
# Clear ProCache cache
# Via ProcessWire admin: Modules > ProCache > Clear All Cache
# Or delete cached files directly
rm -rf site/assets/ProCache/*
# Or via ProcessWire API (in a template or module):
# $procache->clearAll();
Prevention: After any template change that affects analytics, always clear ProCache.
2. Template File Not Using _main.php or _init.php
Symptoms: Analytics works on most pages but specific templates (e.g., search results, 404, sitemap) do not include tracking.
Root cause: ProcessWire supports a _main.php prepend/append system for shared layout. If some templates do not use the shared layout (by setting $config->appendTemplateFile = ''), they miss the analytics code.
Diagnosis:
<?php
// Check your site/config.php for the prepend/append system
// Look for these lines:
$config->prependTemplateFile = '_init.php';
$config->appendTemplateFile = '_main.php';
// If missing, templates render independently
?>
Fix: Ensure all templates use the shared layout, or add analytics to each individual template:
<?php
// In site/templates/_main.php (shared layout)
?>
<head>
<title><?= $page->title ?></title>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>
</head>
3. ProcessWire Hook Modifying Page Output
Symptoms: Analytics code is in the template but the rendered HTML has it removed or modified.
Root cause: ProcessWire's hook system allows modules to modify page output via Page::render hooks. A module may be stripping or modifying scripts.
Diagnosis:
<?php
// In site/ready.php or a template, temporarily log all hooks on Page::render
wire()->addHookAfter('Page::render', function($event) {
$hooks = $event->object->getHooks('render');
file_put_contents('/tmp/pw-hooks.log', print_r($hooks, true));
});
?>
Fix: Check installed modules for output-modifying hooks. Common culprits include HTML minification modules, security modules that strip inline scripts, and SEO modules.
4. Multi-Language URLs Splitting Analytics Data
Symptoms: Analytics shows separate page entries for /en/about/, /de/about/, /fr/about/ instead of grouping them. Traffic appears fragmented.
Root cause: ProcessWire's multi-language support creates separate URL paths per language. Each path appears as a distinct page in GA.
Fix:
// Normalize URLs by stripping the language prefix
var langPrefixes = ['en', 'de', 'fr', 'es'];
var path = window.location.pathname;
langPrefixes.forEach(function(lang) {
path = path.replace(new RegExp('^/' + lang + '/'), '/');
});
gtag('config', 'G-XXXXXXX', {
page_path: path,
custom_map: { dimension1: 'content_language' }
});
gtag('event', 'page_view', {
content_language: document.documentElement.lang
});
5. AJAX-Loaded Content Not Tracked
Symptoms: Pages that use ProcessWire's AJAX page loading (via the $config->ajax flag) do not fire pageview events for AJAX-loaded content.
Root cause: ProcessWire supports AJAX content loading where only the body content is fetched. The <head> section (containing analytics) is not re-executed.
Fix: Trigger a virtual pageview after AJAX content loads:
// After ProcessWire AJAX content loads
document.addEventListener('pw-content-loaded', function(e) {
gtag('event', 'page_view', {
page_path: e.detail?.url || window.location.pathname,
page_title: document.title
});
});
Environment Considerations
- Pure PHP templates: No template engine abstraction. You have full PHP access in templates, which means more power but also more potential for PHP errors breaking analytics
- File-based configuration:
site/config.phpcontrols global settings. Template prepend/append settings affect which templates share layout code - ProCache vs. Template Cache: ProCache serves static files bypassing PHP entirely. ProcessWire also has a template-level cache (
$page->render()caching) that is separate from ProCache - Shared hosting friendly: ProcessWire runs well on shared hosting. Check PHP error logs (
error_login.htaccessorphp.ini) for template rendering issues - ProcessWire API: The
$pages,$page, and$configAPI objects are available in all templates. Use them for conditional analytics (e.g., skip tracking for admin users)
Performance Issues
- LCP Issues - PHP template rendering and ProCache miss latency
- CLS Issues - Layout shifts from AJAX content loading and dynamic module output
Tracking Issues
- Events Not Firing - Debug ProCache serving stale pages, template layout gaps, and hook-based output modification
Related Resources
- ProcessWire documentation
- Global Issues Hub for platform-agnostic solutions