À retenir
- Vous n’avez pas besoin d’une app pour une bannière compte à rebours. Un timer n’est qu’un simple fichier de section : un peu de Liquid, de CSS et un petit script inline. Les apps vous facturent un abonnement mensuel pour ça et ajoutent le poids de leur propre script sur chaque page.
- La barre d’annonces du thème Dawn n’a pas de compte à rebours. Elle supporte jusqu’à 12 annonces textuelles rotatives, des icônes sociales et des sélecteurs de langue, mais rien de basé sur le temps. Une section custom est donc la solution sans app.1
- Le piège de la timezone (timezone gotcha) est bien réel. Une date sans décalage UTC est parsée dans la timezone locale de chaque visiteur, donc votre promo “se termine” à un instant différent dans chaque pays. Fixez la deadline avec un offset explicite.
- Une bannière est une cause fréquente de CLS (layout shift). Réservez sa hauteur en CSS et donnez aux chiffres des boîtes à largeur fixe, sinon le timer décalera toute votre page vers le bas après le chargement.
Une bannière compte à rebours Shopify sans app (countdown banner) est un simple fichier de section que vous collez dans votre thème : un message, quatre chiffres qui défilent, et une deadline définie depuis l’éditeur de thème. Ce guide vous fournit la section complète, puis détaille les trois points sur lesquels la plupart des snippets copiés-collés se trompent : les timezones, le layout shift, et les lecteurs d’écran (screen readers).
Cet article est écrit pour le BFCM, car c’est la période où la plupart des boutiques cherchent à ajouter un timer, mais cette section fonctionnera pour n’importe quelle promo avec une vraie date de fin.
Pourquoi vous pouvez nous faire confiance
Nous évoluons dans l’écosystème Shopify depuis plus de quatre ans et avons travaillé avec des centaines de marques Shopify sur leurs boutiques. Jacques a plus de 15 ans d’expérience en développement. Nous créons Fudge, l’opérateur IA pour les boutiques Shopify, avec une note de 4.9 sur le Shopify App Store et le statut Built for Shopify. Écrire des sections de thème comme celle-ci est donc littéralement ce que notre produit fait toute la journée.
Pourquoi une bannière compte à rebours fonctionne si bien pour le BFCM
Une deadline répond à la seule question que chaque acheteur du BFCM se pose en silence : est-ce que je peux y réfléchir plus tard ? Quand la réponse honnête est non, un compte à rebours visible le dit mieux que n’importe quel adjectif. C’est l’aversion à la perte qui fait le travail de vente pour vous.
Le mot-clé est l’honnêteté. Faites le décompte jusqu’à une vraie date de fin, et arrêtez la promotion quand il atteint zéro. Les timers evergreen qui se réinitialisent discrètement à chaque actualisation habituent les visiteurs réguliers à ignorer l’urgence, et vous placent du mauvais côté de la loi sur les dark patterns dans de plus en plus de juridictions.
Une bannière est aussi l’endroit le moins cher pour créer un sentiment d’urgence. Elle se place au-dessus du header sur chaque page, ne nécessite aucune refonte, et disparaît à la seconde où la promotion se termine.
Un compte à rebours n’est utile que s’il y a une offre pour laquelle il vaut la peine de se dépêcher, alors définissez-la d’abord - idées de promotions Black Friday pour les boutiques Shopify couvre la mécanique et ce que chacune coûte en marge. La bannière va ensuite sur une homepage qui a été préparée pour l’accueillir : voir ce qu’il faut changer sur votre homepage Black Friday.
Si vous finalisez le reste de votre préparation pour le BFCM, penchez-vous aussi sur la partie mesure : notre guide complémentaire sur le tracking Meta server-side avec l’API Conversions vous aide à vous assurer que le trafic converti par votre bannière est correctement attribué.
Avez-vous vraiment besoin d’une app de compte à rebours ?
Non, et pour une bannière aussi petite, recourir à une app est un mauvais calcul sur toute la ligne.
Les apps coûtent de l’argent pour des choses qu’un thème peut faire nativement. Les apps de bannières compte à rebours vous facturent un abonnement pour ce qui revient à un simple fichier de section. C’est tout à fait justifié pour des fonctionnalités complexes ; un timer n’est pas une fonctionnalité complexe.
Les apps ralentissent vos pages, toute l’année. Les app embeds injectent leur propre JavaScript et CSS dans votre boutique, et la plupart restent chargés une fois la promo terminée, ou même après leur désinstallation si l’app a modifié votre thème. Pendant le BFCM, où chaque visiteur compte, le poids d’un script tiers est la dernière chose dont vous avez besoin pour votre plus grosse semaine de trafic de l’année.
Une section native, en revanche, ne pèse que quelques kilo-octets servis depuis le CDN de Shopify avec votre thème, se modifie dans le même éditeur de thème que le reste, et se supprime en un clic quand le mois de décembre arrive.
Que peut faire l’éditeur de thème sans aucun code ?
Il est bon de vérifier avant de coder, car la réponse a changé en 2025-2026.
Dawn et la plupart des thèmes gratuits : pas de compte à rebours. La section “barre d’annonces” de Dawn supporte jusqu’à 12 blocs d’annonces rotatifs avec des liens, un auto-rotate, des icônes sociales, une ligne de séparation et des sélecteurs de pays et de langue. Il n’y a aucun paramètre basé sur le temps dans son schéma (schema).1 Le mieux que vous puissiez faire est un message statique de type “La promo se termine lundi”.
Horizon et les blocs générés par IA : oui, en quelque sorte. L’éditeur de thème de Shopify peut désormais générer un bloc custom à partir d’un prompt textuel via Shopify Magic. Vous cliquez sur “Ajouter un bloc” (Add block), choisissez “Générer” (Generate), et décrivez le timer que vous voulez. Cela fonctionne sur les thèmes du Theme Store avec la plupart des forfaits, mais avec une mise en garde qu’il vaut mieux lire deux fois : le support Shopify ne vous aidera pas à customiser ou à débugger le code généré, et la qualité relève explicitement de votre responsabilité.2
Cette mise en garde explique pourquoi une section vérifiée à la main reste la meilleure option pour le BFCM. Vous obtenez un code que vous avez pu relire, avec les paramètres exacts dont vous avez besoin, sans mauvaises surprises le soir de Thanksgiving à 23h. Si vous n’avez jamais ajouté de section auparavant, survolez d’abord notre guide sur comment ajouter des sections sur la page d’accueil Shopify ; la mécanique est identique.
À vous de jouer : la section complète de la bannière compte à rebours
Dupliquez d’abord votre thème (Boutique en ligne → Thèmes → ⋯ → Dupliquer). Ensuite, ouvrez ⋯ → Modifier le code sur la copie, créez un nouveau fichier dans sections/ appelé countdown-banner.liquid et collez tout ce qui suit à l’intérieur.
<div
id="CountdownBanner-{{ section.id }}"
class="countdown-banner"
data-end="{{ section.settings.end_date | escape }}T{{ section.settings.end_time | escape }}:00{{ section.settings.utc_offset | escape }}"
data-expiry="{{ section.settings.expiry_behavior | escape }}"
style="background: {{ section.settings.bg_color }}; color: {{ section.settings.text_color }};"
>
<div class="countdown-banner__inner">
<p class="countdown-banner__message">
{%- if section.settings.link != blank -%}
<a href="{{ section.settings.link }}">{{ section.settings.message | escape }}</a>
{%- else -%}
{{ section.settings.message | escape }}
{%- endif -%}
</p>
<div class="countdown-banner__timer" role="timer" aria-live="off">
<span class="countdown-banner__sr-only">
L'offre se termine le {{ section.settings.end_date }} à {{ section.settings.end_time }}
</span>
<span class="countdown-banner__unit" aria-hidden="true">
<span class="countdown-banner__digits" data-unit="days">–</span>
<small>jours</small>
</span>
<span class="countdown-banner__unit" aria-hidden="true">
<span class="countdown-banner__digits" data-unit="hours">–</span>
<small>h</small>
</span>
<span class="countdown-banner__unit" aria-hidden="true">
<span class="countdown-banner__digits" data-unit="minutes">–</span>
<small>min</small>
</span>
<span class="countdown-banner__unit" aria-hidden="true">
<span class="countdown-banner__digits" data-unit="seconds">–</span>
<small>sec</small>
</span>
</div>
<p class="countdown-banner__expired" hidden>
{{ section.settings.expired_message | escape }}
</p>
</div>
</div>
{% style %}
#CountdownBanner-{{ section.id }} {
min-height: 3.25rem; /* réserve l'espace : pas de layout shift quand le JS se charge */
display: flex;
align-items: center;
}
#CountdownBanner-{{ section.id }} .countdown-banner__inner {
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.25rem;
align-items: center;
justify-content: center;
width: 100%;
padding: 0.5rem 1.5rem;
text-align: center;
}
#CountdownBanner-{{ section.id }} .countdown-banner__message {
margin: 0;
font-size: 0.9rem;
letter-spacing: 0.03em;
}
#CountdownBanner-{{ section.id }} .countdown-banner__message a {
color: inherit;
}
#CountdownBanner-{{ section.id }} .countdown-banner__timer {
display: flex;
gap: 0.75rem;
}
#CountdownBanner-{{ section.id }} .countdown-banner__unit {
display: inline-flex;
flex-direction: column;
line-height: 1.1;
}
#CountdownBanner-{{ section.id }} .countdown-banner__digits {
font-variant-numeric: tabular-nums; /* chaque chiffre a la même largeur : pas de tremblement */
min-width: 2ch;
font-weight: 700;
font-size: 1rem;
}
#CountdownBanner-{{ section.id }} .countdown-banner__unit small {
font-size: 0.6rem;
text-transform: uppercase;
letter-spacing: 0.08em;
opacity: 0.75;
}
#CountdownBanner-{{ section.id }} .countdown-banner__expired {
margin: 0;
width: 100%;
}
.countdown-banner__sr-only {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
}
@media (prefers-reduced-motion: no-preference) {
/* Mettez toute animation ajoutée ici, pour que les utilisateurs ayant activé la réduction des mouvements ne la voient pas */
}
{% endstyle %}
<script>
(function () {
function initCountdown() {
var banner = document.getElementById('CountdownBanner-{{ section.id }}');
if (!banner || banner.dataset.initialized) return;
banner.dataset.initialized = 'true';
var timer = banner.querySelector('.countdown-banner__timer');
var expired = banner.querySelector('.countdown-banner__expired');
var end = new Date(banner.dataset.end).getTime();
if (isNaN(end)) {
// Date incorrecte ou manquante : ne jamais afficher NaN, revenir au message statique
timer.hidden = true;
expired.hidden = false;
return;
}
var units = {};
banner.querySelectorAll('[data-unit]').forEach(function (el) {
units[el.dataset.unit] = el;
});
function pad(n) {
return n < 10 ? '0' + n : String(n);
}
var tick;
function render() {
if (!banner.isConnected) {
clearInterval(tick);
return;
}
var diff = end - Date.now();
if (diff <= 0) {
clearInterval(tick);
if (banner.dataset.expiry === 'hide') {
banner.hidden = true;
} else {
timer.hidden = true;
expired.hidden = false;
}
return;
}
var s = Math.floor(diff / 1000);
units.days.textContent = String(Math.floor(s / 86400));
units.hours.textContent = pad(Math.floor((s % 86400) / 3600));
units.minutes.textContent = pad(Math.floor((s % 3600) / 60));
units.seconds.textContent = pad(s % 60);
}
render();
tick = setInterval(render, 1000);
}
initCountdown();
// Éditeur de thème : réinitialiser quand la section est rechargée
document.addEventListener('shopify:section:load', function (event) {
if (event.detail && event.detail.sectionId === '{{ section.id }}') {
initCountdown();
}
});
})();
</script>
{% schema %}
{
"name": "Bannière compte à rebours",
"settings": [
{
"type": "text",
"id": "message",
"label": "Message",
"default": "Black Friday : jusqu'à -40 % sur tout le site"
},
{
"type": "url",
"id": "link",
"label": "Lien (facultatif)"
},
{
"type": "text",
"id": "end_date",
"label": "Date de fin (AAAA-MM-JJ)",
"default": "2026-11-30"
},
{
"type": "text",
"id": "end_time",
"label": "Heure de fin, 24h (HH:MM)",
"default": "23:59"
},
{
"type": "text",
"id": "utc_offset",
"label": "Décalage UTC de la boutique",
"default": "-05:00",
"info": "Fixe la date limite à un moment global unique. Utilisez le décalage du fuseau horaire de votre boutique, par ex. -05:00 pour New York en novembre, +01:00 pour Paris."
},
{
"type": "select",
"id": "expiry_behavior",
"label": "Quand le compte à rebours se termine",
"options": [
{ "value": "hide", "label": "Masquer la bannière" },
{ "value": "message", "label": "Afficher le message d'expiration" }
],
"default": "message"
},
{
"type": "text",
"id": "expired_message",
"label": "Message d'expiration",
"default": "La promotion est terminée. À l'année prochaine !"
},
{
"type": "color",
"id": "bg_color",
"label": "Arrière-plan",
"default": "#111111"
},
{
"type": "color",
"id": "text_color",
"label": "Texte",
"default": "#ffffff"
}
],
"presets": [{ "name": "Bannière compte à rebours" }]
}
{% endschema %}
Enregistrez, ouvrez l’éditeur de thème, et ajoutez Bannière compte à rebours au groupe de sections En-tête (Header) pour qu’elle s’affiche au-dessus de l’en-tête sur toutes les pages. Définissez la date, l’heure et le décalage, choisissez le comportement à l’expiration, et le tour est joué. Ce même placement dans le groupe de sections fonctionne pour une barre de livraison gratuite, qui se marie très bien avec un compte à rebours pendant le BFCM.
Le piège de la timezone (timezone gotcha)
C’est le bug de la plupart des compte à rebours copiés-collés. new Date('2026-11-30T23:59:00'), sans décalage, est analysé dans le fuseau horaire local du visiteur. Un acheteur à Sydney verrait votre promotion se terminer 19 heures avant un acheteur à Los Angeles, et il y a toujours quelqu’un pour faire une capture d’écran.
La section évite cela en ajoutant le paramètre utc_offset à la chaîne de date, de sorte que 2026-11-30T23:59:00-05:00 représente le même instant partout sur Terre. Deux choses à vérifier lors de la configuration :
- Utilisez le décalage que le fuseau horaire de votre boutique aura à la date de fin, et non aujourd’hui. New York est à -05:00 fin novembre (EST), et non à -04:00 comme en été.
- Si votre promotion chevauche un changement d’heure (DST), vérifiez le décalage pour cette semaine précise. Pour le BFCM 2026 (le Black Friday est le 27 novembre), les horloges américaines et européennes auront déjà changé, c’est donc le décalage d’hiver qui est le bon.
Éviter le layout shift (optimisation CLS)
Une bannière injectée tout en haut de l’écran est la cause la plus classique d’un mauvais score de Cumulative Layout Shift (CLS) : dès que la bannière s’affiche, tout le reste de la page saute d’un coup vers le bas. Cette section vous en protège de deux manières différentes :
La hauteur est réservée avant même que le JavaScript ne s’exécute. Le min-height: 3.25rem sur le container principal garantit que l’espace existe dès le premier affichage (first paint). Quand le JavaScript remplit les chiffres, la mise en page (layout) reste intacte. Si vous grossissez la taille des polices, n’oubliez pas de remesurer et de mettre à jour cette hauteur minimale réservée.
Les chiffres ne peuvent pas “trembler” ni sauter. La propriété CSS font-variant-numeric: tabular-nums donne la même largeur à chaque chiffre, et le min-width: 2ch sur la boîte de chaque chiffre empêche le timer de changer de taille lorsque “10” se transforme en “09”. Sans cela, sur certaines polices, la bannière ferait un re-flow du layout toutes les secondes.
Un compromis assumé : l’option cacher à l’expiration (hide on expiry) supprime la bannière et, de fait, remonte toute la page, mais cela n’arrive qu’une seule fois. Si votre promo se termine alors que vous avez un fort trafic, privilégiez plutôt l’option du message d’expiration, qui maintient la hauteur et évite ce saut. Le layout shift peut venir de nombreux autres éléments que des bannières ; pour régler les autres problèmes de ce type, vous pouvez consulter notre guide expliquant comment corriger le CLS sur Shopify.
Accessibilité : un timer qui reste silencieux
Un compte à rebours qui s’actualise chaque seconde est la pire chose possible à annoncer à un lecteur d’écran. Cette section est donc conçue pour l’annoncer une fois, puis rester silencieuse :
- Le minuteur a
role="timer"avecaria-live="off", de sorte que les mises à jour ne sont jamais annoncées automatiquement. C’est l’opposé explicite duaria-live="polite"que beaucoup de snippets intègrent, ce qui interromprait un utilisateur de lecteur d’écran à chaque seconde. - Les chiffres qui défilent sont en
aria-hidden="true". Ce que les technologies d’assistance lisent à la place est une phrase statique, visuellement masquée : « L’offre se termine le 2026-11-30 à 23:59. » - La section n’a aucune animation. Le CSS inclut une media query
prefers-reduced-motion: no-preferencevide ; si vous ajoutez un effet plus tard, mettez-le ici pour que les utilisateurs ayant demandé une réduction des animations n’en voient aucun.
Avant de publier
Testez le rendu de la bannière sur ordinateur et sur mobile (le retour à la ligne du texte et du timer ne se comporte pas de la même façon sur un petit écran). Configurez une date de fin passée pour vous assurer que l’état “expiré” (hide ou message) s’active correctement comme vous l’avez paramétré, puis remettez la vraie date de fin. Ouvrez la section dans l’éditeur de thème et changez une option au hasard pour vérifier que le timer redémarre bien une fois la section rechargée par l’éditeur.
Quand un page builder est-il plus approprié ?
Une simple bannière ne justifie pas d’installer quoi que ce soit. Mais le calcul change lorsque le compte à rebours fait partie de la construction d’une campagne plus large : une landing page BFCM avec des minuteurs, des offres par paliers, des éléments dynamiques à travers les modèles, et une équipe marketing qui veut itérer toutes les heures sans toucher au code. À ce stade, un page builder ou un outil de campagne dédié rentabilise son abonnement, au moins pour novembre.
La voie du milieu, c’est Fudge. Vous décrivez la bannière, ou toute la section de la campagne, en langage naturel, et Fudge l’écrit en Liquid, CSS et JavaScript natifs dans votre thème, avec tous ses paramètres, sous forme de brouillon que vous prévisualisez avant de publier. Vous obtenez un résultat sans application tierce et sans coder à la main ; la page éditeur de boutique Shopify montre comment cela fonctionne. Rien à désinstaller en décembre, car il n’y a jamais eu de surcouche d’application pour commencer. Les compte à rebours font partie des applications à usage unique que Fudge remplace par une petite section dans votre thème, au même titre que les barres de livraison gratuite, les guides des tailles et les barres d’annonce.
FAQ
Puis-je ajouter une bannière de compte à rebours sur Shopify sans application ?
Oui. Une bannière de compte à rebours est une simple section personnalisée : du code Liquid, un schéma avec un paramètre de date de fin, un peu de CSS et un petit script intégré. Vous la collez dans sections/ via l'éditeur de code, l'ajoutez via l'éditeur de thème, et configurez la date limite comme n'importe quel autre paramètre de section. Pas d'abonnement, pas de script tiers.
Le thème Dawn a-il un compte à rebours intégré ?
Non. La barre d'annonce de Dawn prend en charge jusqu'à 12 annonces textuelles rotatives avec des liens, une rotation automatique, des icônes de réseaux sociaux et des sélecteurs de pays et de langue, mais rien de basé sur le temps. Pour avoir un compte à rebours dans Dawn, vous devez ajouter une section personnalisée ou utiliser la génération de blocs par IA de l'éditeur de thème, dont le résultat n'est pas pris en charge par l'assistance Shopify.
Pourquoi mon compte à rebours affiche-t-il des heures différentes selon les pays ?
Parce que la chaîne de date n'a pas de décalage UTC. JavaScript analyse une date-heure simple comme 2026-11-30T23:59:00 dans le fuseau horaire local de chaque visiteur, ce qui fait que la date limite peut varier jusqu'à un jour à travers le monde. Ajoutez un décalage explicite tel que -05:00 pour fixer la fin de la promotion à un instant global unique.
Une bannière de compte à rebours va-t-elle nuire à mes Core Web Vitals ?
Seulement si elle est injectée sans espace réservé. Donnez à la bannière une min-height fixe en CSS pour que la page soit correctement mise en page dès le premier affichage (first paint), et utilisez tabular-nums avec une min-width sur les chiffres pour que le minuteur ne se recadre pas chaque seconde. Construite de cette façon, la bannière est conçue pour minimiser le layout shift.
Que doit-il se passer quand le compte à rebours atteint zéro ?
Choisissez l'un des deux comportements et faites-en un paramètre : masquer entièrement la bannière, ou remplacer le minuteur par un message d'expiration. L'option du message est préférable si la promotion se termine pendant qu'il y a du trafic sur le site, car elle préserve la hauteur de la bannière et évite un layout shift tardif. Quel que soit votre choix, mettez réellement fin à la promotion.
Les compte à rebours « evergreen » qui se réinitialisent automatiquement sont-ils une bonne idée ?
Non. Les minuteurs qui se réinitialisent à chaque visite habituent les acheteurs récurrents à ignorer l'urgence, et les fausses dates limites sont considérées comme des pratiques trompeuses (deceptive design) par les règles de protection des consommateurs dans plusieurs juridictions. Faites un compte à rebours vers une vraie date de fin et respectez-la ; l'urgence honnête convertit et continue de convertir.
Comment afficher la bannière sur toutes les pages de ma boutique ?
Ajoutez la section au groupe de sections d'en-tête (header) dans l'éditeur de thème plutôt qu'à un modèle unique. Les sections du groupe d'en-tête s'affichent au-dessus de l'en-tête sur toutes les pages d'un thème Online Store 2.0, de sorte qu'un seul placement couvre toute la boutique et qu'un seul clic la supprime après la promotion.
Footnotes
-
Shopify, code source du thème Dawn,
sections/announcement-bar.liquid- le schéma de la section prend en charge les blocs d’annonce (jusqu’à 12) avec texte et lien, rotation automatique avec une vitesse de 3 à 10 secondes, un schéma de couleurs, une ligne de séparation, des icônes de réseaux sociaux, et des sélecteurs de pays et de langue ; il n’y a pas de compte à rebours ni de paramètre basé sur le temps. https://github.com/Shopify/dawn/blob/main/sections/announcement-bar.liquid ↩ ↩2 -
Centre d’aide Shopify, « Générer automatiquement des blocs de thème dans l’éditeur de thème » - Shopify Magic génère un bloc de thème autonome à partir d’un prompt textuel via Ajouter un bloc → Générer, fonctionne avec les thèmes du Theme Store sur les forfaits Essai gratuit, Basic, Growth, Advanced et Plus, et « L’assistance Shopify ne prend pas en charge la personnalisation ou la résolution de problèmes de code pour les blocs générés par Shopify Magic. » https://help.shopify.com/en/manual/online-store/themes/customizing-themes/theme-editor/shopify-magic/generate-blocks ↩