Expressionengine Troubleshooting: Common Issues and Fixes | OpsBlu Docs

Expressionengine Troubleshooting: Common Issues and Fixes

Debug analytics issues on ExpressionEngine — template tag parsing, template caching, add-on conflicts, and multi-site manager (MSM) tracking problems.

ExpressionEngine (EE) is a PHP CMS with its own template tag language. Analytics problems on EE almost always involve the template parser interfering with JavaScript code, aggressive template caching, or add-on conflicts. The template system uses { and } delimiters that directly conflict with JavaScript syntax.

ExpressionEngine-Specific Debugging Approach

EE's template engine parses all content for template tags before outputting HTML. This is the number one source of analytics failures on this platform.

Check for Template Tag Parsing Issues

# SSH into your EE server

# Check if analytics code appears in the rendered output
curl -s http://your-ee-site.com/ | grep -iE "gtag|gtm|analytics" | head -5

# Check EE developer log for parse errors
tail -100 system/user/log/developer_log.log | grep -i "tag\|parse\|error"

Verify Template Group and Template

# Find which template serves the homepage
# In EE admin: Developer > Templates > check the "index" template in your site's template group
# Or check the rendered HTML for the EE comment marker:
curl -s http://your-ee-site.com/ | grep "ExpressionEngine"

Most Common ExpressionEngine Analytics Issues

1. EE Template Parser Eating JavaScript Curly Braces

Symptoms: Analytics code partially renders or is completely missing. Console shows Unexpected token errors. EE's developer log shows unrecognized tag warnings.

Root cause: EE's template parser interprets {anything} as a potential template tag. Your analytics JavaScript with functions, objects, and arrow functions all contain curly braces.

Fix: Use EE's {embed} or encode strategy:

{!-- In your EE template, use the encode attribute on the script tag --}
{!-- Option 1: External script only (no curly brace conflicts) --}
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>

{!-- Option 2: Wrap inline JS with encode="yes" in a snippet --}
{!-- Create a snippet called "analytics_code" in Developer > Snippets --}
{!-- Then include it: --}
{snippet:analytics_code}

For the snippet content, use EE's {encode} or place the JavaScript in an external .js file:

// /assets/js/analytics-init.js (external file, no EE parsing)
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
{!-- In your template --}
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script src="/assets/js/analytics-init.js"></script>

2. Template Caching Serving Stale Tracking Code

Symptoms: Updated analytics tag not appearing on the live site despite being correct in the template editor.

Root cause: EE aggressively caches templates. Tag caching, template caching, and the PHP output cache can all serve old versions.

Fix:

# Clear all EE caches
# Via admin: Developer > Utilities > Cache Manager > Clear All

# Or via CLI
cd system && php eecli.php cache:clear

3. Add-on Injecting Duplicate Analytics

Symptoms: Double pageview counts. Two copies of GA or GTM loading.

Root cause: EE add-ons like "Google Analytics" or "SEO Lite" may inject their own analytics code alongside your manually-placed snippet.

Diagnosis:

// Count analytics script loads
const gaScripts = document.querySelectorAll('script[src*="gtag"], script[src*="analytics"], script[src*="gtm"]');
console.log('Analytics scripts found:', gaScripts.length);
gaScripts.forEach((s, i) => console.log(`  #${i+1}:`, s.src));

Fix: Check Developer > Add-ons for any analytics-related add-ons. Disable them if you are manually managing tracking code.

4. Multi-Site Manager (MSM) Sites Missing Tracking

Symptoms: Analytics works on the primary site but not on MSM sub-sites.

Root cause: MSM sites can use separate template groups. If analytics was only added to the primary site's templates, sub-sites are untracked.

Fix: Add analytics to a shared snippet that all MSM sites include:

{!-- Create a shared snippet accessible to all MSM sites --}
{!-- In Developer > Snippets, create "global_analytics" --}
{!-- Then include in every site's main template: --}
{snippet:global_analytics}

5. URL Routing Variables in Analytics Data

Symptoms: Page paths in GA contain EE template group/template structure (e.g., /site/index instead of /).

Root cause: EE's URL structure includes template group names by default. Without proper .htaccess rules, the raw EE URLs leak into analytics.

Fix: Ensure your .htaccess removes index.php and verify canonical URLs:

// Override page path to use the clean URL
gtag('config', 'G-XXXXXXX', {
  page_path: window.location.pathname,
  page_title: document.title
});

Environment Considerations

  • EE 6/7 vs legacy: EE 7 requires PHP 8.0+. Older EE versions on PHP 5.x may have different template parsing behavior
  • File-based templates: EE supports saving templates as files (instead of database). If using file-based templates, changes require a template sync in the admin
  • Add-on ecosystem: EE's add-on store is smaller than WordPress's. Custom add-ons are common and may have undocumented side effects on page output
  • Licensing: EE is commercial software. Some hosting plans bundle specific EE versions that may not support the latest template features

Performance Issues

  • LCP Issues - Template parsing overhead and database query-heavy template tags
  • CLS Issues - Layout shifts from channel entry dynamic content and add-on widgets

Tracking Issues