Recipe: Cart bridge custom
Para activar el carrito en el widget necesitas dos cosas:
- Pasar
CartConfigcon callbacks al inicializar el widget víaNeuroonWidget.init() - Emitir
neuroon:cart-updatecada vez que el carrito cambie fuera del widget
1. Configurar CartConfig
Al inicializar el widget, define los callbacks que conectan con tu backend:
const widget = window.NeuroonWidget.init({
container: '#neuroon-search',
token: '<widget-token>',
apiUrl: 'https://api.neuroon.ai',
locale: 'es',
cart: {
enabled: true,
initialCount: 0, // badge inicial desde cookie
// El widget llama esto cuando abre el drawer o recibe neuroon:cart-update
onGetCart: async () => {
const res = await fetch('/api/cart', { credentials: 'include' })
const data = await res.json()
return data.cart // CartState { items, totalItems, subtotal, total, currency }
},
onAddToCart: async (productId, quantity, externalProductId) => {
const res = await fetch('/api/cart/add', {
method: 'POST', credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ productId, quantity, externalProductId }),
})
const data = await res.json()
return { success: true, cart: data.cart, notice: data.notice }
},
onRemoveFromCart: async (itemKey) => {
const res = await fetch('/api/cart/remove', {
method: 'POST', credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ itemKey }),
})
const data = await res.json()
return { success: true, cart: data.cart }
},
onUpdateQuantity: async (itemKey, quantity) => {
const res = await fetch('/api/cart/update', {
method: 'POST', credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ itemKey, quantity }),
})
const data = await res.json()
return { success: true, cart: data.cart }
},
onCheckout: () => {
window.location.href = '/checkout'
},
},
})
2. Emitir el evento al mutar el carrito
Cada vez que tu storefront modifica el carrito fuera del widget, emite el evento. El widget lo recibe, aplica un debounce interno de 300 ms, y llama a onGetCart() para releer el estado:
<script>
(function () {
let timer = null;
const emit = () => {
clearTimeout(timer);
timer = setTimeout(() => {
window.dispatchEvent(new CustomEvent('neuroon:cart-update'));
}, 200);
};
document.addEventListener('cart:added', emit);
document.addEventListener('cart:removed', emit);
document.addEventListener('cart:cleared', emit);
})();
</script>
El widget ignora
event.detail. Siempre consulta el carrito víaonGetCart(). No necesitas pasar datos en el evento.
React / Next.js
'use client';
import { useEffect } from 'react';
export function CartBridge({ cartSnapshot }: { cartSnapshot: unknown }) {
useEffect(() => {
const t = setTimeout(() => {
window.dispatchEvent(new CustomEvent('neuroon:cart-update'));
}, 200);
return () => clearTimeout(t);
}, [cartSnapshot]);
return null;
}
Renderiza <CartBridge cartSnapshot={cart} /> en tu layout principal.
Vue 3 / Nuxt 3
export function useNeuroonCartBridge(cartStore: Ref<unknown>) {
if (process.server) return;
let timer: ReturnType<typeof setTimeout> | null = null;
watch(cartStore, () => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
window.dispatchEvent(new CustomEvent('neuroon:cart-update'));
}, 200);
}, { deep: true });
}
Validar que funciona
// Consola del navegador
window.addEventListener('neuroon:cart-update', () => console.log('cart-update recibido'));
// Añade un producto al carrito → deberías ver el log
Buenas prácticas
- Debounce 200 ms en tu lado. El widget ya aplica 300 ms internamente.
initialCountdesde cookie para que el badge sobreviva al cache de página.canAddToCartpara evitar "añadir al carrito" en productos variables o sin stock.CartOperationResultsiempre con el carrito completo. Nada de actualizaciones parciales.- Una sola fuente de verdad. Si usas WordPress, el plugin ya cubre esto.
Próximos pasos
- Widget · Cart integration — arquitectura del carrito en el widget.