Content Pages Module — Storefront
Public storefront reads for content (CMS) pages. Returns only published pages by slug (with breadcrumb and children) plus a paginated published summary list; content is raw HTML rendered verbatim.
HTTP surface for storefront content-page reads. Content pages are operator-authored CMS pages (About, Return Policy, FAQ, landing pages, …) addressable by slug. The content field is raw HTML authored by an admin and rendered verbatim by the storefront.
Source:
api-modules/content/src/controllers/store-content-page.controller.ts.Admin CRUD for content pages lives in
admin/content.md. This file documents the public read endpoints only.
Conventions
Authentication
| Endpoint | Auth |
|---|---|
GET /store/content-pages | none (public) |
GET /store/content-pages/:slug | none (public) |
Only PUBLISHED, non-deleted pages are ever returned. Draft or soft-deleted pages return 404 (never 403), so their existence can't be probed.
Response envelope
Successful responses are wrapped by ResponseInterceptor:
{
"data": <payload>,
"message": "Success",
"statusCode": 200,
"metadata": { /* present on the paginated list only */ }
}The list endpoint is offset-paginated (metadata: { total, limit, offset, hasMore }). List rows are summaries — the (potentially large) HTML content body is omitted; fetch it via the slug endpoint.
Caching
Storefront reads are cached in Redis and invalidated on every admin write, so edits surface promptly. content is rendered as-is — server-side HTML sanitisation is not performed; treat it as trusted operator content.
Domain types
ContentPageSummary (list rows)
type ContentPageStatus = "DRAFT" | "PUBLISHED"; // always "PUBLISHED" on the storefront
type ContentPageSummary = {
id: string;
title: string;
description: string | null; // page subtitle / short description
slug: string;
status: ContentPageStatus;
template: "default" | "html"; // storefront render mode (default = prose, html = raw)
layout: string | null; // free-form layout hint (preserved from legacy CMS)
hideLowerMenu: boolean; // hide the storefront lower (category) nav on this page; default false
publishedAt: string | null; // ISO
sortOrder: number; // ascending
parentId: string | null;
metaTitle: string | null;
metaDescription: string | null;
metaKeywords: string | null;
metaRobots: string | null; // e.g. "index, follow"
ogTitle: string | null;
ogDescription: string | null;
ogImage: string | null; // storage key (prefix with assets base URL)
ogType: string | null;
createdAt: string; // ISO
updatedAt: string; // ISO
deletedAt: string | null; // always null on the storefront
};ContentPageDetail (slug endpoint)
type ContentPageNav = { id: string; title: string; slug: string; sortOrder: number };
type ContentPageDetail = {
page: ContentPage; // full record incl. raw HTML `content`, `schema` (JSON-LD), `metadata`
breadcrumb: ContentPageNav[]; // published ancestor chain, root-first (excludes the page itself)
children: ContentPageNav[]; // published direct children, sorted by sortOrder
};page carries every field of ContentPageSummary plus content (raw HTML string), schema (JSON-LD object or null) and metadata.
Endpoints
GET /store/content-pages — List published pages
Offset-paginated summary list of published, non-deleted pages, sorted by sortOrder ASC, title ASC.
Query
| Name | Type | Notes |
|---|---|---|
limit | number? | default 100, max 500 |
offset | number? | default 0 |
parentId | string? | parentId=<id> lists that page's published children; parentId=null (literal) lists top-level pages |
Response 200 — paginated array of ContentPageSummary.
GET /store/content-pages/:slug — Published page by slug
Returns the published page plus its breadcrumb (published ancestor chain, root-first) and published direct children.
Path params
| Name | Notes |
|---|---|
slug | Page slug |
Response 200 — ContentPageDetail.
{
"data": {
"page": {
"id": "01J9...",
"title": "Shipping",
"description": "Delivery timelines & charges",
"slug": "shipping",
"content": "<h1>Shipping</h1><p>…</p>",
"status": "PUBLISHED",
"publishedAt": "2026-05-01T08:00:00.000Z",
"sortOrder": 0,
"parentId": "01J8...",
"metaRobots": "index, follow",
"schema": null,
"metadata": null,
"createdAt": "2026-05-01T08:00:00.000Z",
"updatedAt": "2026-05-01T08:00:00.000Z",
"deletedAt": null
},
"breadcrumb": [
{ "id": "01J8...", "title": "Help", "slug": "help", "sortOrder": 0 }
],
"children": []
},
"message": "Success",
"statusCode": 200
}Errors
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND | No published page with that slug (also covers draft / soft-deleted pages) |
Related modules
content(admin) — operator CRUD that authors these pages. Seeadmin/content.md.
Catalog Module — Storefront
HTTP surface for unauthenticated catalog reads. The storefront uses these endpoints to render the navigation tree, brand / tag / ingredient pages, the product detail page (PDP),…
Customer Module — Storefront
HTTP surface for the customer-side address book. The customer identity itself lives in Better-Auth's user table; this module owns the shopping-related customer data on top of that…