---
title: FlexiLivre / Google Tag Manager
---
Hello!
The goal of this ticket is to switch to a tag management system, namely [Google Tag Manager](https://tagmanager.google.com) (GTM for short). At the same time, the consent popup (currently "tarteaucitron") is to be replaced by [Axeptio](https://www.axeptio.eu).
Consent was already a tricky thing, especially in France where Legitimate Interest isn't recognized, and now that Google has released its own "[Consent Mode](https://support.google.com/analytics/answer/9976101?hl=en)", it's turned into even more of a mess 🙄
We're lucky, FlexiLivre is a simple case because it only has two kinds of content (tag-ly speaking):
- the bulk of the website, where only Axeptio and Google Analytics have to be loaded ;
- the confirmation page, where Google Ads and Microsoft Advertising (ex-Bing) also have to be loaded (along with the Customer Survey, which we'll discuss later).
GTM will handle (almost) all of that and "just" has to be fed some data through its [Data Layer](https://developers.google.com/tag-manager/devguide) for the confirmation page.
# The Events
GTM is event-based, so every time an event happens it looks for contextual data, the Data Layer, the URL of the page, etc. and triggers tags. I'll skip over events we don't care about and explain what happens on the confirmation page (in this case initial consent has been given — or not — previously on another page of the website).
1. The consent event is fired, triggering two tags: first, the Google Consent Mode for `analytics_storage` and `ad_storage` is initialized to `denied`, which is its default state. There's also a slight 500ms delay before data will be sent, so that we have time to check for the stored consent. And we enable [`url_passthrough`](https://developers.google.com/gtagjs/devguide/consent#url_passthrough), just in case. Immediately after that, the Axeptio tag is triggered; it's really simple, the only specific thing is the style injection in order to remove their logo.
2. Axeptio fires an `axeptio_update` event, allowing us to update the Google Consent Mode.
3. The `PageView` event is fired. Here, Microsoft Advertising's tag is dependent upon Axeptio's consent status, like what's happening today with tarteaucitron. The difference is that we let Google handle its consent status for the GA and Ads tags because it "knows" what it can and cannot do.
# Demos
- [Standard page](https://flexilivre-gtm.glitch.me/)
- [Confirmation page](https://flexilivre-gtm.glitch.me/order/confirmation/)
# Technical Implementation
## On every page
First things first: we can remove the calls to `/js/lib/tarteaucitron/tarteaucitron.js` and `/js/analytics.min.js`, along with the following script tag (everything that uses the `tarteaucitron` Object, really).
We now have to load GTM, as close to the opening `<head>` tag as possible:
```javascript
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { window.dataLayer.push(arguments); }
(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','GTM-N89TL7');
</script>
```
And that's it!
## On the confirmation page
Here we can delete every third party tag integration that was not already handled by tarteaucitron, **with the exception of the Customer Survey**. If you look at the demo you'll see it's harcoded in the source. That's because [GTM currently doesn't support it](https://support.google.com/merchants/answer/9352538?hl=en) so we have to keep this tag there 😔
Now we have to fill the Data Layer with the order info, so that conversion tracking tags get all the data they need (you can remove comments in production):
```javascript
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { window.dataLayer.push(arguments); }
// as per GA docs, we're resetting the property
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
ecommerce: {
currencyCode: "EUR",
purchase: {
actionField: {
id: "111111", // order ID
affiliation: "flexilivre.com",
revenue: "0.01", // total order price
shipping: "0.00", // order shipping price
tax: "0.00", // order taxes
},
// you can have as many products as you need (but at least one)
products: [{
id: "123", // product ID
name: "Livre photo", // product name
sku: "11111", // product SKU
category: "XX", // product category
price: "0.01", // product price
quantity: "1", // product quantity
}, ...],
},
},
});
(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','GTM-N89TL7');
</script>
```
> Note that for simplicity sake the Confirmation PageView detection relies on the `/order/confirmation/` referrer path match. We could also fill the Data Layer with contextual info (environment, pagename, etc.) and use this as a variable to know which page we're on.