How to Manage Product Categories
In this document, you’ll learn how to manage product categories using the admin REST APIs.
Overview
Using the product category admin REST APIs, you can manage the categories in your commerce application.
Scenario
You want to add or use the following admin functionalities:
- Manage categories including list, create, edit, and delete categories.
- Manage products in a category, including adding or removing products from a category.
Prerequisites
Medusa Components
It is assumed that you already have a Medusa backend installed and set up. If not, you can follow the quickstart guide to get started.
JS Client
This guide includes code snippets to send requests to your Medusa backend using Medusa’s JS Client, among other methods.
If you follow the JS Client code blocks, it’s assumed you already have Medusa’s JS Client installed and have created an instance of the client.
Medusa React
This guide also includes code snippets to send requests to your Medusa backend using Medusa React, among other methods.
If you follow the Medusa React code blocks, it's assumed you already have Medusa React installed and have used MedusaProvider higher in your component tree.
Authenticated Admin User
You must be an authenticated admin user before following along with the steps in the tutorial.
You can learn more about authenticating as an admin user in the API reference.
List Categories
You can retrieve available categories by sending a request to the List Categories API Route:
import { useAdminProductCategories } from "medusa-react"
function Categories() {
const {
product_categories,
isLoading
} = useAdminProductCategories()
return (
<div>
{isLoading && <span>Loading...</span>}
{product_categories && !product_categories.length && (
<span>No Categories</span>
)}
{product_categories && product_categories.length > 0 && (
<ul>
{product_categories.map(
(category) => (
<li key={category.id}>{category.name}</li>
)
)}
</ul>
)}
</div>
)
}
export default Categories
This request returns an array of product categories, as well as pagination fields.
You can also pass filters and other selection query parameters to the request. Check out the API reference for more details on available query parameters.
Create a Category
You can create a category by sending a request to the Create a Category API Route:
import { useAdminCreateProductCategory } from "medusa-react"
const CreateCategory = () => {
const createCategory = useAdminCreateProductCategory()
// ...
const handleCreate = (
name: string
) => {
createCategory.mutate({
name,
}, {
onSuccess: ({ product_category }) => {
console.log(product_category.id)
}
})
}
// ...
}
export default CreateCategory
This request requires one body parameter name
, which is the name of the category. The request also accepts the following optional body parameters:
handle
: a string that is typically used as a URL path or slug. If you don’t provide ahandle
, it will be the kebab case format of the name.is_internal
: a boolean that indicates whether the category is visible to customers. By default, it’sfalse
.is_active
: a boolean that indicates whether the category is active. By default, it’strue
.parent_category_id
: An ID of another category that this new category should be a child of.
The request returns the newly created product category.
Retrieve a Category
You can retrieve a product category by sending a request to the Get a Product Category API Route:
import { useAdminProductCategory } from "medusa-react"
type Props = {
productCategoryId: string
}
const Category = ({
productCategoryId
}: Props) => {
const {
product_category,
isLoading,
} = useAdminProductCategory(productCategoryId)
return (
<div>
{isLoading && <span>Loading...</span>}
{product_category && <span>{product_category.name}</span>}
</div>
)
}
export default Category
This request requires the ID of the category to be passed as a path parameter.
It returns the full object of the product category.
Edit a Category
You can edit a product category by sending a request to the Update a Product Category API Route:
import { useAdminUpdateProductCategory } from "medusa-react"
type Props = {
productCategoryId: string
}
const Category = ({
productCategoryId
}: Props) => {
const updateCategory = useAdminUpdateProductCategory(
productCategoryId
)
// ...
const handleUpdate = (
name: string
) => {
updateCategory.mutate({
name,
}, {
onSuccess: ({ product_category }) => {
console.log(product_category.id)
}
})
}
// ...
}
export default Category
fetch(`<BACKEND_URL>/admin/product-categories/${productCategoryId}`, {
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Skinny Jeans",
}),
})
.then((response) => response.json())
.then(({ product_category }) => {
console.log(product_category.id)
})
This request requires the ID of the category to be passed as a path parameter.
In its body, you can pass any of the category’s fields that you want to update. In the code snippet above, you update the name of the category.
You can check the list of accepted fields in the API reference.
The request returns the full object of the updated product category.
Manage Products in a Category
You can manage the categories of each product individually using the product APIs. This section explores the other approach of managing a product’s category using the product category APIs.
Add Products to a Category
You can add more than one product to a category using the Add Products to a Category API Route:
import { useAdminAddProductsToCategory } from "medusa-react"
type Props = {
productCategoryId: string
}
const Category = ({
productCategoryId
}: Props) => {
const addProducts = useAdminAddProductsToCategory(
productCategoryId
)
// ...
const handleAddProducts = (
productIds: ProductsData[]
) => {
addProducts.mutate({
product_ids: productIds
}, {
onSuccess: ({ product_category }) => {
console.log(product_category.products)
}
})
}
// ...
}
export default Category
fetch(`<BACKEND_URL>/admin/product-categories/${productCategoryId}/products/batch`, {
credentials: "include",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
product_ids: [
{
id: productId1,
},
{
id: productId2,
},
],
}),
})
.then((response) => response.json())
.then(({ product_category }) => {
console.log(product_category.id)
})
This request requires the ID of the category to be passed as a path parameter.
In its body, it requires a product_ids
parameter which is an array of objects. Each object in the array has the property id
, which is the ID of the product to add. So, each product you want to add you pass it to the array as an object having the property id
.
The request returns the full object of the product category updated with the new products.
Remove Products from a Category
You can remove products from a category by sending a request to the Delete Products API Route:
import { useAdminDeleteProductsFromCategory } from "medusa-react"
type ProductsData = {
id: string
}
type Props = {
productCategoryId: string
}
const Category = ({
productCategoryId
}: Props) => {
const deleteProducts = useAdminDeleteProductsFromCategory(
productCategoryId
)
// ...
const handleDeleteProducts = (
productIds: ProductsData[]
) => {
deleteProducts.mutate({
product_ids: productIds
}, {
onSuccess: ({ product_category }) => {
console.log(product_category.products)
}
})
}
// ...
}
export default Category
fetch(`<BACKEND_URL>/admin/product-categories/${productCategoryId}/products/batch`, {
credentials: "include",
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
product_ids: [
{
id: productId1,
},
{
id: productId2,
},
],
}),
})
.then((response) => response.json())
.then(({ product_category }) => {
console.log(product_category.id)
})
This request requires the ID of the category to be passed as a path parameter.
In its body, it requires a product_ids
parameter which is an array of objects. Each object in the array has the property id
, which is the ID of the product to remove. So, each product you want to remove you pass it to the array as an object having the property id
.
The request returns the full object of the product category updated with the its products.
Delete a Category
You can delete a product category by sending a request to the Delete a Product Category API Route:
import { useAdminDeleteProductCategory } from "medusa-react"
type Props = {
productCategoryId: string
}
const Category = ({
productCategoryId
}: Props) => {
const deleteCategory = useAdminDeleteProductCategory(
productCategoryId
)
// ...
const handleDelete = () => {
deleteCategory.mutate(void 0, {
onSuccess: ({ id, object, deleted }) => {
console.log(id)
}
})
}
// ...
}
export default Category
This request requires the ID of the category to be passed as a path parameter.
The request returns the following fields:
id
: The ID of the deleted category.object
: The type of object that was deleted. In this case, the value will beproduct-category
.deleted
: A boolean value indicating whether the category was deleted.