Menús y contenido
Arma la navegación y las páginas de contenido de tu tienda headless.
Vas a armar la base de una tienda de Lima: el menú del encabezado, la categoría «Polos» y la página «Envíos». Todo con Storefront API, sin token.
Requisitos
- El slug o un dominio de la tienda, para
x-Store-Domain. Ver Tienda headless. - Categorías y páginas publicadas en la tienda.
Lee la configuración
GET / trae en una llamada la tienda, su marca, su SEO, sus páginas
publicadas (cms.pages) y sus menús activos (cms.menus). Pídela una vez por
petición y reutilízala. GET / trae solo cms.settings.
curl https://storefront.ecomiq.pe/v1/settings \
-H "x-Store-Domain: mi-tienda"{
"store": { "name": "Mi tienda", "currency": "PEN", "visibility": "public" },
"cms": {
"settings": {
"branding": { "logoUrl": "https://…/logo.webp" },
"seo": { "siteName": "Mi tienda", "robotsIndex": true },
"contact": { "whatsapp": "+51987654321" }
}
}
}Los pasos siguientes reutilizan API y headers.
- Con
visibility: "private", la tienda pide contraseña. Ver Abre una tienda privada. - Con
robotsIndex: false, bloquea todo el sitio enrobots.txt.
Pinta el menú
Los menús llegan en cms.menus y en GET /. Para uno solo, usa
GET /. Una tienda nueva trae main, footer y account.
curl https://storefront.ecomiq.pe/v1/menus/main \
-H "x-Store-Domain: mi-tienda"{
"key": "main",
"name": "Menú principal",
"items": [
{
"label": "Polos",
"url": "/categories/polos",
"reference": { "type": "category", "id": "7204558912004327982" },
"order": 1,
"visible": true,
"children": []
}
]
}- Los ítems llegan tal como se guardaron. Omite los que tienen
visible: falsey ordena pororder, también enchildren. - Los enlaces a productos y categorías llegan con su URL actual, aunque el
comercio la cambie.
referencedice a cuál apuntan.
Muestra una categoría
GET / trae la categoría con su SEO, sus migas de pan y
sus subcategorías. Luego pide sus productos con categoryId, como en
Tienda headless.
curl https://storefront.ecomiq.pe/v1/categories/polos \
-H "x-Store-Domain: mi-tienda"
curl "https://storefront.ecomiq.pe/v1/products?categoryId=7204558912004327982" \
-H "x-Store-Domain: mi-tienda"{
"id": "7204558912004327982",
"name": "Polos",
"url": "/categories/polos",
"metaTitle": "Polos de algodón pima",
"productCount": 24,
"ancestors": [
{
"id": "7204558912004329210",
"name": "Hombre",
"url": "/categories/hombre"
}
],
"children": []
}ancestorsva de la raíz al padre.categoryIdexcluye las subcategorías.GET /trae todas en una lista plana, ordenada porv1/ categories order. Arma el árbol conparentId.GET /lista las marcas.v1/ brands GET /lista las colecciones. Para una, usav1/ collections GET /yv1/ collections/ {slug} collectionId. Sinsort, los productos siguen el orden que eligió el comercio.
Muestra páginas y artículos
GET / trae la versión publicada de una página. Todas llegan
también en cms.pages.
curl https://storefront.ecomiq.pe/v1/pages/envios \
-H "x-Store-Domain: mi-tienda"{
"name": "Envíos",
"slug": "envios",
"layout": "content",
"settings": {
"title": "Envíos",
"html": "<p>Entregamos en Lima en 24 a 48 horas.</p>",
"seo": { "title": "Envíos", "description": "Tiempos y costos de envío." }
},
"sections": []
}- Con
layout: "content", el texto viene ensettings:title,htmlyseo. La portada tiene el slughomey traesectionscon susblocks. htmllo escribe el comercio. Sanéalo antes de insertarlo.
Para el blog, GET / lista los artículos publicados, del más
reciente al más antiguo. GET / trae uno con su body en
HTML, que también debes sanear.
curl "https://storefront.ecomiq.pe/v1/articles?tag=pima&limit=12" \
-H "x-Store-Domain: mi-tienda"Filtra con folder o tag, por valor exacto, o con search, que busca en el
título y el resumen. limit va de 1 a 100 y vale 24; no hay más páginas.
Agrega el buscador
GET / sugiere productos mientras el comprador escribe.
Envía search, de 2 a 80 caracteres, y limit, de 1 a 20.
curl "https://storefront.ecomiq.pe/v1/search/autocomplete?search=polo&limit=6" \
-H "x-Store-Domain: mi-tienda"[
{
"name": "Polo pima azul",
"url": "/products/polo-pima-azul",
"imageUrl": "https://…/polo.webp"
}
]Para la página de resultados, usa GET /.
Resuelve una URL
Antes de pintar una ruta, revisa si el comercio la redirigió.
curl "https://storefront.ecomiq.pe/v1/redirects/resolve?path=/ofertas" \
-H "x-Store-Domain: mi-tienda"{
"redirect": {
"location": "/categories/polos",
"statusCode": 301,
"preserveQuery": true
}
}Responde con statusCode y location. Con preserveQuery: true, agrega la
query de la petición. Sin redirección, redirect es null. La ruta debe
coincidir exacta, mayúsculas incluidas; solo se ignora la / final.
Luego, en tu ruta comodín, pregunta qué hay en esa ruta. Envía solo la ruta, sin dominio ni query.
curl "https://storefront.ecomiq.pe/v1/urls/resolve?path=/categories/polos" \
-H "x-Store-Domain: mi-tienda"{
"kind": "category",
"url": "/categories/polos",
"handle": "polos",
"product": null,
"category": { "id": "7204558912004327982", "name": "Polos" }
}productocategory: pinta la ficha o la categoría con el objeto que llega.redirect: responde301aurl. Pasa con URLs viejas, en mayúsculas o con/al final.- Solo resuelve productos y categorías. Si nada coincide:
404Url.NotFound.
Si guardas enlaces a productos o categorías en tu propio contenido,
POST / los devuelve con su URL actual y su reference, en el
mismo orden. Acepta hasta 100, conserva la query y deja igual los externos.
curl -X POST https://storefront.ecomiq.pe/v1/urls/links \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-d '{ "links": [{ "url": "/products/polo-azul?talla=m" }] }'Publica el sitemap
GET / lista las URL canónicas de productos visibles, categorías y
colecciones. Cada página trae hasta 1000 productos; la primera suma las
categorías y las colecciones.
curl "https://storefront.ecomiq.pe/v1/sitemap?page=1" \
-H "x-Store-Domain: mi-tienda"{
"items": [{ "url": "/categories/polos", "updatedOn": null }],
"nextPage": 2,
"totalPages": 3
}Las URL son rutas: antepón el dominio de tu tienda. No incluye la portada, las
páginas ni el blog; agrégalos desde cms.pages y GET /. Si
totalPages es mayor que 1, publica un índice con un sitemap por página.
Muestra las tiendas físicas
GET / lista las tiendas físicas activas, por nombre. Filtra
con search por nombre o ciudad. Trae 20 por defecto; usa limit y cursor
para pedir más. En un marketplace trae las de la tienda principal; las de un
vendedor salen con sellerId. GET / trae una.
curl "https://storefront.ecomiq.pe/v1/store-locations?search=Miraflores" \
-H "x-Store-Domain: mi-tienda"{
"data": [
{
"name": "Tienda Miraflores",
"address": "Av. Larco 1234",
"city": "Lima",
"schedules": [
{
"dayOfWeek": "monday",
"openTime": "10:00:00",
"closeTime": "21:00:00"
}
]
}
],
"hasNextPage": false,
"nextCursor": null
}Abre una tienda privada
Una tienda con visibility: "private" responde 401 con Common.Unauthorized
en todas las llamadas, salvo / y /. Pide la
contraseña al visitante y envíala desde tu servidor.
curl -X POST https://storefront.ecomiq.pe/v1/access/unlock \
-H "x-Store-Domain: mi-tienda" \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{ "accessKey": "<contraseña>" }'Responde { "unlocked": true } y deja la cookie ecomiq_store_access, válida
por 12 horas. Reenvíala en cada llamada siguiente; en cURL, con
-b cookies.txt. Si el comercio cambia la contraseña, la cookie deja de valer.
Errores
code | Estado | Qué hacer |
|---|---|---|
Url.NotFound | 404 | No hay nada publicado en esa ruta. Muestra tu página 404. |
cms.page.not_found | 404 | La página no existe o no está publicada. |
cms.article.not_found | 404 | El artículo no existe o no está publicado. |
Category.NotFound | 404 | La categoría no existe o está inactiva. |
cms.menu.not_found | 404 | El menú no existe o está inactivo. Pinta el encabezado sin él. |
Common.NotFound | 404 | No existe la colección, la ubicación o la tienda. |
Common.Validation | 400 | Revisa errors. Por ejemplo, search con un solo carácter. |
Common.Unauthorized | 401 | La tienda es privada. Pide la contraseña. |
Store.AccessDenied | 401 | La contraseña no coincide. |
Common.ServiceUnavailable | 503 | El buscador no responde. Reintenta en unos segundos. |
Siguientes pasos
- Tienda headless: carrito y checkout.
- Contenido y tienda: referencia.
- Errores: formato y reintentos.
Última actualización: