Template de integración desarrollado para implementar la experiencia de búsqueda Empathy en tiendas VTEX. Esta aplicación inyecta un widget de búsqueda avanzada mediante VTEX Pixel, siguiendo las prácticas recomendadas por VTEX.
- Descripción General
- Requisitos Previos
- Instalación
- Configuración
- Arquitectura
- Componentes Principales
- Flujo de Integración
- Conceptos Clave
- Configuración por Cliente
- Debugging
- Contributors
Esta app es una solución template configurable que permite integrar el buscador de Empathy en tiendas VTEX. Cada cliente puede tener diferentes configuraciones según sus necesidades:
✅ Con o sin variantes de productos
✅ Con o sin botón de add to cart
✅ Con o sin quantity selector
✅ Con o sin wishlist
- 🔍 Búsqueda avanzada mediante el widget de Empathy
- 🛒 Integración con carrito VTEX (add/remove/update)
- ❤️ Gestión de wishlist con sincronización visual
- 📊 Eventos de analítica GA4 personalizados
- 🔄 Comunicación bidireccional mediante el
setSnippetConfig
⚠️ IMPORTANTE: Antes de instalar esta app, asegúrate de que:
- El conector backend de Empathy esté correctamente configurado
- El catálogo de VTEX se esté enviando como feed a Empathy
- El equipo de Empathy haya mapeado el feed correctamente
- Tengas acceso al script de Empathy de cada cliente (
app.js) provisto por el equipo de Empathy
Esta aplicación está diseñada para operar como una App Privada. Sigue estos pasos para configurarla e instalarla bajo la cuenta correspondiente.
Asegúrate de estar logueado en la cuenta objetivo:
vtex login <account-name>-
Opción A - Hacer fork del repositorio (recomendado):
- Haz fork del repositorio desde GitHub: https://github.com/empathyco/empathy-pixel-app-archetype/fork
- Clona tu fork:
git clone https://github.com/TU_USUARIO/empathy-pixel-app-archetype cd empathy-pixel-app-archetypeOpción B - Clonar repositorio:
git clone https://github.com/empathyco/empathy-pixel-app-archetype cd empathy-pixel-app-archetype -
Configura tu aplicación: Sigue la guía de configuración detallada en la sección Configuración.
-
Prueba la aplicación: En este punto puedes probar la aplicación localmente para asegurarte de que se carga correctamente en tu tienda VTEX.
vtex link
-
Publica la aplicación: Publica la app en el registry de VTEX para que esté disponible en tu cuenta:
vtex publish
-
Instala la aplicación: Instala la versión recién publicada en el workspace actual:
vtex install
-
Verifica la instalación:
vtex ls | grep <account-name>.empathy-pixel-app
Configura el Vendor (Account Name): Abre el archivo manifest.json en la raíz del proyecto. Cambia el valor del campo vendor por el nombre de la cuenta (account name) donde se instalará la aplicación.
// manifest.json
{
"name": "empathy-pixel-app",
"vendor": "TU_ACCOUNT_NAME",
"version": "0.0.x"
}Nota: Esto cambiará el ID de la app a TU_ACCOUNT_NAME.empathy-pixel-app.
Actualiza el archivo pixel/head.html con la URL del script de Empathy proporcionada por el equipo:
<script src="https://x.empathy.co/x-{INSTANCE}/app.js" type="module"></script>Ejemplo:
<script src="https://x.empathy.co/x-chedraui/app.js" type="module"></script>En react/Components/EmpathySearchbar/index.tsx, configura los parámetros del cliente:
Ejemplo:
(window as any).initX = {
instance: "{INSTANCE}", // Identificador del cliente provisto por Empathy. Ej: 'chedraui'
lang: "es", // Idioma: 'es', 'en', 'pt', etc.
scope: "desktop", // 'desktop' o 'mobile'
currency: "EUR", // 'EUR', 'USD', 'MXN', etc.
consent: false,
viewMode: 'embedded',
callbacks: { ... }
};En tu theme, agrega los componentes empathy-searchbar y empathy-results en las templates donde necesites. Estos componentes pueden ubicarse independientemente en diferentes templates según la estructura de tu tienda.
empathy-searchbar: En el header o donde necesites el cajón de búsquedaempathy-results: En la template donde quieras mostrar los resultados (home, search, category, etc.)
El componente empathy-results tiene un comportamiento especial que requiere una configuración específica.
¿Cómo funciona?
empathy-results renderiza un div con data-teleport="empathy-results-container". Cuando el usuario realiza una búsqueda, el script de Empathy inyecta los resultados dentro de este contenedor y automáticamente oculta todos sus elementos hermanos en el DOM. Esto permite que el grid de resultados se incruste en el contenido de la página sin necesidad de CSS adicional.
Configuración requerida:
Para que este mecanismo funcione correctamente, el contenido de la página que quieras ocultar durante la búsqueda debe estar declarado como children de empathy-results, convirtiéndose así en hermanos de los resultados de búsqueda.
💡 Nota: No es necesario incluir todo el contenido de la página. Elementos como partes del footer, chatbots, o componentes específicos que quieras mantener visibles durante la búsqueda pueden quedar fuera de los children de
empathy-results.
Ejemplo A: Searchbar en header, Results en home
Antes de la integración - Home:
{
"store.home": {
"blocks": [
"flex-layout.row#hero",
"flex-layout.row#integrate",
"flex-layout.row#promises"
]
}
}Después de la integración - Home:
{
"store.home": {
"blocks": [
"empathy-results",
"flex-layout.row#promises"
]
},
"empathy-results": {
"children": [
"flex-layout.row#hero",
"flex-layout.row#integrate"
]
}
}💡 Aquí,
flex-layout.row#promisesqueda fuera de los children deempathy-resultsporque no queremos que se oculte durante la búsqueda. Solo los elementos dentro de los children se ocultan automáticamente cuando aparecen los resultados.
Antes de la integración - Header:
{
"header": {
"blocks": [
"header-layout.desktop"
]
},
"flex-layout.row#desktop": {
"children": [
"logo",
"minicart"
]
}
}Después de la integración - Header:
{
"header": {
"blocks": [
"header-layout.desktop"
]
},
"flex-layout.row#desktop": {
"children": [
"logo",
"empathy-searchbar",
"minicart"
]
}
}💡 Aquí, el cajón de búsqueda se integrará en una fila del header, entre el logo de la store y el carrito.
Ejemplo B: Ambos componentes en search page
Antes de la integración:
{
"store.search": {
"blocks": [
"flex-layout.row#products"
]
}
}Después de la integración:
{
"store.search": {
"blocks": [
"empathy-searchbar",
"empathy-results"
]
},
"empathy-results": {
"children": [
"flex-layout.row#products"
]
}
}💡 En este ejemplo, tanto el cajón de búsqueda como los resultados están integrados consecutivamente. Todos los elementos originales del search page están dentro de los children de
empathy-results, por lo que se ocultarán automáticamente cuando aparezcan los resultados de búsqueda.
📌 Recuerda: Puedes decidir dónde colocar cada componente según su estructura de templates. Por ejemplo: podrías usar
empathy-searchbarsinempathy-resultssi solo necesitas el cajón de búsqueda, o usar solamenteempathy-resultsmanejando la query, filtros, etc. por los parámetros de la url.
📚 Más información: Puedes obtener más detalles sobre cómo se integra Empathy en la documentación oficial de Empathy.
empathy-pixel-app-archetype/
├── manifest.json # Configuración de la app VTEX
├── pixel/
│ └── head.html # Script de inicialización de Empathy
├── store/
│ ├── interfaces.json # Definición de componentes React
│ └── plugins.json # Configuración de pixel manager
├── react/
│ ├── index.tsx # Entry point del pixel
│ ├── Components/
│ │ ├── EmpathySearchbar/ # 🔑 Componente principal
│ │ │ ├── index.tsx
│ │ │ ├── constants.tsx
│ │ │ ├── utils/
│ │ │ │ ├── index.tsx # Utilidades generales
│ │ │ │ └── handleCart.ts # Lógica de carrito
│ │ │ ├── hooks/
│ │ │ │ ├── handleWishlist.ts
│ │ │ │ └── useGAAnalytics.ts
│ │ │ └── gql/ # GraphQL queries
│ │ └── EmpathyResults/ # Overlay de resultados
└── docs/
└── README.md
{
"vtex.pixel-interfaces": "1.x",
"vtex.order-items": "0.x",
"vtex.order-manager": "0.x",
"vtex.styleguide": "9.x",
"vtex.pixel-manager": "1.x",
"vtex.session-client": "1.x",
"vtex.wish-list": "1.x" // Opcional (solo si se usa wishlist)
}El componente principal que:
- Inicializa el widget de Empathy mediante
initX - Configura callbacks para interacciones del usuario
- Gestiona la comunicación con VTEX (carrito, wishlist)
- Envía eventos de analítica a GA4
Callbacks disponibles:
| Callback | Descripción |
|---|---|
UserClickedResultAddToCart |
Click en "agregar al carrito" (producto simple) |
UserClickedResultVariantAddToCart |
Click en "agregar al carrito" (con variantes) |
UserClickedResultRemoveFromCart |
Click en "quitar del carrito" (producto simple) |
UserClickedResultVariantRemoveFromCart |
Click en "quitar del carrito" (con variantes) |
UserClickedResultWishlist |
Click en el icono de wishlist |
Contenedor overlay para mostrar los resultados de búsqueda. Empathy "teleporta" su UI a este componente usando data-teleport.
handleCart.ts: Lógica centralizada para operaciones de carritohandleWishlist.ts: Gestión completa de wishlist con GraphQLuseGAAnalytics.ts: Envío de eventos personalizados a GA4index.tsx(utils): Funciones auxiliares (findProductBySkuId,mapProductForGA4)
sequenceDiagram
participant Browser
participant VTEX
participant Empathy
participant Component
Browser->>VTEX: Carga página
VTEX->>Browser: Inyecta head.html
Browser->>Empathy: Descarga app.js
Empathy->>Browser: window.InterfaceX disponible
Component->>Empathy: Configura initX + callbacks
Component->>Empathy: InterfaceX.init()
Empathy->>Component: Widget renderizado en teleport
sequenceDiagram
participant User
participant Empathy
participant Callback
participant VTEX
participant GA4
User->>Empathy: Click "Agregar al carrito"
Empathy->>Callback: UserClickedResultAddToCart(result, metadata)
Callback->>Callback: handleCartOperation()
Callback->>Callback: Determina acción (newProduct/updateQuantity)
Callback->>Empathy: setSnippetConfig({ cart: {...} })
Callback->>VTEX: findProductBySkuId()
VTEX->>Callback: Datos del producto
Callback->>GA4: pushAddToCartEvent()
Callback->>VTEX: addItems() o updateQuantity()
VTEX->>User: Producto en carrito
sequenceDiagram
participant User
participant Empathy
participant Hook
participant VTEX
participant GA4
User->>Empathy: Click icono wishlist
Empathy->>Hook: UserClickedResultWishlist(result)
Hook->>VTEX: checkSession()
alt Usuario no autenticado
Hook->>User: Redirigir a /login
else Usuario autenticado
Hook->>VTEX: checkItemQuery (GraphQL)
alt Ya en wishlist
Hook->>VTEX: removeMutation (GraphQL)
Hook->>Empathy: setSnippetConfig({ wishlist: [...] })
else No en wishlist
Hook->>VTEX: addMutation (GraphQL)
Hook->>GA4: pushWishlistEvent()
Hook->>Empathy: setSnippetConfig({ wishlist: [...] })
end
end
Esta es la interfaz principal para comunicarse con el widget de Empathy:
(window as any).InterfaceX.setSnippetConfig({
cart: {
"123": 2, // SKU ID → Cantidad
"456": 1
},
wishlist: ["789", "101112"], // Array de SKU IDs en wishlist
// ... otros parámetros
});¿Qué hace?
- ✅ Actualiza el estado visual del widget
- ✅ Muestra cantidades en el carrito
- ✅ Marca productos con icono de wishlist "filled"
📚 Más información: Puedes obtener más información sobre la configuración del snippet en la documentación oficial de Empathy.
La app envía 3 eventos personalizados:
add_to_cart_empathy: Cuando se agrega un productoremove_from_cart_empathy: Cuando se quita un productoadd_to_wishlist_empathy: Cuando se agrega a favoritos
Todos incluyen:
search_term: El término de búsqueda que generó la interacciónecommerce.items[]: Datos del producto en formato GA4
- Cambiar URL en
pixel/head.htmlsegún entorno del cliente - Verificar que el script se cargue correctamente (
console.log(window.InterfaceX))
- Actualizar
instance(identificador del cliente en Empathy) - Ajustar
langsegún idioma del sitio - Configurar
currencysegún moneda de la tienda - Verificar
scope:'desktop'o'mobile'
- ¿El cliente tiene variantes? → Mantener callbacks de
Variant - ¿El cliente tiene add to cart? → Configurar callbacks de
AddToCart - ¿El cliente tiene quantity selector? → Verificar
metadata.inputValue - ¿El cliente tiene wishlist? → Verificar dependencia
vtex.wish-list
- Verificar que el conector backend esté instalado
- Confirmar que el feed se envíe correctamente a Empathy
- Validar que Empathy haya mapeado el feed
- Probar búsqueda y resultados
- Probar add/remove from cart (con y sin variantes)
- Probar wishlist (agregar/remover)
- Verificar eventos GA4 en
window.dataLayer
// 1. Verificar que Empathy está cargado
console.log(window.InterfaceX);
// 2. Ver configuración actual
console.log(window.InterfaceX.getSnippetConfig());
// 3. Ver cart sincronizado
console.log(window.InterfaceX.getSnippetConfig()?.cart);
// 4. Ver wishlist sincronizada
console.log(window.InterfaceX.getSnippetConfig()?.wishlist);
// 5. Ver eventos GA4
console.log(window.dataLayer);| Problema | Solución |
|---|---|
| Widget no se muestra | Verificar que el script en head.html se cargue correctamente |
InterfaceX is undefined |
El script de Empathy no se cargó. Revisar URL y conectividad |
| Cart no sincroniza | Revisar que setSnippetConfig se llame después de init() |
| Wishlist no funciona | Verificar que vtex.wish-list esté instalada |
| Eventos GA4 no aparecen | Revisar que window.dataLayer exista antes de push |
Desarrollado por el equipo de Experimentality para implementaciones de Empathy en VTEX.