Skip to main content

GTM — Sign Up Fake Product PDP (Customer Guest)

Script que transforma la PDP de un producto no disponible para su compra en un punto de captación de leads. Elimina el botón original "Add to Cart" y el mensaje de fecha de llegada, y los sustituye por un botón que despliega un formulario de suscripción inline. Al registrarse correctamente, envía un evento sign_up al dataLayer de GTM.


Variables GTM

Variable GTMDescripción
{{fake-product-button-let-me-know}}Texto del botón que reemplaza al "Add to Cart".
{{fake-product-form-intro-guest}}Texto introductorio que aparece dentro del panel del formulario.
{{fake-product-message-success-guest}}Mensaje de éxito que se muestra tras el registro correcto.
{{popup-url}}URL del endpoint al que se envía el formulario.
{{popup-introduce-email}}Placeholder del campo email.
{{popup-accept-legal}}Texto de la cláusula legal (prefijo del enlace).
{{privacy-policyURL}}URL de la política de privacidad.
{{popup-privacy-policy}}Texto del enlace a la política de privacidad.
{{popup-button-submit}}Texto del botón de envío del formulario.
Variables compartidas con Popup Fast Sign Up

{{popup-url}}, {{popup-introduce-email}}, {{popup-accept-legal}}, {{privacy-policyURL}}, {{popup-privacy-policy}} y {{popup-button-submit}} son las mismas variables que usa el script Popup Fast Sign Up. Se pueden reutilizar si los valores coinciden.


Elementos que se eliminan del DOM

Antes de inyectar el contenido propio, el script elimina dos elementos del DOM original:

SelectorQué esPor qué se elimina
.js-button-add-to-cartBotón original de añadir al carritoSe reemplaza por el botón fake
.js-arrival-date-messageMensaje de fecha estimada de llegadaNo es relevante para un producto fake

El padre del botón original recibe la clase gtm-html-fake-button-parent (flex-wrap: wrap) para que el botón fake y el panel del formulario se apilen correctamente.


Flujo de interacción

La experiencia tiene dos pasos:

  1. Botón fake visible — reemplaza visualmente al "Add to Cart" (fondo gris #969696). Al hacer clic, muestra un estado de carga durante 500ms.
  2. Panel del formulario — se abre tras esos 500ms. Contiene email + checkbox legal + botón de envío.
[Botón fake] → click → is-loading (500ms) → panel abre (is-opened)
[Panel] → submit → XHR POST → éxito / error

Estados del componente

ClaseCuándo se aplicaEfecto visual
(ninguna)Estado inicialBotón gris #969696 activo.
is-loadingAl hacer click (durante 500ms)cursor: not-allowed, oculta el texto, muestra spinner SVG.

Clases CSS

ClaseElementoDescripción
gtm-html-fake-button-parentPadre del botón originalflex-wrap: wrap — permite apilar botón fake + panel.
gtm-html-fake-button-add-to-cartbutton fakeBotón gris #969696, ancho 100%, negro al hover.
gtm-html-fake-button-add-to-cart__textspan dentro del botónTexto visible del botón; se oculta con is-loading.
gtm-html-fake-button-contentdiv panelOculto por defecto (display: none); visible con is-opened. border: 1px solid #969696.
gtm-html-fake-product-form__inputinput[email]Ancho 100%, fondo #f9f9f9, font-size: 14px.
gtm-html-fake-product-form__buttonbutton[submit]Fondo negro, texto blanco, ancho 100%.
gtm-html-fake-product-form__button-textspan del botónTexto del envío; se oculta con is-loading en el form.
gtm-html-fake-product-form__legal-wrapperdivFila checkbox + texto. align-items: baseline.
gtm-html-fake-product-form__legal-textlabelTexto legal con enlace subrayado. font-size: 14px.
gtm-html-button-loadersvg spinnerCompartido por botón fake y botón de envío. Animación gtm-spin.
gtm-html-fake-product__errorpOculto por defecto; visible con has-error en el form. Fondo rojo #f22248.
gtm-html-fake-product__successpOculto por defecto; visible con has-success.

Campos del formulario

Atributo nameTipoDescripción
emailPopupFastSignUpemailEmail del usuario. Enviado en el body del POST como email=....
fakeProductSignUpLegalcheckboxAceptación de la política de privacidad. Solo se valida localmente.
note

El campo email usa el mismo name (emailPopupFastSignUp) que el script Popup Fast Sign Up. El checkbox usa un name propio (fakeProductSignUpLegal).


Respuesta de la API

El XHR espera la misma estructura JSON que el Popup Fast Sign Up:

{
"success": true,
"message": "¡Gracias por suscribirte!",
"hashedEmail": "5f4dcc3b5aa765d61d8327deb882cf99"
}

Evento GTM

Al registrarse correctamente se hace un push al dataLayer:

{
event: "sign_up",
method: "web",
place: "fake_product", // diferente de "popup"
email: hashedEmail // email hasheado, nunca en claro
}

Diferencias respecto a Popup Fast Sign Up

AspectoPopup Fast Sign UpSign Up Fake Product
Posición en pantallafixed, esquina inferior derechaInline en la PDP, parte del flujo de página
DisparadorSe abre automáticamente al cargarClic del usuario en el botón fake
Animación de aperturaSlide-up con translateYPanel con display: none → block tras 500ms
Elementos eliminadosNinguno.js-button-add-to-cart + .js-arrival-date-message
Cierre automáticoSí, 3000ms tras el éxitoNo — el formulario se elimina y queda el mensaje
place en evento GTM"popup""fake_product"
Nombre del checkboxlegalPopupFastSignUpfakeProductSignUpLegal

Flujo de ejecución

fnGtmSignUpFakeProductInit() ← llamada directa al cargar el tag

├─ fnGtmSignUpFakeProductToPreInitElements()
│ ├─ Busca .js-button-add-to-cart → lo elimina del DOM
│ ├─ Guarda su parentElement como addToCartButtonParent
│ ├─ Añade gtm-html-fake-button-parent al parentElement
│ └─ Busca .js-arrival-date-message → lo elimina del DOM

├─ fnGtmSignUpFakeProductToInjectCode()
│ ├─ Crea button.gtm-html-fake-button-add-to-cart con texto + spinner
│ ├─ Crea div.gtm-html-fake-button-content con form + success
│ └─ Appenda ambos al addToCartButtonParent

├─ fnGtmSignUpFakeProductToInitElements()
│ └─ Recupera todos los nodos via selectores gtm-js-* y gtm-html-*

└─ fnGtmSignUpFakeProductToListenEvents()

├─ Botón fake → click → fnGtmSignUpFakeProductToShowForm()
│ ├─ Añade is-loading al botón fake
│ └─ setTimeout(500ms):
│ ├─ Añade is-opened al panel (form visible)
│ └─ Quita is-loading del botón fake

└─ Form → submit → fnGtmSignUpFakeProductToHandleSubmitForm(event)
├─ event.preventDefault()
├─ fnGtmSignUpFakeProductToValidateForm() → {url, email, isValid}
│ ├─ URL vacía → error (console)
│ ├─ Email vacío → error (console)
│ └─ Legal no marcado → error (console)
├─ fnGtmSignUpFakeProductToStartLoadingForm()
│ └─ Añade is-loading al form, quita has-error
├─ Si isValid: XHR POST a url con email=...
│ └─ readyState 4 + status 200:
│ ├─ success: true → fnGtmSignUpFakeProductToSetSuccess(hashedEmail)
│ │ ├─ Elimina el <form> del DOM
│ │ ├─ Añade has-success a .gtm-html-fake-product__success
│ │ └─ fnGtmSignUpFakeProductToLaunchGtmEvent(hashedEmail)
│ │ └─ dataLayer.push({ event: "sign_up", place: "fake_product", ... })
│ └─ success: false → fnGtmSignUpFakeProductToSetError(message)
│ ├─ Escribe message en .gtm-html-fake-product__error
│ └─ Añade has-error al form
└─ fnGtmSignUpFakeProductToStopLoadingForm()
└─ Quita is-loading del form