Bloomreach Experience Manager (brXM, formerly Hippo CMS) is a Java-based enterprise CMS with a component-oriented architecture (HST framework), a channel manager for multi-site delivery, and built-in personalization. Analytics problems on brXM typically stem from HST component lifecycle issues, the SPA SDK's client-side routing, or the personalization engine serving variant pages that fragment tracking.
Bloomreach-Specific Debugging Approach
brXM's HST (Hippo Site Toolkit) serves pages through a component tree. Each component can independently inject scripts into the <head> or <body>, making it easy for duplicate tags to appear or for tags to be missing from specific component configurations.
Verify Tag Placement in HST Component Tree
# In the Bloomreach CMS console (JCR), check where your analytics component lives
# Navigate to: /hst:hst/hst:configurations/[your-site]/hst:pages/
# Via the CMS REST API (if enabled):
curl -u admin:admin "http://localhost:8080/cms/ws/simple/hst:hst/hst:configurations/yoursite/hst:pages" \
-H "Accept: application/json" | python3 -m json.tool | grep -i "analytics\|gtm\|tracking"
Check SPA Delivery API Responses
If you use the brXM SPA SDK (React/Angular/Vue), analytics must hook into the SDK's page model updates, not traditional page loads:
// In browser console on a brXM SPA site
// Check if the Page Model API is active
console.log('brXM SPA SDK:', window.__bloomreach_spa ? 'Active' : 'Not found');
console.log('Page model:', window.__INITIAL_PROPS__?.page ? 'Present' : 'Missing');
// Check for SPA navigation events
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
if (entry.entryType === 'navigation' || entry.entryType === 'resource') {
if (entry.name.includes('/resourceapi') || entry.name.includes('/delivery/')) {
console.log('brXM API call:', entry.name, '| duration:', entry.duration + 'ms');
}
}
});
});
observer.observe({ entryTypes: ['resource'] });
Most Common Bloomreach Analytics Issues
1. HST Component Rendering Analytics Tag Twice
Symptoms: Duplicate pageviews or events. Two identical gtm.js or gtag script loads in the Network tab.
Root cause: The analytics snippet was added to both a base page layout component and a sub-component, or exists in both the HST template and a channel-level head contribution.
Fix: Centralize the tag in a single HST head contribution component:
<!-- In your HST page layout's head-contribution component -->
<!-- hst:headContribution category="analytics" -->
<hst:headContribution keyHint="gtm-script" category="scripts">
<script async="async" src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXXX"></script>
</hst:headContribution>
The keyHint attribute prevents duplicates even if multiple components try to inject the same script.
2. SPA Route Changes Not Tracked
Symptoms: Only the initial page load fires a pageview. Navigating through the SPA produces no additional analytics hits.
Root cause: brXM's SPA SDK handles navigation via the Delivery API without full page reloads.
Fix: Hook into the Bloomreach SPA SDK's page update cycle:
// For brXM React SDK
import { BrPageContext } from '@bloomreach/react-sdk';
function AnalyticsTracker() {
const page = React.useContext(BrPageContext);
React.useEffect(() => {
if (page) {
const url = page.getUrl() || window.location.pathname;
gtag('event', 'page_view', {
page_path: url,
page_title: page.getTitle() || document.title
});
}
}, [page]);
return null;
}
3. Personalization Variants Fragmenting Data
Symptoms: The same page shows different analytics data, or conversion attribution is inconsistent. Pageview paths may include variant identifiers.
Root cause: Bloomreach's relevance module serves personalized component variants. Each variant may have different tracking parameters or different dataLayer pushes.
Fix: Normalize the page path in your GTM configuration to strip variant identifiers, and push a custom dimension for the active variant:
// Add to your dataLayer before GTM loads
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'bloomreachVariant': document.querySelector('[data-brx-variant]')?.dataset.brxVariant || 'default',
'pagePath': window.location.pathname.replace(/\/__variant__.*$/, '')
});
4. Channel Manager Preview Mode Inflating Data
Symptoms: Pageviews spike during content editing sessions. Internal traffic bleeds into production analytics.
Fix: Detect Channel Manager preview mode and suppress analytics:
// Detect brXM Channel Manager / preview mode
const isPreview = window.location.search.includes('bloomreach-preview') ||
document.cookie.includes('hippo-preview') ||
window.parent !== window; // Channel Manager uses iframes
if (isPreview) {
console.log('brXM preview mode detected — analytics suppressed');
window['ga-disable-G-XXXXXXX'] = true;
}
5. Varnish/CDN Cache in Front of brXM
Symptoms: Updated tracking code only appears for some visitors or after long delays.
Root cause: Enterprise brXM deployments typically place Varnish or a CDN (Akamai, Cloudflare) in front. HST page output is cached at the HTTP level.
Fix: Use brXM's cache invalidation API after template changes:
# Trigger cache invalidation via brXM's page event system
curl -X POST "http://localhost:8080/cms/ws/pagemodelapi/invalidate" \
-H "Content-Type: application/json" \
-d '{"paths": ["/"]}'
Environment Considerations
- Multi-channel delivery: brXM can serve the same content via HST (server-rendered), SPA SDK, or headless API. Each channel needs its own analytics integration approach
- Java-based: Template changes require HST component recompilation or at minimum a CMS restart. Unlike PHP CMS platforms, you cannot just edit a file
- Relevance module: If using Bloomreach's personalization, test analytics with personalization both enabled and disabled
- Docker-based development: Local brXM instances via Docker may have different HST configurations than production — always test on staging
Performance Issues
- LCP Issues - HST component rendering latency and SPA hydration delays
- CLS Issues - Layout shifts from personalized component variant swaps
Tracking Issues
- Events Not Firing - Debug HST component duplication, SPA navigation gaps, and preview mode leakage
Related Resources
- Bloomreach Experience Manager documentation
- Global Issues Hub for platform-agnostic solutions