Ir al contenido

Parallax Banner

Hero de ancho completo con una imagen de fondo, una capa gris para dar legibilidad, un título, un subtítulo y una lista de botones. Los botones son items independientes: cada uno tiene su propia etiqueta, URL, estilo y decisión de abrir en una pestaña nueva.

En el paneltipo en el JSONToken de la clave
Parallax BannerPARALLAX_BANNERparallax_banner

Este tipo usa el sobre genérico de los tipos generados: los campos editables viajan dentro de campos, no en propiedades con nombre propio.

{
tipo: 'PARALLAX_BANNER';
titulo: string | null; // título legacy; normalmente null, usá campos.parallaxBannerHeading
nombre_personalizado?: string; // nombre interno del panel (opcional)
items: Array<{
orden: number;
campos: {
buttonUrl: string | null; // destino del botón; null si no tiene URL
buttonLabel: string | null; // texto visible; null o vacío si no tiene etiqueta
buttonStyle: 'primary' | 'secondary' | null;
openInNewTab: 'true' | 'false' | null; // string, no boolean
};
}>;
campos: {
parallaxBannerImageUrl: string | null; // fondo; null si no hay asset READY
parallaxBannerImageMimeType: string | null; // "image/webp", "video/mp4", …
parallaxBannerImageDurationSeconds?: number; // solo videos READY con duración
parallaxBannerHeading: string | null; // el "Título" de la sección
parallaxBannerSubtitle: string | null; // el "Subtítulo"
};
estado: { lifecycle: string; storefrontVisible: boolean };
orden: number;
indice?: number; // solo cuando hay más de una sección del mismo tipo
}

items es la lista de botones, ordenada por orden. El panel permite hasta 6 botones por sección.

{
"parallax_banner-home-general-cmvig62ck0001f592tncqb4dk": {
"tipo": "PARALLAX_BANNER",
"titulo": null,
"items": [
{
"orden": 0,
"campos": {
"buttonUrl": "https://mitienda.com/nueva-coleccion",
"buttonLabel": "Ver colección",
"buttonStyle": "primary",
"openInNewTab": "false"
}
},
{
"orden": 1,
"campos": {
"buttonUrl": "https://mitienda.com/contacto",
"buttonLabel": "Contactanos",
"buttonStyle": "secondary",
"openInNewTab": "true"
}
}
],
"campos": {
"parallaxBannerImageUrl": "https://cdn.example.com/stores/xyz/media/hero.webp",
"parallaxBannerImageMimeType": "image/webp",
"parallaxBannerHeading": "Nueva colección",
"parallaxBannerSubtitle": "Descubrí lo nuevo de la temporada"
},
"estado": { "lifecycle": "active", "storefrontVisible": true },
"orden": 2
}
}

La regla de render y el orden son los compartidos. Lo propio de este tipo es pintar la imagen de fondo con el overlay y decidir el estilo de cada botón:

const res = await fetch(`https://sectionfy.codefy-apps.com/api/public/content/${TOKEN}/home-page`);
const { sections } = await res.json();
const banners = Object.entries(sections)
.filter(([, s]) => s.tipo === 'PARALLAX_BANNER')
.filter(([, s]) => s.estado.lifecycle === 'active' && s.estado.storefrontVisible)
.sort(([, a], [, b]) => a.orden - b.orden);
for (const [key, seccion] of banners) {
const botones = seccion.items
.slice()
.sort((a, b) => a.orden - b.orden)
.filter((item) => item.campos.buttonLabel)
.map((item) => {
const nuevaPestana = item.campos.openInNewTab === 'true';
const href = item.campos.buttonUrl ? ` href="${escapar(item.campos.buttonUrl)}"` : '';
const target = nuevaPestana ? ' target="_blank" rel="noopener noreferrer"' : '';
const estilo = item.campos.buttonStyle === 'secondary' ? 'secundario' : 'principal';
return `<a class="sectionfy-pb__btn sectionfy-pb__btn--${estilo}"${href}${target}>
${escapar(item.campos.buttonLabel)}
</a>`;
})
.join('');
const fondo = seccion.campos.parallaxBannerImageUrl
? ` style="background-image: url('${escapar(seccion.campos.parallaxBannerImageUrl)}')"`
: '';
contenedor.insertAdjacentHTML(
'beforeend',
`<section class="sectionfy-pb" data-block="${key}"${fondo}>
<div class="sectionfy-pb__overlay"></div>
<div class="sectionfy-pb__contenido">
${
seccion.campos.parallaxBannerHeading
? `<h2>${escapar(seccion.campos.parallaxBannerHeading)}</h2>`
: ''
}
${
seccion.campos.parallaxBannerSubtitle
? `<p>${escapar(seccion.campos.parallaxBannerSubtitle)}</p>`
: ''
}
<div class="sectionfy-pb__botones">${botones}</div>
</div>
</section>`,
);
}
  • Usá campos.parallaxBannerHeading, no titulo. El campo titulo es el título legacy del bloque y en este tipo normalmente viene en null; el texto que el comerciante carga como título vive en campos.parallaxBannerHeading.
  • La imagen puede ser imagen o video. Si parallaxBannerImageMimeType empieza con video/, no la pongas en un <img>: usá un <video muted playsinline> o background-image con el poster que corresponda. parallaxBannerImageDurationSeconds solo aparece para videos READY con duración registrada.
  • parallaxBannerImageUrl puede ser null. Renderizá un fondo sólido o descartá la sección; no rompas la página.
  • Los botones sin etiqueta no se muestran. Si buttonLabel es null o vacío, filtrá ese item. Si buttonUrl es null, podés mostrarlo como texto no interactivo o descartarlo; nunca generes un href="#" que parezca navegar.
  • openInNewTab es un string, no un boolean: 'true' abre en pestaña nueva; cualquier otro valor se trata como la misma pestaña. Cuando abre en pestaña nueva, usá rel="noopener noreferrer".
  • buttonStyle distingue primary (fondo sólido) de secondary (contorno). Si viene null, usá el estilo primario como fallback.
  • Máximo 6 botones. El panel bloquea el séptimo; no asumas más de seis items.