Creating nested product folders filtered by category in Sanity Desk Structure

5 replies
Last updated: Nov 29, 2025
I have the following schema type.

export default {
  name: "products",
  type: "document",
  title: "Products",
  fields: [
{
      name: "categories",
      type: "reference",
      title: "Categories",
      to: {
        type: "category",
      },
    },

// other file

export default {
  name: "category",
  type: "document",
  title: "Product Categories",
  fields: [
    {
      name: "title",
      type: "string",
      title: "Title",
    },
  ],
};
I was wondering if in my deskStructure if it is possible to have a products folder -> then sub category folders filtered by the the categories that are selected for that product
AI Update

Yes, absolutely! You can create a nested structure where products are organized into folders based on their categories. Here's how to do it using the Structure Builder:

// structure/index.ts
import type {StructureResolver} from 'sanity/structure'

export const structure: StructureResolver = (S) =>
  S.list()
    .id('root')
    .title('Content')
    .items([
      // Products folder with category sub-folders
      S.listItem()
        .title('Products')
        .child(
          // Fetch all categories and create a folder for each
          S.documentTypeList('category')
            .title('By Category')
            .child((categoryId) =>
              S.documentList()
                .title('Products')
                .filter('_type == "products" && references($categoryId)')
                .params({ categoryId })
            )
        ),
      
      // You can also add a flat "All Products" list
      S.listItem()
        .title('All Products')
        .child(
          S.documentTypeList('products')
        ),
      
      // Direct access to categories
      S.documentTypeListItem('category').title('Categories'),
    ])

Then wire it up in your config:

// sanity.config.ts
import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {structure} from './structure'

export default defineConfig({
  // ...other config
  plugins: [
    structureTool({structure}),
    // ...other plugins
  ],
})

This creates a "Products" folder in your desk structure. When you click it, you'll see a list of all your categories. Clicking any category will show only the products that reference that specific category.

The key part is the GROQ filter '_type == "products" && references($categoryId)' which filters products that reference the selected category.

Note: Your schema has categories as a singular reference field. If you want to support multiple categories per product, change it to an array:

{
  name: "categories",
  type: "array",
  title: "Categories",
  of: [{
    type: "reference",
    to: {type: "category"}
  }]
}

The references() function works with both single references and arrays of references, so the same Structure Builder code will work either way!

You can learn more about customizing your desk structure in the Structure Builder guide and the Structure customization course.

Show original thread
5 replies

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?