Guía de implementación · 2024

Blog que
convierte.

Instala el sistema CRO para blogs de Shopify en menos de 10 minutos, con Claude Code.

3pasos
10minstalación
0código manual

4 elementos que hacen
que el blog venda.

Panel sticky con producto

El artículo vende mientras el lector lee. El panel se mantiene visible durante todo el scroll.

Botón de WhatsApp directo

Compra con un clic sin salir del blog. Mensaje pre-armado con producto, precio y link.

Add to Cart integrado

Convierte sin redirecciones. Estados idle → loading → success con feedback visual.

Carruseles de productos

Upsell visual al final del artículo. Dos instancias reutilizando la sección existente.

1

Descarga el tema de tu tienda

Tienes dos opciones según tu flujo de trabajo

Opción A — Panel de Shopify (más fácil)
  1. Entra a tu panel de Shopify → Online StoreThemes
  2. En tu tema activo, haz clic en ··· (tres puntos) → Edit code
  3. Haz clic en ActionsDownload theme file (.zip)
  4. Descomprime el .zip en una carpeta de tu computador
Opción B — Shopify CLI (recomendado para Claude Code)
shopify theme pull # descarga el tema activo a la carpeta actual

Ejecuta este comando dentro de la carpeta donde quieres trabajar el tema.

💡 Consejo: Si usas el CLI (Opción B), ya quedas conectado al store y en el Paso 3 solo necesitas un comando para publicar. Con la Opción A deberás subir el .zip manualmente desde el panel.
2

Corre el prompt en Claude Code

Abre la terminal en la carpeta del tema y ejecuta Claude Code

cd ruta/a/tu/tema # navega hasta la carpeta del tema descargado claude # inicia Claude Code en esa carpeta

Una vez dentro de Claude Code, ve a la sección de abajo, copia el prompt completo y pégalo directamente en la terminal de Claude Code.

3

Revisa y sube el tema

Claude Code nunca hace push automáticamente — siempre revisas tú primero

Con Shopify CLI
shopify theme push --theme [ID-del-tema]

Sube los cambios al tema que especifiques con su ID numérico.

Sin CLI — Manual
  1. Comprime la carpeta del tema en .zip
  2. Ve a Online Store → Themes
  3. Add theme → Upload zip file
  4. Actívalo cuando estés listo

Nada que tocar.
Todo automatizado.

Analizarel tema existente y detectar el stack: Liquid, React islands, esbuild, variables CSS del design system
Crearsections/blog-cro-hero.liquid — encabezado con breadcrumb, badge de categoría, título, meta row e imagen
Crearsections/blog-cro-body.liquid — layout 2 columnas con data bridge para React
Crearassets/components/BlogCroPanel.jsx — panel sticky con WhatsApp CTA y Add to Cart
Actualizarassets/main.jsx — solo añade el import y el registro del componente, sin tocar nada más
Actualizartemplates/article.json — agrega las 4 secciones en el orden correcto
Generarestilos BEM en assets/main.css adaptados al design system sin romper los estilos existentes

Cópialo completo y
pégalo en Claude Code.

Copia todo el bloque de abajo con el botón. Asegúrate de estar dentro de la carpeta raíz del tema antes de pegar.

Prompt → Claude Code
Blog-CRO Article Page — Shopify + React Islands

Stack técnico
- Base: Shopify Theme (Online Store 2.0), Liquid — sections, templates, schema con bloques/settings
- UI dinámica: React 18 montado tipo "islands" con data-react-component="ComponentName" en el div raíz de cada sección
- Build: esbuild (npm run build) → assets/main.jsx → assets/main.js
- Estilos: CSS tradicional en assets/main.css con naming BEM. Adapta los estilos al design system existente del proyecto (variables --color-primary, --color-text, --color-bg-alt, --font-heading, --font-body, --radius-card, etc.)
- Para datos complejos (producto), usa el patrón ya establecido: <script id="blog-cro-data-{{ section.id }}" type="application/json">{ ... }</script> y lee con JSON.parse(document.getElementById(id).textContent) dentro del componente React
- Bilingual: usa el hook assets/components/hooks/useLanguage.jsx y campos _en en el schema, igual que el resto del tema

Estructura general de la página

Template: templates/article.json

Secciones en orden:
1. header (existente, ya registrado)
2. blog-cro-hero — encabezado del artículo
3. blog-cro-body — layout 2 columnas: artículo izquierda + panel sticky derecha
4. collection-carousel — primer carrusel de productos (existente, reutilizar)
5. collection-carousel — segundo carrusel (segunda instancia, misma sección)
6. footer (existente)

SECCIÓN 1 — Blog CRO Hero (sections/blog-cro-hero.liquid)

Sección Liquid pura (sin React). Usa directamente el objeto article de Shopify.

Estructura visual (de arriba a abajo):
- Breadcrumb — texto pequeño: "Blog / {article.title}" con links. Tipografía body 12px, color secondary.
- Category badge — pill/chip con el tag principal del artículo (primer tag que no sea "featured"). Background --color-bg-alt, texto uppercase pequeño, border-radius pill.
- Título — h1 con article.title. Tipografía heading, clamp(32px, 4vw, 56px), weight 900, line-height 1.0, letra tight. Máximo 3 líneas.
- Meta row — fila horizontal: avatar del autor (si existe article.author) + nombre del autor + fecha formateada + separador "·" + tiempo estimado de lectura (calcula palabras / 200, mínimo "1 min read"). Tipografía body 13px, color secondary.
- Imagen destacada — article.image a ancho completo, aspect-ratio 16/9, object-fit cover, border-radius --radius-card. Si no hay imagen, no renderizar el elemento (no placeholder vacío).

Schema settings:
- show_breadcrumb checkbox (default true)
- show_read_time checkbox (default true)
- read_time_label text / read_time_label_en text
- author_label text "Por" / author_label_en text "By"

SECCIÓN 2 — Body + Panel Sticky (sections/blog-cro-body.liquid)

Layout 2 columnas. Columna izquierda: Liquid puro. Columna derecha: React BlogCroPanel.

CSS del layout:
.blog-cro-layout { display: flex; gap: 60px; align-items: flex-start; max-width: var(--max-width); margin: 0 auto; padding: 60px var(--padding-x); }
.blog-cro-article { flex: 0 0 60%; min-width: 0; }
.blog-cro-panel-col { flex: 0 0 calc(40% - 60px); }

Columna izquierda — Contenido del artículo (Liquid):
Renderiza {{ article.content }} directamente en .blog-cro-article__content. Estilos tipográficos:
- p, li: font-size 16px, line-height 1.7, color --color-text-secondary
- h2, h3, h4: font-family heading, weight 800, color --color-text, margin-top 32px
- img: max-width 100%, border-radius --radius-card, display block
- a: color --color-primary, text-decoration underline
- blockquote: border-left 3px solid --color-primary, padding-left 20px, font-style italic
- strong: font-weight 700, color --color-text

Columna derecha — Data bridge en Liquid:
{%- assign panel_product = section.settings.panel_product -%}
{%- assign panel_variant = panel_product.selected_or_first_available_variant -%}
Script con id="blog-cro-panel-{{ section.id }}" type="application/json" conteniendo: product, selectedVariant, shopCurrencySymbol, whatsappPhone, whatsappMessageTemplate, whatsappMessageTemplateEn, ctaLabel, ctaLabelEn, atcLabel, atcLabelEn, panelTitle, panelTitleEn.
Div con data-react-component="BlogCroPanel" y data-panel-id="blog-cro-panel-{{ section.id }}".

COMPONENTE React — BlogCroPanel (assets/components/BlogCroPanel.jsx)

Lee el JSON con JSON.parse(document.getElementById(panelId).textContent).
El panel tiene position: sticky; top: 120px. Fondo blanco, border: 1px solid var(--color-border), border-radius: var(--radius-card), padding 24px.

Estructura interna (de arriba a abajo):
1. Panel header (solo si panelTitle está definido): texto pequeño uppercase bold, color secondary.
2. Product image: selectedVariant.featured_image.src o product.featured_image. aspect-ratio 4/5, object-fit cover, border-radius --radius-card. Hover: transform: scale(1.03), transition 0.3s ease.
3. Product info: product.title (heading 18px weight 800). Precio: currencySymbol + (price/100).toFixed(2). Si compare_at_price > price: precio original tachado + precio actual destacado.
4. WhatsApp CTA: full-width, fondo #25D366, texto blanco, height 50px. Icono SVG de WhatsApp inline. Construye URL con wa.me usando el template: "Hola! Quiero pedir: {product} — {price}. Link: {url}". Limpia el teléfono con .replace(/\D/g,''). Hover: filter brightness(1.08).
5. Add to Cart: full-width, fondo --color-text, texto blanco, height 48px. Estados: idle → loading (spinner) → success ("¡Agregado!") → idle (1.5s). fetch('/cart/add.json'). En success: document.dispatchEvent(new CustomEvent('dissent:cart-updated')).
6. Product link: "Ver producto →" centrado, 12px, color secondary, text-decoration underline.

SECCIONES 4 y 5 — Colecciones

No crear código nuevo. Solo añadir al article.json:
"collection-1": { "type": "collection-carousel", "settings": { "heading": "Productos en este artículo", "view_all_label": "Ver todo" } }
"collection-2": { "type": "collection-carousel", "settings": { "heading": "También te puede gustar", "view_all_label": "Ver todo" } }

Schema settings de blog-cro-body.liquid:
- panel_product: product picker
- panel_title / panel_title_en: text
- whatsapp_phone: text (número sin +, ej: "573001234567")
- whatsapp_message / whatsapp_message_en: textarea (placeholders: {product} {variant} {price} {url})
- cta_label default "Comprar por WhatsApp" / cta_label_en default "Buy on WhatsApp"
- atc_label default "Agregar al Carrito" / atc_label_en default "Add to Cart"

COMPORTAMIENTOS Y MICRO-ANIMACIONES
- Panel: position sticky top 120px en desktop. En mobile: position static.
- WhatsApp hover: filter brightness(1.08), transition 0.2s ease.
- ATC success: animación scale(0.97) → scale(1).
- Imagen hover: transform scale(1.03), overflow hidden en wrapper.

RESPONSIVE (Mobile ≤809px)
.blog-cro-layout { flex-direction: column; padding: 32px var(--padding-x-mobile); gap: 40px; }
.blog-cro-article, .blog-cro-panel-col { flex: none; width: 100%; }
.blog-cro-panel { position: static; }
El panel aparece debajo del artículo completo en mobile.

NOTAS IMPORTANTES
1. Reutilizar — no recrear: CollectionCarousel, useLanguage, useInView ya existen. No crear versiones nuevas.
2. Solo tocar main.jsx: añadir import BlogCroPanel from './components/BlogCroPanel.jsx' y registrar BlogCroPanel en el objeto REGISTRY.
3. article.content se renderiza con Liquid — no pasarlo a React.
4. El panel no tiene selector de variante — usa selected_or_first_available_variant directamente.
5. Limpiar el teléfono con .replace(/\D/g,'') antes de construir el wa.me URL.
6. @media (prefers-reduced-motion: reduce): desactivar todas las transitions y animations.

¿Necesitas que lo
implementemos por ti?

Cotizamos la instalación completa y te lo dejamos funcionando.

Hablar con Digit Deck →