Adding multiple categories to a product in Sanity.io

11 replies
Last updated: Jun 15, 2023
Hello devs, How I can assign two categories to the same product? like a shirt could be in Featured Category as well as Shirt category
AI Update

To assign multiple categories to a product in Sanity, you'll want to use an array of references in your product schema. This allows a single product (like a shirt) to belong to multiple categories simultaneously.

Here's how to set this up:

export default {
  name: 'product',
  type: 'document',
  title: 'Product',
  fields: [
    {
      name: 'title',
      type: 'string',
      title: 'Title'
    },
    {
      name: 'categories',
      type: 'array',
      title: 'Categories',
      of: [
        {
          type: 'reference',
          to: [{type: 'category'}]
        }
      ]
    },
    // ... other product fields
  ]
}

And your category schema would look like:

export default {
  name: 'category',
  type: 'document',
  title: 'Category',
  fields: [
    {
      name: 'title',
      type: 'string',
      title: 'Title'
    },
    {
      name: 'slug',
      type: 'slug',
      title: 'Slug',
      options: {
        source: 'title'
      }
    }
  ]
}

With this setup, when you edit a product in Sanity Studio, you'll see a "Categories" field where you can add multiple category references. Your shirt can then be in both "Featured" and "Shirts" categories at the same time.

To query products with their categories using GROQ:

*[_type == "product"] {
  title,
  "categories": categories[]-> {
    title,
    slug
  }
}

Or to find all products in a specific category:

*[_type == "product" && references(*[_type=="category" && slug.current == "featured"]._id)]

This approach is mentioned in the Product Information Management article, where products can be "grouped into categories through reference documents." It's a flexible pattern that scales well as your product catalog grows.

Hi! 👋 If
category
is an array of categories, you can add more than one.
import { defineType } from "sanity";


export const category = defineType({

name: "category",

title: "Category",

type: "array",

fields: [

{

name: "name",

title: "Category Name",

type: "string",

},


],

});
getting this error on fields:Argument of type '{ name: "category"; title: string; type: "array"; fields: { name: string; title: string; type: string; }[]; }' is not assignable to parameter of type '{ type: "array"; name: "category"; } & Omit<ArrayDefinition, "preview">'.
Also, I'm referencing this into my product file
Like this
export const products = {

name: "products",

title: "Products",

type: "document",

fields: [

{

name: "title",

title: "Product Title",

type: "string",

},

defineField({

name: "category",

title: "Product Category",

type: "reference",

to: [

{

type: "category",

},

],

}),

],

};
Sorry if I'm disturbing with this huge code coz I'm new to this:)
References can only be to documents, but it looks like your reference in
products
is to an array type. One way I might do this is to make
category
a document type containing a string (
title
is a convention), and then add an array of references (to
category
) in your
products
schema.
All I want is to add an option so that I can attach 2 categories to the same product. Stucked since yesterday😟
From those two recent screenshots,
category
looks good. Can you open
products
and replace lines 38-47 with this?

defineField({
  name: "categories",
  title: "Product Categories",
  type: "array",
  of: [
    defineArrayMember({
      name: "category",
      title: "Product Category",
      type: "reference",
      to: [{ type: "category" }],
    }),
  ],
})
(Note that the
defineArrayMember
wrapper function isn’t necessary, so omit it if you want. It improves support in your editor, like
defineType
).
Thank you very much, Amazing support you're providing at Sanity.❤️

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?