Contexto de navegación
El módulo de Findalo publica en tu tienda una variable,
window.FINDALO_CTX,
con todo lo que el servidor sabe de la página que está viendo el visitante: qué tipo de página es,
qué producto o categoría, idioma y divisa, su carrito y su grupo de cliente.
La misma forma en PrestaShop, WooCommerce, Magento y Shopware.
Sirve para no adivinar. Hasta ahora, cualquier integración tenía que deducir la página por las clases
del <body>
y el producto por el JSON-LD o la URL — algo que falla en cuanto el tema es a medida.
Aquí el dato viene del servidor, que lo sabe con certeza.
Cómo leerlo
// Directo, para lo que no depende del visitante:
const ctx = window.FINDALO_CTX;
if (ctx.page.type === 'product') console.log('Ficha:', ctx.product.id, ctx.product.sku);
// Si dependes del CARRITO o del CLIENTE, espera a que estén resueltos:
findalo.onContext((ctx) => {
if (ctx.cart?.total !== null && ctx.cart.total < 20) {
// ej. sugerir productos para llegar al envío gratis
}
}); Dos mitades, y por qué importa
El tipo de página, los ids, el idioma y la divisa se escriben directamente en el HTML: son iguales para todo el que visite esa URL, así que se pueden cachear sin riesgo.
El carrito, el cliente y el precio del producto no viajan en el HTML. Si tu tienda
tiene caché de página (LiteSpeed, Varnish, un plugin de WordPress, el Full Page Cache de Magento),
ese HTML se sirve tal cual al siguiente visitante — y el carrito llegaría rancio o, peor, ajeno.
Esa parte se pide aparte, con la sesión del visitante y sin caché, y el widget la mezcla en el
mismo objeto en cuanto llega. Ese momento es el que anuncian
findalo.onContext
y el evento context.
Consecuencia práctica: en el carrito, null significa
desconocido, no cero. Un carrito que no se pudo leer no debe activar una regla
de «carrito por debajo de X €».
Campos
| Campo | Tipo | Qué es |
|---|---|---|
| v | number | Versión del contrato. Hoy 1. Si sube, los campos actuales siguen existiendo. |
| ready | boolean | true cuando la parte privada (carrito y cliente) ya está resuelta. Si dependes de ellos, usa findalo.onContext en vez de leer el objeto directamente. |
| source | "connector" | "fallback" | «connector» = lo emitió el módulo de tu plataforma. «fallback» = el módulo es anterior a esta feature y el widget reconstruyó lo que pudo. |
| emittedAt | number | Epoch (s) en que el servidor generó la parte estática. Si tu tienda cachea páginas, delata HTML viejo. |
| shop | object | platform, platformVersion, connector (versión del módulo), id de tienda/canal, name, baseUrl, homeUrl, cartUrl, checkoutUrl, accountUrl. |
| locale | object | lang (ISO), locale, currency (ISO), country, langId nativo. |
| page.type | string | home · product · category · brand · search · cart · checkout · order-confirmation · cms · account · other. |
| page.legacyType | string | El mismo tipo reducido a los 5 valores históricos (home/product/category/cart/other). |
| page.route | string | El controlador o ruta NATIVA sin traducir: php_self en PrestaShop, full action name en Magento, _route en Shopware, plantilla en WordPress. |
| page.ids | object | Ids de la página: product, category, brand, supplier, cms, order, variant. Solo aparece el que corresponde al tipo de página. |
| page.query | string | Término de la búsqueda NATIVA de la tienda (no la del widget), en páginas de tipo search. |
| product | object | null | Ficha actual: id (en el id-space del catálogo indexado), uuid nativo si difiere, sku, name, url, image, inStock, categoryId(s), brandId, variantId. price y purchasable llegan con la parte privada. |
| category | object | null | Listado actual: id, name, count y path (migas desde la raíz). |
| cart | object | null | count, quantity, total, subtotal, currency, lines[]. OJO: null en un campo significa DESCONOCIDO, no cero. |
| customer | object | logged, id, groups[], pricingGroup y token de visibilidad. Sin datos personales: nunca email ni nombre. |
| native | object | El crudo de tu plataforma: lo que manda el módulo (ids nativos) más los globals que ya publica la tienda — prestashop, los params de WooCommerce, mage-cache-storage, los globals del storefront de Shopware. |
| dynamic | object | null | URL del endpoint de la parte privada, por si quieres refrescar el carrito tú mismo. |
Qué trae cada plataforma
| Plataforma | Desde | Carrito | Notas |
|---|---|---|---|
| PrestaShop | módulo 1.6.45+ | completo | Carrito con líneas, cliente con todos sus grupos y precio del producto para su tarifa. |
| WooCommerce | plugin 1.3.8+ | completo | Carrito con líneas; el «grupo» del cliente son sus roles de WordPress, que es lo que leen los plugins de precios B2B. |
| Magento | módulo 1.3.6+ | completo | Carrito del quote y precio con las catalog price rules del grupo. La parte estática es FPC-safe: no tumba la caché de página. |
| Shopware | App 0.9.5+ | sin carrito | La App no ejecuta PHP en la tienda y el hook del endpoint no expone el carrito, así que cart queda como DESCONOCIDO (no como vacío). Sí llegan el grupo del cliente y si está logueado. |
El crudo de tu plataforma: native
Lo normalizado cubre lo común a las cuatro plataformas. Cuando necesites algo específico,
ctx.native
lleva lo que manda tu módulo (ids nativos: id_shop,
store_id, salesChannelId…) y una
referencia a los globals que tu tienda ya publica por su cuenta.
// PrestaShop: el global oficial del tema, tal cual ctx.native.prestashop?.page.page_name // WooCommerce: los params que publica cada script del core ctx.native.wc_add_to_cart_params?.ajax_url // Magento: el contexto privado que el core guarda en localStorage ctx.native.mageCacheStorage?.cart?.summary_count // Shopware: los globals del storefront ctx.native.activeNavigationId
Si tu módulo es anterior
La variable existe igual:
source valdrá
"fallback" y el widget la habrá reconstruido con lo que tenía a mano
(su configuración más sus heurísticas de siempre). Tendrá menos campos, pero la misma forma:
tu código no necesita ramas.
Garantía: los nombres de estos campos son contrato estable —
añadimos campos nuevos, nunca renombramos ni eliminamos los existentes. Cuando el contrato cambie de forma,
subirá v.