Skip to main content
Skip to main content

Product Categories

In this document, you’ll learn about Product Categories and how they can be used in Medusa.


Product Category feature is currently in beta mode and guarded by a feature flag. To use Product Categories either:

  1. Enable the MEDUSA_FF_PRODUCT_CATEGORIES environment variable;
  2. Or enable the product_categories key in the Medusa backend's settings.

You can learn more about enabling it in the feature flags documentation.


Product Categories allow you to categorize your products. You can manage categories in your store. You can also nest categories in one another, creating a parent-child hierarchy, and there is no limit to how far you can nest the categories.

In addition, you can give a category a ranking. As a product can have multiple categories, rankings can be useful in different cases. For example, when you’re unsure what main category to show in the product’s page in the frontend.

Example Use Cases

Here are some examples of the usage of Product Categories:

  • Organizing your large catalog store in a way that showcases to the customer what products you provide.
  • Create a multi-brand store, where each category acts as a brand.

Product Category vs Product Collection

Before v1.8 of Medusa, Product Collection was used as the main way of organizing products. It was used similarly to how you would use a Product Category. However, a Product Collection is not only different in what it actually represents, it also doesn’t provide the same functionalities that a Product Category does.

A Product Collection is used to group together a list of products, generally for a marketing purpose. For example, you can create a summer collection when summer comes around with a variety of products in them including shorts, t-shirts, and more.

On the other hand, a Product Category is used to provide easy and clear navigation for customers to help them find what they need. For example, you can have the following nested product categories:

  • Women
    • Tops
      • Jackets
      • Sweatshirt
      • T-shirt
      • etc…
    • Bottoms
      • Jeans
      • Shorts
      • etc…

This allows customers to directly choose the category that the product they’re looking for belongs to, and gives them an idea of what products your store offers. If you were to use Product Collections here, as they don’t support nesting, all of these categories would have to be separate collections that are not tied together.

ProductCategory Entity Overview

A product category is stored in the database as a ProductCategory entity. Some of its important attributes are:

  • id: The ID of the product category.
  • name: The name of the product category.
  • description: An optional string used to add a description for the product category.
  • handle: A string indicating a slug path of the category. It’s useful when creating a page on your storefront for the category, as the handle can be used as the path in the URL.
  • is_active: A boolean value indicating the status of the Product Category.
  • is_internal: A boolean value indicating the visibility of the Product Category.
  • mpath: A string value that keeps the IDs of all the category’s ancestors, delimited by a dot (.). This attribute is generated by Typeorm. For example, pcat_id1.pcat_id2.pcat_id3.

Relations to other Entities


Products can be available in more than one category. You can then filter products by a single or list of product categories.

The relation is implemented in the Product entity. You can access the product categories a product is available in by expanding the categories relation and using product.categories


The parent-child hierarchy is represented in the ProductCategory entity through the following relations:

  • You can access the parent of a category by expanding the parent_category relation and accessing category.parent_category. You can also access the ID of the parent category by accessing category.parent_category_id. If a category doesn’t have a parent, the relation and the ID will be null.
  • You can access the children of a category by expanding the category_children relation and accessing category.category_children. If a category doesn’t have children, the relation will be an empty array. By default, when expanding this relation in Product Category API Routes, only the immediate child categories are returned. If you want to get the entire hierarchy of child categories, you must pass the include_descendants_tree flag to the API Route setting its value to true.

Aside from these relations, the mpath attribute, which is a Materialized Path that is automatically generated by Typeorm, can be used to query deep trees faster.


See Also

Was this section helpful?