Edit in GitHubLog an issue

Implement categories on the storefront

Managing categories with Commerce projects that use the Merchandising Services composable catalog data model requires two types of API operations:

  • Create category data using the categories operations available in the Data Ingestion API, and using the products operations to manage product category assignments.

  • Retrieve category data for storefront display and navigation using the navigation and categoryTree queries available in the Merchandising Services GraphQL API.

CategoryViewV2 interface

The CategoryViewV2 interface provides a minimal, streamlined set of category fields—slug and name—optimized for typical storefront display and navigation scenarios.

Interface definition

Copied to your clipboard
interface CategoryViewV2 {
slug: String!
name: String!
}

For complete field details, see CategoryViewV2 in the Merchandising Services GraphQL API reference.

Key benefits

  • Lightweight Design: Contains essential fields (slug and name) for optimal performance
  • Extensible: Serves as a base interface for specialized category types

Category types

The CategoryViewV2 interface is implemented by three specialized types:

  1. CategoryNavigationView - For menu rendering and navigation
  2. CategoryProductView - For category data returned with product queries
  3. CategoryTreeView - For hierarchical category management and rich category pages

CategoryNavigationView type

The CategoryNavigationView type implements CategoryViewV2 and provides category data optimized for storefront navigation. It contains:

  • name and slug — Category identity
  • children — Nested subcategories for building the full menu hierarchy in a single query

Use this type to render top menus, dropdowns, and mobile navigation.

Type definition

Copied to your clipboard
type CategoryNavigationView implements CategoryViewV2 {
slug: String!
name: String!
children: [CategoryNavigationView]
}

For complete field details, see CategoryNavigationView in the Merchandising Services GraphQL API reference.

See the Navigation query examples section below for example queries and responses using this type.

Performance safeguards

  • Depth Limitation: Menu depth is limited to 4 levels maximum
  • Lightweight Attributes: Excludes heavyweight category attributes redundant for menu rendering
  • Single Query: Retrieves entire family in one database query
  • Heavy Caching: Query responses are heavily cached for optimal performance

CategoryProductView type

The CategoryProductView type implements CategoryViewV2 and provides category data within product query responses. Each product's categories field returns a list of CategoryProductView objects containing:

  • name and slug — Category identity
  • level — Position in the hierarchy
  • parents — Full chain of ancestor categories

Use this type to render breadcrumbs, filter by category, or display category context on product detail pages.

Type definition

Copied to your clipboard
type CategoryProductView implements CategoryViewV2 {
name: String!
slug: String!
level: Int!
parents: [CategoryProductView!]
}

The parents field is self-referencing—each parent entry is itself a CategoryProductView with its own name, slug, level, and parents. This allows you to reconstruct the full breadcrumb path for any category a product belongs to.

For complete field details, see CategoryProductView in the Merchandising Services GraphQL API reference.

See the Products query with categories examples section below for example queries and responses using this type.

Performance safeguards

The categories field is optional on product types. Omit it when category data is not needed to avoid unnecessary overhead.

CategoryTreeView type

The CategoryTreeView type implements CategoryViewV2 and provides the richest category data. It contains:

  • name and slug — Category identity
  • level and parentSlug / childrenSlugs — Hierarchy and relationships
  • description — Category descriptive content
  • metaTags — SEO metadata (title, description, keywords)
  • images — Category images

Use this type for rich category landing pages, SEO-driven content, and CMS administration.

Type definition

Copied to your clipboard
type CategoryTreeView implements CategoryViewV2 {
slug: String!
name: String!
level: Int
parentSlug: String
childrenSlugs: [String]
description: String
metaTags: CategoryMetaTags
images: [CategoryImage]
}
type CategoryMetaTags {
title: String
description: String
keywords: [String]
}
type CategoryImage {
url: String!
label: String
roles: [String]
customRoles: [String]
}

For complete field details, including the CategoryMetaTags and CategoryImage types, see CategoryTreeView in the Merchandising Services GraphQL API reference.

See the CategoryTree query examples section below for example queries and responses using this type.

Retrieve category navigation data optimized for storefront menu rendering with built-in performance safeguards.

Copied to your clipboard
type Query {
navigation(family: String!): [CategoryNavigationView]
}

The family parameter is required and specifies which category family to retrieve. The query returns the full hierarchy for that family in a single request, with a maximum depth of 4 levels.

Retrieve basic top menu navigation

Copied to your clipboard
query GetTopMenuNavigation {
navigation(family: "Top-menu") {
slug
name
children {
slug
name
children {
slug
name
}
}
}
}

The response returns a single root node with no nested children:

Copied to your clipboard
Men clothing
└── (no children)

Retrieve multi-level menu navigation

Copied to your clipboard
query GetFullMenuNavigation {
navigation(family: "menu") {
slug
name
children {
slug
name
children {
slug
name
children {
slug
name
}
}
}
}
}

The response returns a three-level nested hierarchy:

Copied to your clipboard
Men clothing
└── Men tops
└── Jackets

Products query with categories examples

Retrieve category data for products, including breadcrumb ancestors, with optional filtering by category family.

Copied to your clipboard
type ProductView {
categories(family: String): [CategoryProductView]
}

The categories field is available on product types such as ProductView. Use the optional family parameter to return only categories from a specific category family. When omitted, categories from all families are returned.

Retrieve product categories with breadcrumb ancestors

Copied to your clipboard
query {
products(skus: ["shorts-red-m"]) {
name
sku
categories(family: "clothing") {
name
slug
level
parents {
name
slug
level
}
}
}
}

The parents array provides the full ancestor chain, which you can use to render a breadcrumb path:

Copied to your clipboard
Men (level 0) → Clothes (level 1) → Shorts (level 2)
└── product: Red Shorts (M)

Filter product categories by family

A product can belong to categories in multiple families. Use the family parameter to return only categories from a specific family. In this example, the product belongs to categories in both the "clothing" and "seasonal" families, but the query filters for "seasonal" only.

Copied to your clipboard
query {
products(skus: ["shorts-red-m"]) {
name
sku
categories(family: "seasonal") {
name
slug
level
parents {
name
slug
level
}
}
}
}

Without the family filter, the response would include categories from all families the product belongs to—for example, both "Shorts" from the "clothing" family and "Summer Essentials" from the "seasonal" family. The family parameter narrows the result to a single family, which is useful when rendering context-specific navigation or breadcrumbs.

CategoryTree query examples

Retrieve hierarchical category data in a tree structure with parent-child relationships and level information.

Copied to your clipboard
type Query {
categoryTree(family: String!, slugs: [String!], depth: Int): [CategoryTreeView]
}

Retrieve full category tree

Copied to your clipboard
query GetFullCategoryTree {
categoryTree(family: "main-catalog") {
slug
name
level
parentSlug
childrenSlugs
}
}

The flat list represents this tree, reconstructed via parentSlug and childrenSlugs:

Copied to your clipboard
Men's Clothing (level 0)
├── Men's Tops (level 1)
│ ├── Shirts (level 2)
│ └── Jackets
└── Men's Bottoms

Retrieve specific category subtree

Copied to your clipboard
query GetSpecificCategorySubtree {
categoryTree(
family: "main-catalog"
slugs: ["men/tops", "men/bottoms"]
depth: 2
) {
slug
name
level
parentSlug
childrenSlugs
}
}

The response is a flat list. Each node's parentSlug and childrenSlugs fields let you reconstruct the tree:

Copied to your clipboard
Men's Tops (level 1) Men's Bottoms (level 1)
├── Shirts (level 2) ├── Pants (level 2)
└── Jackets (level 2) └── Shorts (level 2)

Retrieve root categories only

Copied to your clipboard
query GetRootCategories {
categoryTree(family: "main-catalog", depth: 0) {
slug
name
level
parentSlug
childrenSlugs
}
}

With depth: 0, only the top-level roots are returned:

Copied to your clipboard
Men's Clothing (level 0) Women's Clothing (level 0)
childrenSlugs: childrenSlugs:
├── men/tops ├── women/tops
└── men/bottoms └── women/bottoms
(referenced but not fetched) (referenced but not fetched)

Retrieve category details with metadata and images

Use the description, metaTags, and images fields to build rich category landing pages that include SEO metadata and visual content. This is especially useful when rendering a category page that needs a hero image, descriptive copy, and proper <meta> tags for search engines.

Copied to your clipboard
query CategoryTree {
categoryTree(slugs: ["men/clothes/shorts"], family: "clothing") {
slug
name
level
parentSlug
childrenSlugs
description
metaTags {
title
description
keywords
}
images {
url
label
roles
customRoles
}
}
}

Use case scenarios

Storefront navigation menu

Use the navigation query with CategoryNavigationView for:

  • Building responsive navigation components
  • Creating dropdown menus
  • Mobile menu rendering

Benefits: Optimized performance with caching, depth limits, and lightweight data.

Category landing pages and SEO

Use the categoryTree query with CategoryTreeView to build rich category pages:

  • Render category descriptions and hero images on landing pages
  • Populate <meta> tags (title, description, keywords) for SEO
  • Display category images with appropriate roles (for example, BASE for hero, THUMBNAIL for previews)
  • Assign custom image roles for merchant-specific layouts

Benefits: Combines hierarchy data with descriptive content, SEO metadata, and images in a single query.

Product detail pages and breadcrumbs

Use the categories field on product queries with CategoryProductView for:

  • Rendering breadcrumb navigation on product detail pages
  • Displaying category badges or tags on product cards
  • Filtering or grouping products by category in search results
  • Building "Shop by Category" links from a product context

Benefits: The parents field provides the full ancestor chain in a single query, eliminating the need for separate category lookups when building breadcrumbs.

Retail CMS category management

Use the categoryTree query with CategoryTreeView for:

  • Category hierarchy management
  • Building category administration interfaces
  • Implementing category tree editors
  • Managing parent-child relationships

Benefits: Complete hierarchy metadata, flexible querying, and detailed relationship information.

Performance considerations

  • Choose the right query for the use case. Use navigation for storefront menus—it is heavily cached, limited to four levels, and returns only lightweight fields. Use categoryTree when you need full hierarchy metadata, descriptions, or images.
  • Limit tree depth. Pass the depth parameter to categoryTree to avoid fetching deeper levels than you need.
  • Target specific subtrees. Pass the slugs parameter to categoryTree to fetch only the branches you need rather than the entire tree.
  • Omit optional fields. The categories field on product queries and the description, metaTags, and images fields on categoryTree are optional. Exclude them when they are not needed to reduce payload size.
  • Privacy
  • Terms of Use
  • Do not sell or share my personal information
  • AdChoices
Copyright © 2026 Adobe. All rights reserved.