Findalo

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.