Documentation
Feedback
Guides
VTEX IO Apps

VTEX IO Apps
Empathy Listener System Roadmap
Community extension
Version: 0.0.6
Latest version: 0.0.6

Overview

This roadmap outlines the plan to create a centralized listener hook that synchronizes Empathy context (cart, wishlist, whitelabel) with VTEX state changes (orderForm, session, wishlist).

Core Logic

The listener will primarily react to orderForm changes, which serves as the "heartbeat" of the store's state changes.

useEmpathyListener Hook

A new custom hook will be responsible for orchestrating updates.

Triggers:

  1. Mount: Initial sync.
  2. OrderForm Update: React to changes in useOrderForm.
  3. Window Events: Listen to orderFormUpdated.vtex (backup trigger).

Actions on Trigger:

  1. Sync Session (Region/Whitelabel)

    • Call refetch() from useFullSession.
    • Decoding regionId from namespaces.checkout.regionId.
    • Update Empathy: setSnippetConfig({ whitelabel: { regionId: '...' } }).
  2. Sync Cart

    • Read orderForm.items.
    • Format items to Empathy structure (id, sku, price, quantity).
    • Update Empathy: setSnippetConfig({ cart: [...] }).
  3. Sync Wishlist

    • Note: Wishlist is expensive to fetch entirely. We need a strategy.
    • Option A: Fetch all wishlist items (might be slow if list is huge).
    • Option B: handleWishlist already manages its state locally + API. We might expose a refetchWishlist method.
    • Recommended: execute a "Get All Wishlist" query (or rely on checkItem for visible products if possible, but user asked to sync changes). We will likely need a getUserWishlist query.
    • Update Empathy: setSnippetConfig({ wishlist: [productIds] }).

file Structure


_10
react/
_10
hooks/
_10
useEmpathyListener.ts // Central orchestrator
_10
useSessionListener.ts // (Existing) Refactor to export data + refetch
_10
Components/
_10
EmpathySearchbar/
_10
index.tsx // Mounts useEmpathyListener

Implementation Steps

Phase 1: Preparation (Current)

  • Analyze vtex.session-client.
  • Create useSessionListener prototype.
  • Research/Verify Wishlist generic query (vtex.wish-list generic query typically requires iterating or getting a specific list).

Phase 2: Listener Core

  • Create useEmpathyListener.ts.
  • Implement useOrderForm dependency.
  • Add useEffect listening to orderForm.

Phase 3: Connect Data Sources

  • Cart: Map orderForm.items -> Empathy Cart format.
  • Session: Integrate useSessionListener logic into the new listener or expose refetch.
  • Wishlist: Implement useQuery for "Get Wishlist" (likely GetWishlist from vtex.wish-list).

Phase 4: Integration

  • Replace isolated hooks in EmpathySearchbar with centralized useEmpathyListener.
  • Verify functionality (Add to cart -> Console log / Empathy update).

🚀 Evolutivos Propuestos

1. Sincronización Automática de Carrito

Objetivo: Leer el carrito de VTEX al cargar la página y sincronizarlo con Empathy.

Implementación:


_19
useEffect(() => {
_19
const initialCart: { [key: string]: number } = {};
_19
cartItems.forEach((item: any) => {
_19
initialCart[item.id] = item.quantity;
_19
});
_19
_19
(window as any).InterfaceX?.init();
_19
(window as any).InterfaceX?.setSnippetConfig({ cart: initialCart });
_19
}, []);
_19
_19
// Sincronizar cuando cambie
_19
useEffect(() => {
_19
if (!(window as any).InterfaceX) return;
_19
const syncedCart: { [key: string]: number } = {};
_19
cartItems.forEach((item: any) => {
_19
syncedCart[item.id] = item.quantity;
_19
});
_19
(window as any).InterfaceX.setSnippetConfig({ cart: syncedCart });
_19
}, [cartItems]);

Beneficios:

  • ✅ Usuario ve inmediatamente qué productos ya tiene
  • ✅ Sincronización bidireccional
  • ✅ Mejor UX

2. Integración de regionId con Whitelabel

Objetivo: Leer la región del usuario y pasarla a Empathy para búsquedas específicas por región.

Implementación:


_29
// utils/getRegionId.ts
_29
export const getRegionId = async (): Promise<string | null> => {
_29
const sessionPromise = getSessionPromise();
_29
if (!sessionPromise) return null;
_29
try {
_29
const sessionRes = await sessionPromise;
_29
return sessionRes?.response?.namespaces?.public?.regionId?.value || null;
_29
} catch {
_29
return null;
_29
}
_29
};
_29
_29
// En EmpathySearchbar
_29
useEffect(() => {
_29
(async () => {
_29
const regionId = await getRegionId();
_29
(window as any).initX = {
_29
// ... config ...
_29
whitelabel: regionId ? { regionId } : undefined,
_29
callbacks: { ... }
_29
};
_29
(window as any).InterfaceX?.init();
_29
if (regionId) {
_29
(window as any).InterfaceX?.setSnippetConfig({
_29
whitelabel: { regionId }
_29
});
_29
}
_29
})();
_29
}, []);

Beneficios:

  • ✅ Búsquedas contextuales por región
  • ✅ Productos específicos por ubicación
  • ✅ Mejor relevancia de resultados

3. Pre-carga de Wishlist

Objetivo: Marcar automáticamente productos que ya están en wishlist al cargar la página.

GraphQL Query nueva:


_10
query GetWishlistItems($shopperId: String!, $name: String!) {
_10
list(shopperId: $shopperId, name: $name)
_10
@context(provider: "vtex.wish-list"){
_10
data {
_10
productId
_10
sku
_10
title
_10
}
_10
}
_10
}

Implementación:


_25
export const useInitialWishlist = () => {
_25
const [loadWishlisted] = useLazyQuery(GET_WISHLIST_ITEMS);
_25
_25
const loadAndSyncWishlist = async () => {
_25
try {
_25
const { isAuthenticated, shopperId } = await checkSession();
_25
if (!isAuthenticated) return;
_25
_25
const result = await loadWishlisted({
_25
variables: { shopperId: String(shopperId), name: 'Wishlist' }
_25
});
_25
_25
const wishlistedItems = result?.data?.list?.data || [];
_25
const wishlistedSkus = wishlistedItems.map((item: any) => item.sku);
_25
_25
(window as any).InterfaceX?.setSnippetConfig({
_25
wishlist: wishlistedSkus
_25
});
_25
} catch (error) {
_25
console.error('Error loading wishlist:', error);
_25
}
_25
};
_25
_25
return { loadAndSyncWishlist };
_25
};

Beneficios:

  • ✅ Productos favoritos aparecen con corazón "filled"
  • ✅ Mejor experiencia de usuario
  • ✅ Consistencia entre sesiones

See also
Empathymx.pixel App
VTEX IO Apps
VTEX App Store
VTEX IO Apps
Was this helpful?