Discussion about organizing products in Sanity.io desk structure

23 replies
Last updated: Jun 24, 2022
Hi all,
I have this dekStructure:

import S from "@sanity/desk-tool/structure-builder";

export default () =>
  S.list()
    .title("Menu")
    .items([
      S.listItem()
        .title('Collection')
        .child(
          S.list()
            .title('Collection By Name')
            .items([
              S.listItem()
                .title('Gal')
                .child(
                  S.list()
                  .title('Gal Products')
                  .items([
                    S.listItem()
                    .title('gal-gl004')
                    .child(
                      S.document()
                        .schemaType('product')
                        .documentId('product')
                    ),
                    S.listItem()
                    .title('gal-gl005')
                    .child(
                      S.document()
                        .schemaType('product')
                        .documentId('product')
                    ),
                  ])
                ),
                S.listItem()
                .title('Cobber')
                .child(
                  S.list()
                  .title('Cobber Products')
                  .items([
                    S.listItem()
                    .title('cobber-cb003s')
                    .child(
                      S.document()
                        .schemaType('product')
                        .documentId('product')
                    ),
                    S.listItem()
                    .title('cobber-cb003c')
                    .child(
                      S.document()
                        .schemaType('product')
                        .documentId('product')
                    ),
                  ])
                ),
            ])
        ),
      ...S.documentTypeListItems().filter(
        (listItem) => !["collection", "product"].includes(listItem.getId())),
    ]);
it works fine but If I fill in 1 product it gives every other product the same info. Is there a way to have 1 product.js schema that is unique to the product?
Jun 24, 2022, 9:22 AM
I think you shouldn’t have to customize the desk structure unless you’re trying to achieve something quite specific. Isn’t the default structure alright?
Jun 24, 2022, 9:24 AM
Because right now I see you render specific documents with specific document IDs. That doesn‘t seem like a good idea if you plan on managing collections of products.
Jun 24, 2022, 9:25 AM
yeah I want to organize it properly
Jun 24, 2022, 9:26 AM
because for example the collection has a serie Gal and in that serie there are like 20 products
Jun 24, 2022, 9:26 AM
so its gonna add up if there are a lot of collections
Jun 24, 2022, 9:28 AM
So you want to have a pane for specific collections?
Jun 24, 2022, 9:28 AM
You might want to check this section of the documentation: https://www.sanity.io/docs/dynamically-group-list-items-with-a-groq-filter#e0c103debf81 . They do essentially the same thing. They create custom panes to group blog posts by author, which is similar to your need.
Jun 24, 2022, 9:29 AM
yea that sounds about right
Jun 24, 2022, 9:29 AM
hmm I changed some things according to the documentation but I cant create a new product or see existing one
Jun 24, 2022, 9:49 AM
I can’t debug anything without seeing code. 🙂
Jun 24, 2022, 9:51 AM
ofc sorry hahaha forgot to add it here it is
import S from "@sanity/desk-tool/structure-builder";

export default () =>
  S.list()
    .title("Menu")
    .items([
      S.listItem()
        .title("Products")
        .child(
          S.document()
          .schemaType("product")
          .documentId("product")
          ),
      S.listItem()
        .title("Collection")
        .child(
          S.list()
            .title("Collection By Name")
            .items([
              S.listItem()
                .title("Gal")
                .child(
                  S.documentTypeList("product")
                    .title("Products")
                    .child((categoryId) =>
                      S.documentList()
                        .title("Product")
                        .filter('_type == "post" && $categoryId in categories[]._ref')
                        .params({ categoryId })
                    )
                ),
            ])
        ),
      ...S.documentTypeListItems().filter(
        (listItem) => !["collection", "product"].includes(listItem.getId())
      ),
    ]);
Jun 24, 2022, 9:51 AM
So I think this part is incorrect:
 S.listItem()
        .title("Products")
        .child(
          S.document()
          .schemaType("product")
          .documentId("product")
          )
Because you don’t have a product document with the
product
document ID. This is what you do with singleton documents, but your product is not a singleton. It‘s a collection.
Jun 24, 2022, 9:54 AM
I see you didn’t update the filter at all as well. You need to adjust it for your schema. The one from the documentation is not going to work out of the box.
Jun 24, 2022, 9:54 AM
ah I see what you mean: I changed it to this now:
import S from "@sanity/desk-tool/structure-builder";

export default () =>
  S.list()
    .title("Menu")
    .items([
      S.listItem()
        .title("Collection")
        .child(
          S.list()
            .title("Collection By Name")
            .items([
              S.listItem()
                .title("Gal")
                .child(
                  S.documentTypeList("product")
                    .title("Products")
                    .child((productId) =>
                      S.documentList()
                        .title("Product")
                        .filter('_type == "product" && $productId in product[]._ref')
                        .params({ productId })
                    )
                ),
            ])
        ),
      ...S.documentTypeListItems().filter(
        (listItem) => !["collection", "product"].includes(listItem.getId())
      ),
    ]);
I'm still doing something wrong here because I cant make a document or see any yet
Jun 24, 2022, 9:57 AM
Is this correct
$productId in product[]._ref
?
Jun 24, 2022, 9:59 AM
the schema is called product.js
Jun 24, 2022, 9:59 AM
Yes but a product doesn‘t have an array of products called
product
now, does it?
Jun 24, 2022, 10:01 AM
Not knowing too much of your schema, it feel like it should be more like:
S.listItem()
  .title("Gal")
  .child(
    S.documentTypeList("product")
      .title("Products")
      .child(() =>
        S.documentList()
          .title("Product")
          .filter('_type == "product" && $category == category')
          .params({ category: 'gal' })
      )
  )
Jun 24, 2022, 10:02 AM
hmm let me try to sketch a image so it's less confusing for us haha.
What I want looks like this:

menu(
collection(
gal(product +10),cobber(product +10),friendo(product +10)
)
),
Jun 24, 2022, 10:06 AM
so inside gal i want to be able to make a product with the information but also be able to add like 9 other variants
Jun 24, 2022, 10:08 AM
with the default structure it works fine but I want to be able to organize them
Jun 24, 2022, 10:08 AM
I think you might be modeling the content the wrong way around. The desk structure is purely presentational, it should not be reflective of design constraints. Variants should be attached to a product document, and that 10 variants limit should be defined on the product document itself, not in the structure.
Jun 24, 2022, 10:49 AM
you might be right, I got something working though. Now I can see my products in the Gal folder. All I need now it sorting it so that only products with Gal in the name will show in this structure.
Jun 24, 2022, 11:37 AM

Sanity– build remarkable experiences at scale

The Sanity Composable Content Cloud is the headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?