⚙️ ConfigurationIntermédiaire PS 1.7 PS 8.x

Configurer le suivi des conversions Google Tag Manager dans PrestaShop

Guide complet pour intégrer Google Tag Manager dans PrestaShop : installation GTM, balises Smarty {literal}, suivi e-commerce et erreurs courantes à éviter.

En bref : Pour intégrer Google Tag Manager dans PrestaShop, le snippet JavaScript nécessite des balises {literal} dans les templates Smarty tandis que le snippet noscript n'en a pas besoin. Privilégiez un module avec les hooks displayHeader et displayAfterBodyOpeningTag pour une intégration maintenable qui survit aux mises à jour du thème.

Publié le 21 mars 2026 6 min de lecture Alexandre Carette

Pourquoi le suivi des conversions est indispensable

Sans suivi des conversions, piloter une boutique PrestaShop revient à naviguer sans instruments. Google Tag Manager (GTM) est devenu l'outil de référence pour centraliser tous vos scripts de tracking — Google Ads, Meta Pixel, GA4 — sans toucher au code à chaque modification.

Pourtant, l'intégration de GTM dans PrestaShop pose des problèmes spécifiques liés au moteur de templates Smarty. Cet article couvre les erreurs les plus fréquentes et la méthode propre pour une intégration fiable.

Méthode d'intégration de Google Tag Manager

Étape 1 : le snippet JavaScript (head)

Le premier extrait GTM doit être placé le plus haut possible dans la balise de votre thème. Dans PrestaShop, le fichier cible est généralement :

  • **PrestaShop 1.7 / 8.x** : `themes/votre-theme/templates/_partials/head.tpl`

<!-- Google Tag Manager -->
<script>{literal}(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-XXXXXXX');{/literal}</script>
<!-- End Google Tag Manager -->

Étape 2 : le snippet noscript (body)

Le second extrait doit être inséré juste après l'ouverture de la balise . Le fichier cible :

  • **PrestaShop 1.7 / 8.x** : `themes/votre-theme/templates/layouts/layout-both-columns.tpl` (ou le layout principal de votre thème)

<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->

Attention : ce snippet noscript ne contient aucune variable JavaScript ni accolade. Il ne nécessite donc pas de balises {literal}. L'ajouter inutilement ne cassera rien, mais c'est une surcharge syntaxique inutile.

Le piège des balises `{literal}` dans Smarty

Smarty utilise les accolades { } comme délimiteurs de variables et de fonctions. Or, le code JavaScript en est truffé. Sans précaution, Smarty tente d'interpréter function(){} comme une variable Smarty et génère une erreur de compilation du template.

Quand utiliser `{literal}` ?

La règle est simple :

ContenuAccolades JS ?`{literal}` nécessaire ? Snippet JS GTM (head)Oui (`function(){}`, objets)**Oui** Snippet noscript GTM (body)Non**Non** Code GA4 `gtag()` inlineOui**Oui** Pixel Meta/FacebookOui (`fbq()` avec objets)**Oui** Simple balise HTML sans JSNon**Non**

Erreur fréquente : oublier `{literal}` sur le JavaScript

Si vous collez le snippet JavaScript GTM directement dans un fichier .tpl sans {literal}, Smarty renverra une erreur du type :


Fatal error: Uncaught SmartyCompilerException: Syntax Error in template

La solution est d'encadrer tout le bloc JavaScript :


<script>
{literal}
// Votre code JavaScript ici
(function(w,d,s,l,i){w[l]=w[l]||[];
// ...
});
{/literal}
</script>

Erreur inverse : mettre `{literal}` sur du HTML pur

Si vous encadrez le snippet noscript (qui ne contient que du HTML) avec {literal}, ce n'est pas bloquant mais c'est inutile. En revanche, si ce même bloc devait un jour contenir des variables Smarty (par exemple {$shop_name}), les balises {literal} empêcheraient leur interprétation. Gardez une bonne hygiène : n'utilisez {literal} que là où c'est nécessaire.

Erreur courante : double imbrication de `

Une erreur classique lors du copier-coller est de créer une double imbrication de la balise


<!-- ❌ INCORRECT : double noscript -->
<noscript><iframe src="<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
</iframe></noscript>

Ce HTML malformé empêche GTM de fonctionner pour les utilisateurs ayant JavaScript désactivé, et peut provoquer des erreurs de validation W3C. Le navigateur tentera de corriger le DOM, mais le résultat sera imprévisible.

La version correcte est simple et propre :


<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->

Approche recommandée sur PrestaShop 8.x : le module dédié

Sur PrestaShop 8.x, plutôt que de modifier manuellement les templates, la méthode la plus maintenable consiste à utiliser un module qui injecte GTM via les hooks natifs :

  • **Hook `displayHeader`** pour le snippet JavaScript
  • **Hook `displayAfterBodyOpeningTag`** (disponible depuis PS 1.7.6) pour le snippet noscript

Cette approche présente plusieurs avantages :

  1. **Survit aux mises à jour du thème** — pas de fichier `.tpl` modifié à re-appliquer
  2. **Configuration back-office** — l'ID GTM se gère depuis l'admin
  3. **Compatibilité multi-thème** — fonctionne quel que soit le thème actif
  4. Exemple minimal de module

    
    // modules/mygtm/mygtm.php
    class MyGtm extends Module
    {
        public function __construct()
        {
            $this->name = 'mygtm';
            $this->version = '1.0.0';
            $this->author = 'Alexandre Carette';
            parent::__construct();
            $this->displayName = $this->l('Google Tag Manager');
        }
    
        public function install()
        {
            return parent::install()
                && $this->registerHook('displayHeader')
                && $this->registerHook('displayAfterBodyOpeningTag');
        }
    
        public function hookDisplayHeader($params)
        {
            $gtmId = Configuration::get('MYGTM_ID');
            if (!$gtmId) return '';
    
            return "<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','{$gtmId}');</script>";
        }
    
        public function hookDisplayAfterBodyOpeningTag($params)
        {
            $gtmId = Configuration::get('MYGTM_ID');
            if (!$gtmId) return '';
    
            return '<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=' . htmlspecialchars($gtmId, ENT_QUOTES) . '" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>';
        }
    }
    

    Configurer le suivi e-commerce dans GTM

    Une fois GTM en place, l'étape suivante est de pousser les données de conversion dans le dataLayer. Voici les événements clés à configurer :

    Événement d'achat (page de confirmation)

    Dans le template order-confirmation.tpl (ou via un module sur le hook displayOrderConfirmation) :

    
    <script>
    {literal}
    window.dataLayer = window.dataLayer || [];
    dataLayer.push({
      'event': 'purchase',
      'ecommerce': {
        'transaction_id': '{/literal}{$order.details.reference}{literal}',
        'value': {/literal}{$order.totals.total.amount}{literal},
        'currency': '{/literal}{$currency.iso_code}{literal}',
        'items': [
    {/literal}
    {foreach from=$order.products item=product name=products}
          {literal}{{/literal}
            'item_id': '{$product.reference}',
            'item_name': '{$product.name|escape:'javascript'}',
            'price': {$product.price},
            'quantity': {$product.quantity}
          {literal}}{/literal}{if !$smarty.foreach.products.last},{/if}
    {/foreach}
        {literal}]
      }
    });
    {/literal}
    </script>
    

    Notez l'alternance entre {literal} et {/literal} : on sort du mode literal chaque fois qu'on a besoin d'une variable Smarty, puis on y revient pour les accolades JavaScript.

    Vérification et débogage

    Après intégration, vérifiez systématiquement :

    1. **Google Tag Assistant** (extension Chrome) : doit afficher votre conteneur GTM comme actif
    2. **Mode Aperçu GTM** : depuis l'interface GTM, activez le mode debug pour voir les événements en temps réel
    3. **Console développeur** : tapez `dataLayer` pour inspecter les données poussées
    4. **Google Analytics 4 > Temps réel** : vérifiez que les conversions remontent
    5. **Validateur W3C** : assurez-vous que le HTML généré est valide (pas de double `
    6. Checklist récapitulative

      • [ ] Snippet JS GTM dans le `` avec `{literal}` dans les fichiers `.tpl`
      • [ ] Snippet noscript GTM après `` **sans** `{literal}`
      • [ ] Pas de double imbrication `
      • [ ] DataLayer configuré pour l'événement `purchase`
      • [ ] Tests via Tag Assistant et mode Aperçu GTM
      • [ ] Validation W3C du HTML de sortie
#google-tag-manager #conversion-tracking #smarty #analytics #gtm #e-commerce-tracking

Questions fréquentes

Tout ce que vous devez savoir sur ce sujet.

Un projet PrestaShop ?

Discutons-en directement.

★★★★★

193 projets livrés

Gratuit & sans engagement — réponse sous 24h

Alexandre Carette

Alexandre Carette

Expert PrestaShop & Architecture E-commerce

Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.