Multiple S.list() groups in Sanity desk structure

8 replies
Last updated: May 18, 2021
Hi folks. I’m working on the desk structure and trying to figure out how to have more than one list with a title that contains groups if of document types. e.g. in this screenshot, I want to have another list like the “Site” one but with a different title. I can’t seem to get it working. It seems I can only use one
S.list(…)
in the structure?
AI Update

Based on the Structure Builder documentation, you actually can have multiple lists with titles and groups of document types! The key is understanding that you only have one root S.list(), but within that list, you can create multiple S.listItem() entries that each contain their own nested lists.

Here's how to structure it:

export const structure: StructureResolver = (S) =>
  S.list()
    .id('root')
    .title('Content')
    .items([
      // First section - "Site"
      S.listItem()
        .title('Site')
        .child(
          S.list()
            .title('Site Settings')
            .items([
              S.documentTypeListItem('siteSettings'),
              S.documentTypeListItem('navigation'),
              S.documentTypeListItem('footer'),
            ])
        ),
      
      // Divider (optional)
      S.divider(),
      
      // Second section - "Content"
      S.listItem()
        .title('Content')
        .child(
          S.list()
            .title('Content Types')
            .items([
              S.documentTypeListItem('page'),
              S.documentTypeListItem('post'),
              S.documentTypeListItem('author'),
            ])
        ),
      
      // Third section - "Media"
      S.listItem()
        .title('Media')
        .child(
          S.list()
            .title('Media Assets')
            .items([
              S.documentTypeListItem('gallery'),
              S.documentTypeListItem('video'),
            ])
        ),
    ])

The pattern is:

  1. One root S.list() at the top level
  2. Multiple S.listItem() entries within it (these become your titled sections)
  3. Each S.listItem() uses .child() to contain another S.list() with its own items

This creates a navigable structure where clicking on "Site", "Content", or "Media" in the root list takes you to a new list with that group's document types. According to the Structure Builder documentation, you can nest these infinitely deep if needed!

You can learn more about this in the Structure customization course.

Show original thread
8 replies
Hey Shane! Structure builder can definitely be confusing to work with!
Based off of my experience, you can only use one
S.list()
in your base structure (though I’ve never actually seen anything in the docs confirming this). When I’ve done something similar to what you’re looking to do I’ve used
S.listItem()
. For example, my structure looking like this:

S.list()
.title('Base')
.items([
  S.listItem()
    .title('Blog')
    .icon(BiColumns)
    .child(
      S.list()
        .title('Blog Documents')
        .items([
          S.documentTypeListItem('post'),
          S.documentTypeListItem('author')
        ])
    ),
  S.listItem()
   .title('Learning Path')
   .icon(BiMapAlt)
   .child(
    S.list()
      .title('Learning Path')
      .items([
        S.documentTypeListItem('section'),
        S.documentTypeListItem('module')
      ])
  ),
])
This gives me a structure that looks like this:
If you give me a text example of what you’d like your structure to look like I can give you more specific help.
Hey Shane! Structure builder can definitely be confusing to work with!
Based off of my experience, you can only use one
S.list()
in your structure (though I’ve never actually seen anything in the docs confirming this). When I’ve done something similar to what you’re looking to do I’ve used
S.listItem()
. For example, my structure looking like this:

S.list()
.title('Base')
.items([
  S.listItem()
    .title('Blog')
    .icon(BiColumns)
    .child(
      S.list()
        .title('Blog Documents')
        .items([
          S.documentTypeListItem('post'),
          S.documentTypeListItem('author')
        ])
    ),
  S.listItem()
   .title('Learning Path')
   .icon(BiMapAlt)
   .child(
    S.list()
      .title('Learning Path')
      .items([
        S.documentTypeListItem('section'),
        S.documentTypeListItem('module')
      ])
  ),
])
This gives me a structure that looks like this:
If you give me an text example of what you’d like your structure to look like I can give you more specific help.
user M
thanks for your reply 🙂 I see what you mean - although I was trying to just get multiple headings in the first pane of the editor, something like this (i just did this in photoshop quickly). I don’t think it’s possible though?
Ah yeah, I figured that was what you meant. Unfortunately you can’t condense panes like that.
All good! Is there any way to customise the actual react components that are in the lists? I’ve actually added “fake” list items just with a title - see “data models” and “settings section” here - I thought possibly I could override the CSS on these and set pointer-events: none and change the style to make them appear like headings
user M
I got this working quite well - just using an empty list item for the headings and setting some css on them, if anyone is interested for reference:

S.listItem().id('structure_customListHeading').title('Structure'),

/* Override custom list headings */
a[href$='_customListHeading'] {
  pointer-events: none;
}

a[href$='_customListHeading'] h2 {
  font-weight: 600;
}

a[href$='_customListHeading'] div[class^='DefaultPreview_media'] {
  display: none;
}

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?