Ezplatform Analytics Integrations: Setup Guide | OpsBlu Docs

Ezplatform Analytics Integrations: Setup Guide

Integrate GA4, GTM, and Meta Pixel with Ibexa DXP (formerly eZ Platform) using Twig templates, Symfony bundles, and the SiteAccess system.

Ibexa DXP (formerly eZ Platform, originally eZ Publish) is a Symfony-based enterprise content management platform. It uses Twig templating, Symfony service containers, and a powerful content model with Content Types and SiteAccess configurations for multi-site management. Analytics integration follows Symfony conventions with Ibexa-specific content awareness.

Integration Architecture

Ibexa DXP provides four integration paths:

  1. Twig Templates -- Edit your site's pagelayout.html.twig (the base layout template) to add tracking scripts. Located in your site bundle at templates/themes/yourtheme/pagelayout.html.twig.
  2. Symfony Bundles -- Install analytics bundles via Composer. Ibexa runs on Symfony, so any Symfony-compatible bundle works.
  3. SiteAccess Configuration -- Ibexa's SiteAccess system allows different configurations per site/language. Set different GTM container IDs per SiteAccess in config/packages/ibexa.yaml.
  4. Content Type Mapping -- Ibexa's Content Type system provides structured data that maps directly to analytics dimensions (content type identifier, section, location depth).

Available Integrations

Analytics Platforms

Google Analytics 4

  • Twig layout template injection
  • GTM-based GA4 with content-type data layer (recommended)
  • Ibexa Personalization integration for segment-aware tracking

Tag Management

Google Tag Manager

  • Base Twig layout injection
  • SiteAccess-specific container IDs
  • Symfony bundle for admin-configurable GTM

Marketing Pixels

Meta Pixel

  • Via GTM container (recommended)
  • Twig template head injection

Twig Layout Integration with Data Layer

Edit your base layout template to add GTM and a content-aware data layer:

{# templates/themes/yourtheme/pagelayout.html.twig #}
<!DOCTYPE html>
<html lang="{{ app.request.locale }}">
<head>
    <!-- Google Tag Manager -->
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;
    j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
    f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer',
    '{{ ibexa_config_resolver_parameter("gtm_container_id", "app") }}');</script>

    {% if content is defined %}
    <script>
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
        'contentTypeIdentifier': '{{ content.contentInfo.contentType.identifier }}',
        'contentId': '{{ content.id }}',
        'contentName': '{{ ez_content_name(content)|e("js") }}',
        'locationId': '{{ location.id }}',
        'sectionName': '{{ content.contentInfo.section.name|default("")|e("js") }}',
        'locationDepth': '{{ location.depth }}',
        'language': '{{ content.contentInfo.mainLanguageCode }}',
        'siteAccess': '{{ ezpublish.siteaccess.name }}'
    });
    </script>
    {% endif %}

    {% block head %}{% endblock %}
</head>
<body>
    <noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ ibexa_config_resolver_parameter('gtm_container_id', 'app') }}"
    height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    {% block body %}{% endblock %}
</body>
</html>

SiteAccess-Specific Configuration

Configure different GTM containers per SiteAccess in your Ibexa configuration:

# config/packages/ibexa.yaml
ibexa:
    system:
        site_en:
            params:
                gtm_container_id: 'GTM-EN001'
        site_de:
            params:
                gtm_container_id: 'GTM-DE001'
        site_fr:
            params:
                gtm_container_id: 'GTM-FR001'

Access these in Twig with {{ ibexa_config_resolver_parameter('gtm_container_id', 'app') }}. The resolver automatically picks the correct value based on the active SiteAccess.

Platform Limitations

HTTP cache (Varnish/Fastly). Ibexa DXP uses HTTP cache (Varnish or Fastly) aggressively. Pages served from cache have identical HTML, including data layer values. User-specific data layer variables (logged-in state, user segment) must be populated client-side via JavaScript, not server-side in Twig.

Content Type changes. Modifying Content Type identifiers in the Ibexa admin breaks data layer mappings. Use the Content Type identifier (machine name) rather than the display name in your data layer to minimize the impact of admin changes.

Ibexa Personalization overlap. Ibexa's built-in Personalization engine tracks user behavior independently. Running both Ibexa Personalization and GA4 creates parallel data streams. Coordinate event definitions to avoid duplicate tracking.

Symfony profiler in dev. The Symfony web profiler toolbar injects JavaScript in dev mode that can interfere with tracking. Test analytics in production or staging environments.

Bundle compatibility. Not all Symfony bundles are compatible with Ibexa's version constraints. Verify Symfony version requirements before installing analytics bundles.

Performance Considerations

  • Twig compilation. Template expressions compile to PHP on first render. Data layer Twig code has no measurable runtime cost after compilation. Clear the Symfony cache (bin/console cache:clear) after template changes.
  • Content repository queries. Accessing content.contentInfo.section.name triggers a repository API call. For high-traffic pages, ensure Ibexa's Persistence Cache (Redis/Memcached) is configured to avoid redundant database queries.
  • Multi-site overhead. Each SiteAccess can have a different GTM container. If using many SiteAccesses with unique containers, each container loads independently -- this is by design but increases the number of distinct GTM containers to manage.
  1. Add GTM to pagelayout.html.twig -- Use SiteAccess-aware config for container IDs
  2. Build content-type-aware data layer -- Map Ibexa Content Types, sections, and location depth to analytics dimensions
  3. Configure GA4 via GTM -- Use content type identifiers for GA4 content groups
  4. Add Meta Pixel via GTM -- Standard engagement tracking with consent mode for GDPR

Next Steps

For general integration concepts, see the integrations overview.