Integrate category navigation
This reference is for developers who render hierarchical category navigation in a public storefront. The navigation, category landing page, and product list use the same server-authoritative storefront context.
Load the category tree
Call the public endpoint:
GET /api/v1/public/v1/catalog/categories/tree
Accept-Language: enDo not send tenantId, siteId, or salesChannelId. Workspace derives the tenant, site, and sales channel from the server-resolved public host and site context. Accept-Language selects an admitted locale in that context.
The response contains a flat list in tree order:
{
"data": [
{
"uuid": "uuid",
"label": "Clothing",
"path": "/en/clothing",
"depth": 0
},
{
"uuid": "uuid",
"parentUuid": "uuid",
"label": "Jackets",
"path": "/en/clothing/jackets",
"depth": 1
}
]
}Parents always precede their children. Within one level, Workspace orders nodes by editorial position, resolved label, and UUID. Use parentUuid and depth to render the hierarchy, and use path as the public category URL.
The tree contains only approved categories with an uninterrupted approved ancestor chain and an active route. An unlisted category removes its complete subtree. A category without a matching publication or route is not promoted to a new root.
Include product counts
Without query parameters, the endpoint reads only the category tree. Request counts only when the presentation needs them:
GET /api/v1/public/v1/catalog/categories/tree?includeCounts=trueincludeCounts=true adds count to every node. The default result mode counts distinct product variants. To count distinct catalog products, select the mode explicitly:
GET /api/v1/public/v1/catalog/categories/tree?includeCounts=true&resultMode=catalog_productThe supported values are product_variant and catalog_product. resultMode is valid only with includeCounts=true. A count includes the node and its visible descendants in the same storefront context. The same result contributes only once to a shared ancestor. Categories with showWhenEmpty=false are removed with their subtree after this aggregation.
Landing pages and server-rendered navigation
An active category URL resolves to the canonical landing page for the publication, site, and locale. The minimal landing page uses the existing variant search and product presentation pipeline. The Sitegenerator can also render the no-count tree into the initial HTML through categoryNavigation.
The components provide the server contract but are not placed in a standard theme automatically. The landing page is intentionally minimal. Breadcrumbs, sitemap expansion, and query fallback are outside this contract. Catalog product landing pages are also not included.
Handle errors
The tree API returns 400 for invalid query parameters and 429 when a protection limit is exceeded. A missing or mismatched tenant context returns 403; an unavailable storefront scope returns 404. The tree API also returns 503 when locale admission or the handler is unavailable. Internal reader failures return a neutral 500, and timeouts return 504. Technical error responses use Cache-Control: no-store and do not expose database details. The server-rendered category landing page and categoryNavigation also return 503 when a route or dependency is not ready.
Do not replace these responses with internal admin or PIM calls. An empty data list is a valid tree with no visible categories.
Verify the integration
The integration is correct when parents precede their children, every link uses a public category path, and a request without includeCounts=true has no count field. Also verify a locale with different labels and an empty tree.