GTM — Countdown Promo PDP
Script equivalente a Countdown Promo Cart pero para la página de producto (PDP). El countdown se inyecta dentro del título del acordeón de promociones. Cuando está activo oculta el icono y el título originales del acordeón y, opcionalmente, el hellobar de la página.
Arquitectura compartida
La lógica de fechas, el sistema de clases html/js, el skeleton de carga, el cálculo de horas según showDays y el patrón PreInit → InjectCode → InitElements → InitCountdown son idénticos a Countdown Promo Cart. Esta página documenta únicamente las diferencias.
Variables GTM
| Variable GTM | Descripción |
|---|---|
{{countdown-pdp-promo-message-intro}} | Texto introductorio antes del countdown. |
{{countdown-pdp-promo-start-date}} | Fecha de inicio — antes de esta fecha el countdown no aparece. |
{{countdown-pdp-promo-end-date}} | Fecha de fin — cuando se alcanza, el countdown desaparece. |
{{countdown-pdp-promo-label-days}} | Etiqueta de días. |
{{countdown-pdp-promo-label-hours}} | Etiqueta de horas. |
{{countdown-pdp-promo-label-minutes}} | Etiqueta de minutos. |
{{countdown-pdp-promo-label-seconds}} | Etiqueta de segundos. |
Flags de configuración
| Variable | Valor por defecto | Descripción |
|---|---|---|
gtmCountdownPromoPdpDelay | 1000 | Espera en ms antes de inicializar. |
gtmCountdownPromoPdpShowDays | false | Muestra columna de días y calcula horas módulo 24. |
gtmCountdownPromoPdpShowIntro | false | Inyecta el párrafo de texto intro (desactivado por defecto, al contrario que en Cart). |
gtmCountdownPromoPdpHideHellobar | true | Si true, oculta el hellobar (.js-hellobar) mientras el countdown está activo. |
Elementos del DOM
| Selector | Descripción |
|---|---|
label[for='product-details-promotions'] > .hw-accordion__title | Contenedor donde se inyecta el countdown. |
...> .hw-accordion__title-icon | Icono del acordeón — se oculta cuando el countdown está activo. |
...> .hw-accordion__title-name | Título del acordeón — se oculta cuando el countdown está activo. |
.js-hellobar | Hellobar de la página — se oculta si hideHellobar = true. |
Diferencias respecto a Countdown Promo Cart
| Aspecto | Promo Cart | Promo PDP |
|---|---|---|
| Contenedor objetivo | .hw-cart_list-item-first-applicable | label[for='product-details-promotions'] > .hw-accordion__title |
| Qué se oculta al activar | span:nth-child(2) (mensaje promo) | .hw-accordion__title-icon + .hw-accordion__title-name |
| Control del hellobar | — | Oculta .js-hellobar si hideHellobar = true |
showIntro por defecto | true | false |
| Layout del content | Fila (flex-direction: row) | Columna (flex-direction: column, align-items: center) |
| Layout de cada elemento | Fila (align-items: baseline) | Columna (flex-direction: column, align-items: center) |
Separador : | display: none | Visible (padding: 0 2px) |
Estructura HTML generada
<!-- Dentro de label[for='product-details-promotions'] > .hw-accordion__title -->
<!-- Ocultos al activar el countdown -->
<span class="hw-accordion__title-icon is-hidden">...</span>
<span class="hw-accordion__title-name is-hidden">...</span>
<!-- Inyectado por el script -->
<div class="gtm-js-countdown-content gtm-html-countdown-content">
<!-- Solo si showIntro = true -->
<p class="gtm-js-countdown-intro gtm-html-countdown-intro">
{{countdown-pdp-promo-message-intro}}
</p>
<div class="gtm-js-countdown gtm-html-countdown">
<div class="gtm-html-countdown-wrapper">
<!-- Días: solo si showDays = true Y days > 0 -->
<div class="gtm-html-countdown-element">
<p class="gtm-html-countdown-number">02</p>
<p class="gtm-html-countdown-label">días</p>
</div>
<p class="gtm-html-countdown-separator">:</p>
<!-- Horas: si hours > 0 O si hay días -->
<div class="gtm-html-countdown-element">
<p class="gtm-html-countdown-number">14</p>
<p class="gtm-html-countdown-label">h</p>
</div>
<p class="gtm-html-countdown-separator">:</p>
<!-- Minutos: siempre -->
<div class="gtm-html-countdown-element">
<p class="gtm-html-countdown-number">07</p>
<p class="gtm-html-countdown-label">min</p>
</div>
<p class="gtm-html-countdown-separator">:</p>
<!-- Segundos: siempre -->
<div class="gtm-html-countdown-element">
<p class="gtm-html-countdown-number">33</p>
<p class="gtm-html-countdown-label">seg</p>
</div>
</div>
</div>
</div>
Separador visible
A diferencia de la variante Cart, aquí el separador : entre unidades sí es visible (tiene padding: 0 2px en lugar de display: none).
Flujo de ejecución
Espera gtmCountdownPromoPdpDelay ms (defecto: 1000ms)
│
└─ fnGtmInitCountdownPromoPdp()
│
├─ fnGtmCountdownPromoPdpToPreInitElements()
│ └─ Busca container, icon, title, hellobar
│
├─ fnGtmCountdownPromoPdpToInjectCode()
│ └─ Crea div.content + p.intro (si showIntro) + div.countdown (skeleton)
│ → appended al container, inicialmente con is-hidden
│
├─ fnGtmCountdownPromoPdpToInitElements()
│ └─ Recupera los nodos creados via gtm-js-* selectors
│
└─ fnGtmCountdownPromoPdpToInitCountdown()
├─ Si now < startDate → no hace nada
└─ Si now >= startDate Y diferencia > 0:
└─ fnGtmCountdownPromoPdpToShowCountdown()
├─ Oculta hellobar (si hideHellobar)
├─ Oculta icon + title del acordeón
├─ Muestra intro (si showIntro) + countdown
└─ setInterval 1000ms → fnGtmCountdownPromoPdpToUpdateCountdown()
├─ Recalcula tiempo y actualiza HTML
└─ Si diferencia <= 0:
└─ fnGtmCountdownPromoPdpToRemoveCountdown()
├─ Elimina intro + countdown del DOM
├─ Restaura hellobar (si hideHellobar)
├─ Restaura icon + title del acordeón
└─ clearInterval