Saltar al contenido

Read in English

Guía para desarrolladores

Fik Satellites muestra los productos de una tienda online en cualquier web: rejillas de productos, carruseles, productos sueltos y botones de compra, con carrito y el checkout propio de la tienda. Esta página es para quien construye o mantiene la web. El dueño de la tienda crea los widgets y te envía el código para pegar: no necesitas ninguna cuenta.

Tu código

El dueño de la tienda te envía un código como este, listo para pegar. Sus comentarios numeran las partes:

<!-- Widgets de productos. Guía para desarrolladores: https://app.fiksatellites.com/es/docs -->

<!-- 1. Una vez por página, en la cabecera o el pie de la web (sáltalo si ya está) -->
<script src="https://cdn.fiksatellites.com/v1/sfw.js" defer data-shop="example-store" data-storefront="example-website"></script>

<!-- 2. Opcional: el icono del carrito, p. ej. en el menú de cabecera. Sin él, aparece un botón
     de carrito flotante en cuanto hay algo dentro. Para usarlo, saca esta línea del comentario:
     <div data-sfw-widget="cart"></div>
-->

<!-- 3. Donde deben aparecer estos productos -->
<div data-sfw-widget="scroller" data-collection="512295272597" data-id="home-new-releases"></div>
  1. El script va una vez en cada página que muestra widgets, idealmente en la cabecera o el pie comunes de la web. Es la misma línea en todos los códigos de esta web, así que si ya está en la página, sáltala.
  2. El icono del carrito es opcional. Pon la línea <div data-sfw-widget="cart"></div> donde deba ir el icono, normalmente en la cabecera común, fuera del comentario. Sin ella, aparece un botón de carrito flotante en la esquina inferior derecha en cuanto hay algo en el carrito.
  3. El widget va justo donde deben aparecer los productos. Pégalo tal cual: ya indica qué productos mostrar, con qué diseño, y da nombre a esta ubicación para los informes de ventas de la tienda.

Todo lo demás (colores, esquinas, tipografía, idioma, mercado) sale de la configuración de widgets del dueño de la tienda, que puede cambiarla más adelante sin tocar la web.

Los widgets nunca rompen la página. Si algo está mal configurado o un servicio no responde, se quedan invisibles y dejan un aviso [sfw] en la consola del navegador. Consulta Solución de problemas.

Dónde pegarlo

Las líneas del carrito y del widget son div normales, que la mayoría de editores respetan. El script necesita un sitio que admita scripts: normalmente un ajuste de cabecera o pie para toda la web; si no, un bloque HTML en la misma página.

Plataforma1. Script (una vez por web)2–3. Icono del carrito y widgets
WordPressEn la cabecera o el pie del tema, o con un plugin como WPCode (“Header & Footer”). Temas de bloques: Editor del sitio → un bloque HTML personalizado en la parte de plantilla de la cabecera.Editor de bloques: un bloque “HTML personalizado”. Editor clásico: la pestaña “Texto”. Elementor: el widget “HTML”. Divi y WPBakery: su módulo “Código”.
JoomlaUn módulo “Personalizado” en una posición de cabecera o pie, con el editor en “Ninguno”. Si se elimina el script, permítelo en Configuración global → Filtros de texto para ese grupo de usuarios.Un módulo “Personalizado”, o un artículo con el editor en “Ninguno”.
DrupalEl html.html.twig o una librería del tema, o un módulo como Asset Injector.El campo de cuerpo con el formato de texto “HTML completo” (o uno que permita div con atributos data-).
WebflowSite settings → Custom code → Footer code (requiere un plan de sitio de pago).Un elemento “Code Embed”.
SquarespaceInserción de código → Pie de página (plan Core o superior). Cuentas nuevas: Sitio web → Herramientas del sitio web → Inserción de código; antiguas: Configuración → Avanzado.Un bloque “Código”, en modo HTML.
WixConfiguración → Código personalizado → añadir a todas las páginas, al final del Body (requiere un plan premium con dominio conectado).Limitado: Wix coloca los elementos “Insertar HTML” en un marco aislado, así que un widget ahí no puede usar el carrito de la página. Pon el script y el widget en el mismo elemento; ese widget tendrá su propio carrito y botón de pago dentro del marco.
GhostSettings → Code injection → Site footer.Una tarjeta “HTML”.
HubSpot CMSConfiguración → Contenido → Páginas → Plantillas → HTML del pie del sitio.Un módulo “HTML personalizado”, o la vista de código fuente del editor de texto enriquecido.
Sitio a medida (React, Vue, Next.js, HTML estático…)Carga el script una vez, p. ej. en el layout raíz o la plantilla de página, con defer (Next.js: strategy “afterInteractive”).Renderiza el div del widget tal cual (en JSX, sin los comentarios HTML). Los widgets añadidos más tarde, por navegación en cliente o AJAX, se detectan solos. Ver “React y otros frameworks” más abajo.

Plugins de caché y optimización (WP Rocket, Autoptimize, LiteSpeed, Cloudflare Rocket Loader…) a veces combinan o retrasan scripts. Si los widgets no aparecen, excluye /v1/sfw.js de la combinación y el retraso, o añade data-cfasync="false" a la etiqueta del script para Rocket Loader.

React y otros frameworks

  • Carga el script desde el documento HTML o el layout raíz, no desde un componente: las etiquetas script que renderiza React no se ejecutan. Con renderizado en servidor, cárgalo después de la hidratación (Next.js: <Script strategy="afterInteractive">); si no, los widgets modifican su contenedor antes de que React hidrate y React avisa de una discrepancia.
  • En JSX, quita los comentarios HTML y renderiza el div del widget tal cual. Los widgets añadidos más tarde (navegación en cliente, AJAX) se detectan solos.
  • Cada contenedor se monta una sola vez. Si una ruta reutiliza el mismo div para otro código, dale una key de React para que se cree uno nuevo.
  • Los contenedores dentro de tu propio Shadow DOM no se detectan solos: llama a SFW.mount(shadowRoot).

Más widgets

Cada widget lo crea el dueño de la tienda, con vista previa: una rejilla de productos, un carrusel, una fila deslizable, un producto suelto o solo un botón de compra. ¿Necesitas otro diseño, otros productos o el mismo widget en otro sitio? Pide un código nuevo a quien te dio este: cada ubicación tiene el suyo, para que la tienda vea cuáles venden. Puede haber varios widgets en una página; el script sigue yendo una sola vez.

Los productos con opciones (talla, color…) abren una ventana con galería, selector de variante y cantidad. Solo se muestran los productos que la tienda ha puesto a disposición de esta web.

Carrito

  • La línea del carrito de la parte 2 muestra el icono con el número de artículos. Ponla en la cabecera común y carga el script en todas las páginas, para que el icono funcione en toda la web. Al pulsarlo, el carrito se abre como un panel sobre la página.
  • Añadir un producto abre el carrito. Sin la línea del carrito, aparece un botón flotante en cuanto hay algo dentro.
  • El carrito se guarda en el navegador del visitante por dominio (localStorage, sin cookies), sobrevive a las recargas y se sincroniza entre pestañas. www. y el dominio sin www tienen carritos distintos.
  • El checkout se abre en la misma pestaña, a pantalla completa aunque la web esté en un iframe, en el checkout de la tienda.
  • Un botón propio puede abrirlo: window.SFW?.openCart() (SFW existe cuando el script diferido se ha ejecutado).

Idioma y mercado

  • El idioma sigue el <html lang="…"> de la página cuando los widgets lo admiten (hoy español e inglés): textos de botones y carrito, formato de precios, traducciones de productos de la tienda e idioma del checkout. Las webs bilingües ya suelen indicarlo en cada página. lang="es" sin región usa el país de la tienda para el formato de precios. Con otros idiomas se usa el idioma predeterminado del dueño de la tienda.
  • Para forzar un idioma en una página, añade data-locale="es-ES" (u otro locale es-… / en-…) a la etiqueta del script.
  • El mercado (precios, moneda, disponibilidad) lo define el dueño de la tienda. Un carrito tiene una sola moneda, así que es la misma en todas las páginas de la web.

Estilos

Los widgets se pintan dentro de un Shadow DOM, así que el CSS de la web no puede romperlos por accidente y su CSS no se filtra a la web. Heredan la tipografía de la web salvo que el dueño de la tienda elija una. El dueño define color de acento, esquinas y tipografía; tú puedes sobrescribirlos con propiedades CSS personalizadas en el contenedor del widget o en cualquier ancestro. La ventana de producto y el carrito flotante van al final de <body>, así que define sus colores y tipografía en :root o body.

/* Whole site, including the product popup and floating cart */
:root {
  --sfw-accent: #ec98ca;
  --sfw-radius: 8px;
}

/* One placement */
.home [data-sfw-widget] {
  --sfw-image-ratio: 4 / 5;
}
PropiedadPor defectoControla
--sfw-accent#0b0b0b *Botones, contador del carrito, destacados
--sfw-accent-hover#333333Botón al pasar el ratón
--sfw-button-text#ffffffTexto de los botones de acento
--sfw-text#111111Texto
--sfw-muted#6b6b6bTexto secundario, precios tachados
--sfw-bg#ffffffFondo de la ventana de producto y del carrito
--sfw-fontinherit *Tipografía
--sfw-radius0px *Esquinas de imágenes, botones y carrito
--sfw-gap20pxEspacio entre tarjetas
--sfw-columns4Columnas cuando el widget mide más de 900px
--sfw-columns-tablet3Columnas entre 600 y 900px (tablets, columnas laterales); 2 por debajo de 600px
--sfw-card-width-mobile70%Ancho de tarjeta en las filas deslizables del móvil
--sfw-card-max-width320pxAncho de la tarjeta de producto individual
--sfw-image-ratio1 / 1Proporción de las imágenes de producto

* O el ajuste del dueño de la tienda. Si un código ya fija un número de columnas, manda sobre --sfw-columns: pide un código nuevo para cambiarlo.

Para todo lo demás, da estilo a las partes expuestas con ::part():

sfw-grid::part(card-title),
sfw-scroller::part(card-title) {
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

sfw-product-modal::part(modal) {
  border-radius: 12px;
}

/* Move the floating cart button above a chat or cookie button */
sfw-cart[floating] {
  bottom: 96px;
}
ElementoPartes
sfw-grid, sfw-carousel, sfw-scroller, sfw-collectioncontainer, heading, track, nav, card, card-media, badge, card-title, price, button, load-more
sfw-productcard, card-media, badge, card-title, price, button
sfw-buy-buttonbutton
sfw-cartcart-toggle, cart-count, cart, cart-lines, cart-footer, checkout, button, toast
sfw-product-modal (la ventana de producto)modal, modal-title, price, quantity, button, description
— (cualquier widget, en modo depuración)error

JavaScript y eventos

LlamadaQué hace
SFW.openCart()Abre el carrito, p. ej. desde el enlace de carrito de la propia web.
SFW.consent(true | false)Informa a los widgets del consentimiento de analítica. Ver más abajo.
SFW.mount(root)Monta los contenedores dentro de root, p. ej. el shadow root de tu componente. Rara vez hace falta.

Los widgets emiten eventos en window, para que la web alimente su propia analítica. Cada event.detail tiene storefront (el ID del sitio), widget_id e items (formato GA4). view_item, add_to_cart, view_cart y begin_checkout añaden value y currency; view_item_list y select_item, item_list_name. Los eventos se emiten con o sin consentimiento del visitante: compruébalo antes de enviarlos a tus propias herramientas.

window.addEventListener("sfw:add_to_cart", (event) => {
  console.log(event.detail.widget_id, event.detail.items);
});

Eventos: sfw:view_item_list, sfw:select_item, sfw:view_item, sfw:add_to_cart, sfw:view_cart, sfw:begin_checkout.

Analítica y consentimiento

  • Cada pedido registra de qué web, widget y página vino, y aparece en los pedidos de la tienda etiquetado con la web. El enlace al checkout lleva utm_source (la web), utm_medium=storefront_widget y utm_campaign (el último widget usado).
  • Si el dueño de la tienda configuró Google Analytics 4, los widgets envían eventos de ecommerce de GA4, y la propiedad de la tienda también recibe un page_view de tus páginas. Si la página ya tiene gtag, lo usan; si no, lo cargan con el consentimiento denegado por defecto (Consent Mode v2). Antes del consentimiento, Google recibe pings sin cookies; si tu política prohíbe cualquier petición a Google antes del consentimiento, avisa al dueño de la tienda.
  • Los banners de cookies compatibles con Google Consent Mode no necesitan nada más. Si no, llama a SFW.consent(true) cuando el visitante acepte la analítica y SFW.consent(false) si la retira. También actualiza analytics_storage en el gtag de la página, así que llámalo solo desde tu banner de consentimiento.
  • Una fuente de Google elegida por el dueño de la tienda se carga desde fonts.googleapis.com.

Rendimiento y compatibilidad

  • El script pesa unos 17 KB comprimido, se carga con defer y lo sirve una CDN. Los widgets se pintan cuando la página ha cargado y piden los productos en directo; las imágenes se cargan en diferido, así que no uses un widget como imagen principal (LCP).
  • El contenedor está vacío hasta que se pinta el widget. Para evitar saltos de diseño, dale un min-height. Si el widget falla, ese espacio queda vacío.
  • Chrome, Edge, Firefox y Safari actuales (iOS y macOS 16+). En pantallas táctiles, los botones miden al menos 44px. Botones y ventanas son nativos y con etiqueta; las ventanas retienen el foco y se cierran con Esc. Las animaciones respetan la preferencia de movimiento reducido y la reproducción automática se pausa al pasar el ratón, enfocar o tocar.

Solución de problemas

  • No aparece nada. Añade ?sfw-debug=1 a la URL de la página: cada widget muestra por qué está oculto y la consola registra mensajes [sfw]. Causas habituales: una errata en data-shop o data-storefront (editados a mano), los widgets se han desactivado para esta tienda, o la tienda no ha puesto esos productos a disposición de esta web. Envía el mensaje de la consola al dueño de la tienda.
  • No se ven los cambios del dueño de la tienda. Los ajustes tardan unos minutos (hasta unos 10) en llegar a las webs. Productos y precios siempre están al día.
  • Content Security Policy. Si la web envía una cabecera CSP, permite lo siguiente. Las entradas de Google solo hacen falta con GA4; las de fuentes, si el dueño de la tienda eligió una fuente de Google; frame-src, solo para vídeos en las descripciones de producto.
script-src  https://cdn.fiksatellites.com https://www.googletagmanager.com
connect-src https://cdn.fiksatellites.com https://*.myshopify.com https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com
img-src     https://cdn.shopify.com https://*.google-analytics.com https://*.googletagmanager.com
style-src   'unsafe-inline' https://fonts.googleapis.com
font-src    https://fonts.gstatic.com
frame-src   https://www.youtube.com https://www.youtube-nocookie.com
  • Dos copias del script no causan problemas: la segunda no hace nada. Si son distintas, se usa la primera etiqueta de la página.