GoogleTagManagerBundle
OroGoogleTagManagerBundle adds integration with Google Tag Manager (GTM), which enables users to add tracking tags to their OroCommerce web store pages with the help of Enhanced E-commerce and collect information on customer behavior, purchases, product clicks, page views, etc. All this information can subsequently be shared with Google Analytics to measure various user interactions with products on their website through E-Commerce reports. This can help you get a full picture of on-page visitor behavior, how well your marketing strategies work, and how to target your audience better.
To learn how to create a new integration with Google Tag Manager in your Oro application, please see a step-by-step user guide on configuring GTM.
Add Server-Side Events
Create Custom Collector
The easiest way to add a GTM message to a web page is to create a custom collector class.
Your collector class must implement \Oro\Bundle\GoogleTagManagerBundle\DataLayer\Collector\CollectorInterface
and be tagged by oro_google_tag_manager.data_layer.collector
.
For example:
namespace Acme\Bundle\DemoBundle\DataLayer\Collector;
use Doctrine\Common\Collections\Collection;
use Oro\Bundle\GoogleTagManagerBundle\DataLayer\Collector\CollectorInterface;
class CustomCollector implements CollectorInterface
{
/**
* @inheritDoc
*/
public function handle(Collection $data): void
{
$data->add([
'event' => 'someEventName',
'my-custom-key' => 'My custom data',
]);
}
}
services:
acme_demo.data_layer.collector.user_detail:
class: Acme\Bundle\DemoBundle\DataLayer\Collector\CustomCollector
tags:
- { name: oro_google_tag_manager.data_layer.collector }
Add Event to DataLayerManager Manually
In cases when you need to add data to the GTM data layer manually, use service oro_google_tag_manager.data_layer.manager directly. The example below illustrates adding an event when the entity changes:
namespace Acme\Bundle\DemoBundle\EventListener;
use Acme\Bundle\DemoBundle\Entity\Some;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Oro\Bundle\GoogleTagManagerBundle\DataLayer\DataLayerManager;
use Oro\Bundle\GoogleTagManagerBundle\Provider\GoogleTagManagerSettingsProviderInterface;
class ExampleEventListener
{
private DataLayerManager $dataLayerManager;
private GoogleTagManagerSettingsProviderInterface $settingsProvider;
private array $data = [];
/**
* @param DataLayerManager $dataLayerManager
* @param GoogleTagManagerSettingsProviderInterface $settingsProvider
*/
public function __construct(
DataLayerManager $dataLayerManager,
GoogleTagManagerSettingsProviderInterface $settingsProvider
) {
$this->dataLayerManager = $dataLayerManager;
$this->settingsProvider = $settingsProvider;
}
/**
* @param Some $entity
* @param PreUpdateEventArgs $args
* @return void
*/
public function preUpdate(Some $entity, PreUpdateEventArgs $args): void
{
// Check enabled GTM integration
if (!$this->isApplicable()) {
return;
}
// For example, we will add message when changing a specific field
if ($args->hasChangedField('someFieldName')) {
$this->data[] = [
'oldValue' => $args->getOldValue('someFieldName'),
'newValue' => $args->getNewValue('someFieldName'),
];
}
}
/**
* @return void
*/
public function postFlush(): void
{
// Add all collected messages to DataLayerManager
foreach ($this->data as $data) {
$this->dataLayerManager->add([
'event' => 'acmeSomeEntityUpdate',
'entityUpdate' => $data,
]);
}
// Clear listener
$this->onClear();
}
/**
* @return void
*/
public function onClear(): void
{
$this->data = [];
}
/**
* @return bool
*/
private function isApplicable(): bool
{
// Check enable GTM integration
if (!$this->settingsProvider->getGoogleTagManagerSettings()) {
return false;
}
// If necessary, check any other global conditions to apply this listener
return true;
}
}
Register this listener as a service:
services:
oro_google_tag_manager.event_listener.checkout:
acme_demo.event_listener.example:
class: Acme\Bundle\DemoBundle\EventListener\ExampleEventListener
public: false
arguments:
- '@oro_google_tag_manager.data_layer.manager'
- '@oro_google_tag_manager.provider.google_tag_manager_settings'
tags:
- { name: doctrine.orm.entity_listener, entity: 'Acme\Bundle\DemoBundle\Entity\Some', event: preUpdate }
- { name: doctrine.event_listener, event: postFlush }
- { name: doctrine.event_listener, event: onClear }
Add Client-Side Events
Product Events
Service oro_google_tag_manager.provider.product_detail is responsible for transferring product data to Google Analytics. Below is an example of updating the product block for product lists via layout update functionality:
layout:
actions:
- '@setBlockTheme':
themes: '@OroGoogleTagManager/layouts/default/imports/oro_product_list_item/oro_product_list_item.html.twig'
- '@add':
id: __google_tag_manager_product_model_expose
parentId: __product
blockType: block
options:
# This block must be rendered only when GTM integration is active
visible: '=data["oro_google_tag_manager_settings"].isReady()'
{% block __oro_product_list_item__google_tag_manager_product_model_expose_widget %}
{% if product is defined %}
{# In this block, we have a Product entity from which we need to get data #}
{% set productDetail = oro_google_tag_manager_product_detail(product) %}
{% set attr = layout_attr_defaults(attr, {'~class': ' hidden', 'data-gtm-model': productDetail}) %}
<div {{ block('block_attributes') }}></div>
{% endif %}
{% endblock %}
See more in products-embedded-list-gtm-component.js and product-details-gtm-helper.js.
Push GTM Message In JavaScript
To push some data to the GTM data layer from the javascript code, trigger event gtm:event:push.
For example:
var mediator = require('oroui/js/mediator');
mediator.trigger('gtm:event:push', {
event: 'eventName',
anyEventKeys: 'Any event data'
});