💻 DéveloppementIntermédiaire PS 1.7 PS 8.x

Ajouter un loader lors de la soumission de commande PrestaShop

Comment ajouter un spinner de chargement au clic sur le bouton de commande PrestaShop pour éviter les doubles clics et améliorer l'UX du tunnel d'achat.

En bref : Pour ajouter un loader au tunnel de commande PrestaShop, injectez un script JavaScript (protégé par {literal} en Smarty) qui affiche un overlay au submit du formulaire de paiement et désactive le bouton pour éviter les doubles commandes. En PrestaShop 8.x, privilégiez un module avec le hook actionFrontControllerSetMedia.

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

Pourquoi ajouter un loader au tunnel de commande

Lorsqu'un client clique sur le bouton "Commander" à l'étape finale du checkout PrestaShop, il se passe parfois plusieurs secondes avant la redirection vers la page de confirmation ou la passerelle de paiement. Sans retour visuel, le client peut :

  • **Double-cliquer** et générer deux commandes identiques
  • **Quitter la page** en pensant que rien ne se passe
  • **Perdre confiance** dans la fiabilité de la boutique

Ajouter un spinner (loader) au moment de la soumission est une amélioration UX simple mais redoutablement efficace pour le taux de conversion.

Étape 1 : Identifier le bon fichier template

Dans PrestaShop 1.7 et 8.x, le tunnel de commande est géré par le template :


themes/votre-theme/templates/checkout/checkout.tpl

Le bouton de validation finale se trouve plus précisément dans :


themes/votre-theme/templates/checkout/_partials/steps/payment.tpl

C'est le formulaire contenant le bouton #payment-confirmation button qui déclenche la soumission.

Étape 2 : Créer le CSS du loader

Ajoutez ces styles dans votre fichier CSS personnalisé ou dans themes/votre-theme/assets/css/custom.css :


/* Overlay de chargement sur le bouton de commande */
.checkout-loader-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.checkout-loader-overlay .spinner {
  width: 50px;
  height: 50px;
  border: 4px solid rgba(255, 255, 255, 0.3);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

.checkout-loader-overlay p {
  color: #fff;
  margin-top: 15px;
  font-size: 16px;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

Étape 3 : Ajouter le JavaScript

Voici le point crucial. Dans PrestaShop 1.7/8.x, les templates Smarty nécessitent d'encadrer le JavaScript natif avec les balises {literal} pour éviter que Smarty n'interprète les accolades comme des variables de template.

Ajoutez ce script juste avant la balise dans votre template checkout.tpl ou via un module :


{literal}
<script>
  document.addEventListener('DOMContentLoaded', function() {
    var paymentForm = document.querySelector('#payment-confirmation form');
    if (!paymentForm) return;

    var submitted = false;

    paymentForm.addEventListener('submit', function(e) {
      // Empêcher le double-clic
      if (submitted) {
        e.preventDefault();
        return false;
      }
      submitted = true;

      // Créer l'overlay loader
      var overlay = document.createElement('div');
      overlay.className = 'checkout-loader-overlay';
      overlay.innerHTML = '<div style="text-align:center;"><div class="spinner"></div><p>Traitement de votre commande en cours...</p></div>';
      document.body.appendChild(overlay);

      // Désactiver le bouton visuellement
      var btn = paymentForm.querySelector('button[type="submit"], input[type="submit"]');
      if (btn) {
        btn.disabled = true;
        btn.style.opacity = '0.6';
      }
    });
  });
</script>
{/literal}

Approche alternative via un module (recommandée en 8.x)

En PrestaShop 8.x, la bonne pratique est d'injecter le JavaScript via un module plutôt que de modifier le template directement. Utilisez le hook actionFrontControllerSetMedia :


public function hookActionFrontControllerSetMedia($params)
{
    if ($this->context->controller instanceof OrderController) {
        $this->context->controller->registerJavascript(
            'module-checkout-loader',
            'modules/' . $this->name . '/views/js/checkout-loader.js',
            ['position' => 'bottom', 'priority' => 200]
        );
        $this->context->controller->registerStylesheet(
            'module-checkout-loader-css',
            'modules/' . $this->name . '/views/css/checkout-loader.css',
            ['media' => 'all', 'priority' => 200]
        );
    }
}

Dans ce cas, le fichier checkout-loader.js contient le même code sans les balises {literal} :


document.addEventListener('DOMContentLoaded', function() {
  var paymentForm = document.querySelector('#payment-confirmation form');
  if (!paymentForm) return;

  var submitted = false;

  paymentForm.addEventListener('submit', function(e) {
    if (submitted) {
      e.preventDefault();
      return false;
    }
    submitted = true;

    var overlay = document.createElement('div');
    overlay.className = 'checkout-loader-overlay';
    overlay.innerHTML = '<div style="text-align:center;"><div class="spinner"></div><p>Traitement de votre commande en cours...</p></div>';
    document.body.appendChild(overlay);

    var btn = paymentForm.querySelector('button[type="submit"], input[type="submit"]');
    if (btn) {
      btn.disabled = true;
      btn.style.opacity = '0.6';
    }
  });
});

Diagnostic : erreur 500 après modification

Si vous obtenez une erreur 500 après avoir ajouté votre JavaScript, voici la marche à suivre :

Activer le mode debug

Dans le fichier .env à la racine de PrestaShop 8.x :


APP_DEBUG=1
APP_ENV=dev

Pour PrestaShop 1.7, modifiez /config/defines.inc.php :


define('_PS_MODE_DEV_', true);

Consulter les logs serveur

Si le mode debug ne suffit pas, vérifiez les logs Apache ou Nginx :


# Apache
tail -f /var/log/apache2/error.log

# Nginx
tail -f /var/log/nginx/error.log

Les causes les plus fréquentes d'erreur 500 lors de l'ajout de JavaScript dans un template Smarty sont :

  1. **Accolades non protégées** : Smarty interprète `{` et `}` comme des délimiteurs. Encadrez systématiquement votre JS avec `{literal}...{/literal}`
  2. **Fichier corrompu à l'upload** : Comparez avec une installation vierge de la même version
  3. **Cache Smarty périmé** : Videz le dossier `var/cache/` et recompilez
  4. Comparer avec une installation vierge

    En cas de doute sur l'intégrité de vos fichiers, téléchargez la version correspondante de PrestaShop depuis le site officiel et comparez les fichiers du tunnel de commande :

    
    diff -r votre-theme/templates/checkout/ prestashop-vierge/themes/classic/templates/checkout/
    

    Cela permet d'identifier rapidement si un fichier a été modifié ou corrompu.

    Bonnes pratiques UX pour le loader

    • **Message rassurant** : affichez un texte comme "Traitement en cours, ne fermez pas cette page"
    • **Timeout de sécurité** : ajoutez un `setTimeout` de 30 secondes qui masque le loader et réactive le bouton si la page ne redirige pas
    • **Accessibilité** : ajoutez un attribut `aria-live="polite"` sur le message pour les lecteurs d'écran
    • **Mobile** : testez que le loader s'affiche correctement sur les petits écrans
    
    // Timeout de sécurité
    setTimeout(function() {
      var overlay = document.querySelector('.checkout-loader-overlay');
      if (overlay) {
        overlay.remove();
        submitted = false;
        if (btn) {
          btn.disabled = false;
          btn.style.opacity = '1';
        }
      }
    }, 30000);
    
#checkout #javascript #ux #tunnel-commande #loader #smarty

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.