Saltar al contenido principal

Producto y favoritos

El SDK puede mostrar una tarjeta de producto en el visor y mantener una lista de favoritos en localStorage. Ambas funciones son opcionales y se configuran en vto.start().


Card de producto por tono

Cuando el usuario elige un tono, el visor puede mostrar una tarjeta con el producto asociado: miniatura, nombre, variante y un CTA «VER EL PRODUCTO».

Interfaz Product

CampoTipoObligatorioDescripción
namestringNombre del producto (p.ej. 'AURA Color Gloss').
tonestringNoNombre de la variante o tono (p.ej. 'Cobrizo Rubí').
imageUrlstringNoURL de la miniatura del producto.
urlstringNoURL de destino del CTA «VER EL PRODUCTO».
skustringNoSKU del producto (se usa como clave de favorito cuando está disponible).

Tabla exhaustiva de tipos en 10-referencia-de-tipos.md.

Orden de resolución de producto

El SDK actualiza la card en cada cambio de tono según la primera fuente definida (no es una cascada por valor: si defines resolveProduct, se usa esa y no se consultan las siguientes, aunque devuelva null/undefined, en cuyo caso la card mantiene el producto anterior):

  1. resolveProduct(color) — función async del cliente; se llama siempre que esté definida.
  2. products[color.id] — mapa estático indexado por id del tono; se consulta si no hay resolveProduct.
  3. color.product — producto incrustado en el propio objeto Color; prioridad más baja.

Si resolveProduct está definida y lanza un error, la card mantiene el producto anterior (el SDK absorbe el error silenciosamente).

Ejemplo con mapa estático

await vto.start({
module: 'hair-color',
colors: TONOS,
ui: { branding: { name: 'AURA' } },
products: {
cobrizo: { name: 'AURA Color Gloss', tone: 'Cobrizo Rubí', url: 'https://ejemplo.com/cobrizo' },
cobre: { name: 'AURA Color Gloss', tone: 'Cobre', url: 'https://ejemplo.com/cobre' },
},
onProductClick: (p) => window.open(p.url, '_blank'),
})

Ejemplo con resolveProduct (API async)

await vto.start({
module: 'hair-color',
colors: TONOS,
ui: { branding: { name: 'AURA' } },
resolveProduct: async (color) => {
const res = await fetch(`/api/productos/${color.id}`)
if (!res.ok) return null
return res.json()
},
onProductClick: (p) => window.open(p.url, '_blank'),
})

onProductClick

onProductClick?: (p: Product) => void

Se invoca al pulsar «VER EL PRODUCTO» en la card. Recibe el objeto Product activo. Si no se pasa, el CTA no aparece.


Favoritos (♥)

El visor incluye un panel de favoritos que el usuario puede abrir pulsando el botón ♥ de la barra. El SDK persiste los favoritos en localStorage y expone callbacks para sincronización con la API del cliente.

Persistencia en localStorage

El campo favoritesStorageKey de StartOptions controla la clave de almacenamiento:

ValorComportamiento
undefined (omitido)Usa la clave por defecto 'vto:favorites'.
Cadena no vacía (p.ej. 'aura:favs')Usa esa cadena como clave de localStorage.
'' (cadena vacía)Desactiva la persistencia; los favoritos viven solo en memoria.

Semilla inicial

initialFavorites?: Product[]

Si localStorage está vacío al arrancar (primera visita o clave nueva), el SDK carga initialFavorites como lista de partida. Útil para precargar favoritos desde la API del cliente.

Callbacks

onFavorite?: (p: Product) => void // el usuario añadió un producto
onUnfavorite?: (p: Product) => void // el usuario quitó un producto

Se invocan en tiempo real con el objeto Product afectado. Úsalos para sincronizar con tu backend o registrar analíticas.

Ejemplo completo

await vto.start({
module: 'hair-color',
colors: TONOS,
ui: { branding: { name: 'AURA' } },
products: {
cobrizo: { name: 'AURA Color Gloss', tone: 'Cobrizo Rubí', url: 'https://ejemplo.com/cobrizo' },
},
favoritesStorageKey: 'aura:favs',
initialFavorites: await fetchFavoritesFromApi(userId),
onFavorite: (p) => api.saveFavorite(userId, p),
onUnfavorite: (p) => api.removeFavorite(userId, p),
onProductClick: (p) => window.open(p.url, '_blank'),
})

Para desactivar el botón ♥ en la barra consulta 06-controles.md.