Tu primera llamada
Necesitas dos cosas: el token y el ID de un producto de la
tienda. El ID de producto es el mismo que usa Tiendanube y está disponible en el
template del tema como {{ product.id }}.
1. Traer el contenido
Sección titulada «1. Traer el contenido»curl https://sectionfy.codefy-apps.com/api/public/content/ndp_pub_a3f9k2mX7pLqR2wN/product/333333174Tres piezas en esa URL:
| Segmento | Valor | Qué es |
|---|---|---|
{token} | ndp_pub_a3f9k2mX7pLqR2wN | La tienda. |
{page} | product | El tipo de página. |
{targetId} | 333333174 | El producto concreto. |
Ten en cuenta el vocabulario de {page}: cambia según lleve o no
{targetId}. Con target se usa product / category; sin target se usa
product-page / category-page / home-page. Es el error más común y no hay
fallback: si los mezclas, la API responde 400. Está detallado en
endpoints.
2. Lo mismo desde el tema
Sección titulada «2. Lo mismo desde el tema»const TOKEN = window.SECTIONFY_TOKEN;const API = 'https://sectionfy.codefy-apps.com/api/public/content';
const res = await fetch(`${API}/${TOKEN}/product/333333174`);if (!res.ok) throw new Error(`Sectionfy ${res.status}`);const bundle = await res.json();No hace falta pasar headers, ni credentials: es un GET simple.
3. Lo que vuelve
Sección titulada «3. Lo que vuelve»{ "page": "product", "product_id": "333333174", "sections": { "faq-product-333333174-cmqic4kt5000ieq2bk3hbiat3": { "titulo": "Preguntas frecuentes", "items": [ { "pregunta": "¿Hacen envíos a todo el país?", "respuesta": "Sí, con despacho en 24 a 72 horas hábiles.", "orden": 0 } ], "estado": { "lifecycle": "active", "storefrontVisible": true }, "orden": 0 } }}sections es un objeto, no un array. Cada clave codifica cuatro cosas
separadas por guiones:
faq-product-333333174-cmqic4kt5000ieq2bk3hbiat3└┬┘ └──┬──┘ └───┬───┘ └───────────┬────────────┘ │ │ │ └─ blockId: identidad estable de esta sección │ │ └─ targetId: el producto (o el literal `general` si no aplica) │ └─ placement: la página └─ kind: el tipo de sección4. Sacar las secciones de un tipo
Sección titulada «4. Sacar las secciones de un tipo»Cada sección trae además un campo tipo con su identificador, así que quedarte
con todos los FAQ son tres pasos: filtrar por tipo, aplicar la regla de render, y
ordenar.
const faqs = Object.entries(bundle.sections) // 1. El tipo que buscas, en MAYUSCULAS. .filter(([, s]) => s.tipo === 'FAQ') // 2. Regla de render: el bundle trae secciones ocultas y archivadas. .filter(([, s]) => s.estado.lifecycle === 'active' && s.estado.storefrontVisible) // 3. El comerciante define el orden arrastrando en el panel. .sort(([, a], [, b]) => a.orden - b.orden) .map(([key, seccion]) => ({ key, ...seccion }));Esos tres pasos son iguales para todos los tipos, así que conviene envolverlos en
un helper. En el resto de la documentación aparece como
seccionesDeTipo(bundle, kind) y está escrito en
el módulo cliente.
5. Renderizar
Sección titulada «5. Renderizar»for (const faq of faqs) { const detalles = faq.items .slice() .sort((a, b) => a.orden - b.orden) .map( (item) => ` <details> <summary>${item.pregunta}</summary> <p>${item.respuesta}</p> </details> `, ) .join('');
contenedor.insertAdjacentHTML( 'beforeend', ` <section> ${faq.titulo ? `<h2>${faq.titulo}</h2>` : ''} ${detalles} </section> `, );}Eso es todo el ciclo. El resto de la documentación es detalle: qué otros endpoints hay, qué shape tiene cada tipo de sección, y cómo cachear bien.
Siguiente paso
Sección titulada «Siguiente paso»El modelo mental — cuatro ideas que explican casi todas las decisiones de esta API.
