CoursesStudio excellenceSuperior structure
Certification
Sanity developer certification
Track
Sanity developer essentials

Studio excellence

Lesson
4

Superior structure

By default, Sanity will create menu items in the Structure tool for every registered document schema and display them with default icons. We can do better!
Log in to mark your progress for each Lesson and Task
Review List Previews in the documentation

Both document and object schema have a preview key, which can be customized with a title, subtitle and media so that they are more easily identifiable in list views and search results.

It can be the difference between document lists that look like this:

...and lists full of helpful document information like this:

This is done using both select and prepare when customizing the preview key in schema types.

In the example below, "task" blocks are extracted from a portable text field, counts and displays them in the subtitle.

The media key is an icon component, but it could also be an image field in the document.

./schemas/exercise.ts
preview: {
select: {
title: 'title',
content: 'content',
},
prepare: ({title, content}) => {
const taskCount = content ? content.filter((b) => b.listItem === 'task').length : 0
const subtitle = content ? (taskCount === 1 ? '1 task' : `${taskCount} tasks`) : `No tasks`
return {
title,
subtitle,
media: CheckCircle2,
}
},
},
Customize the preview for every document and object in the Studio

The media key is often used to display an icon for the document type or a key image asset from within the document.

It will also accept JSX as a value and render a component. From there, it’s possible to run asynchronous requests to show an even richer preview.

That is how this example shows both a picture from the presenter as well as an image from the document.

The example code for this first ensures that there are presenters to load into the component. Otherwise, it falls back to an image or just the schema type’s icon

./schemas/exercise.ts
// Import your own custom Component
import CourseMedia from './components/CourseMedia'
// Update the schema's "prepare" key
return {
title,
subtitle,
media: presenterCount ? (
<CourseMedia image={image} presenters={presenters} />
) : (
image ?? FiBook
),
}
Consider enriching the document list and search previews with a media component
See Structure Builder cheat sheet for quick examples of the most commonly used configurations

Creating a list item of all documents of a single type only requires this much configuration:

S.list()
.title('Base')
.items([
S.documentTypeListItem('lesson').title('Lessons')
])

However as your Studio configuration grows, listing all documents in a single column with no dividers or grouping can become unwieldy for authors.

Document lists can be nested to either group together related document schemas, or documents of the same type into filtered lists. This way less frequently edited documents are hidden from the main list.

In the example below, an array of lessons creates multiple child lists of the parent "Lessons" list.

S.listItem()
.title('Lessons')
.icon(FiAward)
.child(
S.list()
.title('Lessons')
.items(
languages.map((language) =>
S.listItem()
.title(`Lessons (${language.id.toLocaleUpperCase()})`)
.schemaType('lesson')
.icon(FiAward)
.child(
S.documentList()
.id(language.id)
.title(`${language.title} Lessons`)
.schemaType('lesson')
.filter('_type == "lesson" && language == $language')
.params({language: language.id})
)
)),
),
Nest infrequently edited document lists

Lists of documents can be visually separated by inserting S.divider() functions between list items.

Group related or filtered document lists together with dividers
Review Structure Builder reference documentation of default view panes

The default view pane is a document editor, but multiple view panes can be added to give context to the current document.

The most common use cases include using the Documents Pane plugin to show references to the current document. In the example below, you can see which "courses" reference the current "presenter" you're editing.

Other ideas for this pane are to contain style guides or documentation about the content creation process for that document type.

A view pane can be any React component, which will be passed in the current document value as props.

Add View Panes to give additional context to document editing
Review parameterized templates in the documentation

When customizing list views in the desk, you can extend the document creation process with parameterized initial value templates.

The document-internationalization plugin configures new templates by default so that new documents can be invoked with a language value prefilled.

Another common use case is for an "author" schema type to have the project member's ID set.

Create dynamic initial values for new documents
You have 6 uncompleted tasks in this lesson
0 of 6