Magnolia CMS is a Java-based enterprise CMS with a dual-instance architecture (author and public instances) and FreeMarker templating. Analytics issues on Magnolia typically involve the author-to-public content activation pipeline, FreeMarker template rendering, or conflicts between Magnolia's traditional rendering and its headless REST API delivery.
Magnolia-Specific Debugging Approach
Magnolia separates authoring from delivery using paired instances. Content changes must be activated (published) from the author instance to the public instance before they appear on the live site.
Check Content Activation Status
# In Magnolia Admin Central (author instance):
# Go to Pages app > select your page > check the "Status" column
# Green = activated (published), Yellow = modified, Red = not activated
# Check the public instance directly
curl -s "http://public-instance:8080/" | grep -iE "gtag|gtm|analytics" | head -5
# Compare with author instance
curl -s -u admin:admin "http://author-instance:8080/" | grep -iE "gtag|gtm|analytics" | head -5
Verify FreeMarker Template Output
# Check Magnolia logs for FreeMarker errors
tail -100 /opt/magnolia/logs/magnolia-error.log | grep -i "freemarker\|template\|render"
# Enable FreeMarker debug logging temporarily
# In admincentral: Configuration > /server/filters/cms/templates > set DEBUG mode
Check via Magnolia REST API
# If using headless delivery, verify the REST endpoint
curl -s "http://public-instance:8080/.rest/delivery/pages/v1/" \
-H "Accept: application/json" | python3 -m json.tool | grep -i "analytics"
Most Common Magnolia Analytics Issues
1. Content Not Activated to Public Instance
Symptoms: Analytics code visible in the author instance preview but not on the public (production) site.
Root cause: Magnolia uses a publication workflow. Template changes or content updates with analytics code must be activated from the author instance to the public instance.
Fix: Activate the affected content:
- In Magnolia Admin Central, go to Pages app
- Select the page or template component containing analytics
- Click Publish (or Activate in older versions)
- Check the public instance to confirm the change propagated
For template file changes (as opposed to content changes), the public instance may need a module restart or redeployment.
2. FreeMarker Template Syntax Error Silently Dropping Scripts
Symptoms: Analytics tag present in the template file but not in the rendered output. No visible error on the page.
Root cause: FreeMarker syntax errors in the template can cause portions of the output to be silently swallowed. Magnolia's error handling may render the page without the broken section.
Diagnosis:
# Check for FreeMarker errors
grep -i "freemarker\|template" /opt/magnolia/logs/magnolia-error.log | tail -20
Fix: Validate your FreeMarker template syntax:
[#-- In your page template, e.g., templates/pages/main.ftl --]
<head>
[#-- Use FreeMarker's #escape or #noparse for JavaScript --]
[#noparse]
<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>
[/#noparse]
</head>
The [#noparse] directive prevents FreeMarker from interpreting JavaScript curly braces as FreeMarker expressions.
3. Area/Component Template Not Including Head Scripts
Symptoms: Analytics code is in a component but it does not appear in the page <head>.
Root cause: Magnolia's template architecture separates page templates from component templates. Components render in designated areas, which may be in the <body>, not the <head>.
Fix: Place analytics in the page template (not a component), or use Magnolia's <head> contribution mechanism:
[#-- In your page template's <head> section --]
<head>
[@cms.page /]
[#-- This renders head contributions from components --]
${model.headContributions!}
[#-- Direct analytics injection --]
[#noparse]
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
[/#noparse]
</head>
4. Magnolia Cache Module Serving Stale Pages
Symptoms: Analytics changes appear after activation but the public instance still serves old HTML for a period.
Root cause: Magnolia's cache module caches rendered pages on the public instance. Activation triggers cache invalidation, but aggressive cache configurations or CDN layers in front can delay updates.
Fix:
# Flush Magnolia cache
# In Admin Central: Tools > Cache > Flush All
# Or via REST API
curl -u admin:admin -X POST "http://public-instance:8080/.rest/cache/v1/flush"
5. Headless/SPA Delivery Not Tracking Navigation
Symptoms: Using Magnolia's REST API for a SPA frontend. Only the initial page load fires analytics.
Root cause: When Magnolia delivers content via REST API to a JavaScript SPA, client-side navigation does not trigger full page reloads.
Fix: Hook into your SPA framework's router:
// For a React SPA consuming Magnolia REST API
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function MagnoliaAnalytics() {
const location = useLocation();
useEffect(() => {
gtag('event', 'page_view', {
page_path: location.pathname,
page_title: document.title
});
}, [location]);
return null;
}
Environment Considerations
- Author vs. Public: Always test analytics on the public instance, not the author instance. They serve different content and have different caching
- Java/JCR-based: Magnolia stores content in a JCR repository. Template changes require knowledge of FreeMarker and the Magnolia templating API
- Light modules: Magnolia supports "light modules" (file-based, no Java compilation needed) for templates and configurations. These are easier to modify than Java-based modules
- Magnolia CLI: Use
mgnlCLI for developing light modules locally. It creates a direct file-based development workflow - Docker support: Magnolia provides Docker images for development. Production deployments are typically WAR-based on Tomcat
Performance Issues
- LCP Issues - JCR content rendering latency and FreeMarker template compilation overhead
- CLS Issues - Layout shifts from area/component lazy rendering and personalization variant swaps
Tracking Issues
- Events Not Firing - Debug content activation, FreeMarker rendering, and cache invalidation
Related Resources
- Magnolia CMS documentation
- Global Issues Hub for platform-agnostic solutions