Happening this week! Hear how Amplitude built a self-serve marketing engine to drive growth 🚀

Structure Builder API Reference

Overview of different methods in the Structure Builder API

This is the complete reference documentation for Structure Builder. This API lets you configure how the Sanity Studio's Structure tool organizes lists, documents, views, menus, and initial value templates.

The Structure Builder API is designed as a collection of methods that can be chained and passed in as arguments/parameters. To learn about the central concepts of Structure Builder, go to the introduction article and dive deeper into the API in the TypeScript reference documentation.

Configuring the structure

You can build custom structures by passing the structure to the desk tool configuration. To do this, define the structure resolver function, which receives the Structure Builder instance, by convention referred to as S, as its first argument, and a context object as its second.

// sanity.config.js

import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {schemaTypes} from './schema'

export default defineConfig({
  name: 'default',
  title: 'My Cool Project',
  projectId: 'my-project-id',
  dataset: 'production',
  plugins: [
    structureTool({
      structure: (S, context) => {
        console.log(context) // returns { currentUser, dataset, projectId, schema, getClient, documentStore }
        return S.documentTypeList('post')
      },
    })
  ],
  schema: schemaTypes
})


Where you define your structure is up to you - you could define it inline (as in the above example), or you could place it in a separate file and import/use it in your desk tool config:

// src/structure.js

export const structure = (S) => S.documentTypeList('post')

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

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

In the Structure Builder API, you'll find “convenience methods.” We recommend using these unless you want more fine-grained control.

Overview annotating what the different parts are
  • datasetstring

    Name of the current dataset

  • projectIdstring

    Unique ID for the project

  • schemaobject | Schema

    The schema registry of your project. Use `schema.get("schemaTypeName") to retrieve any schema by name.

  • currentUserobject | CurrentUser

    An object with info about the currently logged in user.

  • getClientfunction | SanityClient

    Callback function that returns a configured client

  • documentStoreobject

Lists

These methods define how lists and list items appear in the collapsible panes within the Studio’s desk tool. There are methods you can consider as “primitives” and methods that take a document schema type and automatically configure menus, initial value templates, and similar from the schema configuration.

Protip

You should generally opt for documentTypeList and documentList when you can since these give you good defaults and sets up a lot of things automatically for you.

list():List

A list goes into a collapsible pane. It also has a title.

A primitive for defining the list content of the collapsible pane, including its title and representation in the URL bar. Typically used when you want to group different list items within a pane.

Protip

Are you getting the error Structure node id cannot contain character ...? This is typically caused when the title contains a character that is not in the domain of (or cannot be automatically converted to the domain of) web-safe characters.

The solution is to explicitly specify an id that includes only web-safe characters.

Methods

  • id(id): List

    Set the id for the list.

    Parameters

    • idstring

      Identifier for the list used to reflect the current structure state in the studio’s URL. Derived automatically from .title() if not explicitly defined.


  • title(title): List

    Set the title for the list.

    Parameters

    • titlestring

      The title to use for the list

  • items(items): List

    Set the list items to display.

    You would typically use a method that returns an array of list items, such as documentTypeListItems, or list item methods inserted into their own array, such as listItem and documentListItem.

    Parameters

    • itemsarray

      An array of list items.

  • showIcons(showIcons): List

    Set whether or not to show the icons of the list items.


    Parameters

    • showIconsboolean

      Hides the list items icons if set to false.

  • initialValueTemplates(templateItems): List

    Sets which initial value templates should be available for this pane (which items appear when using "new document" on the pane).

    Use S.initialValueTemplateItem(templateId, parameters) to get a reference to a template. By passing an object of parameters, you can contextualize the template for the specific pane. See the initial value template documentation for more information.

    Parameters

    • templateItemsInitialValueTemplateItem[]

      Array of initial value template items.

  • menuItemsGroups(groups): List

    Defines which groups of menu items should be available for the pane. This also defines the order of the groups.

    You can either build these groups by using the builder method:
    [S.menuItemGroup().id('some-id').title('Some title')]

    or by passing an array of objects containing id and title properties:
    [{id: 'some-id', title: 'Some title'}]

    Parameters

    • groupsMenuItemGroup[]

      Array of menu item groups to use.

  • menuItems(menuItems): List

    Sets the list of menu items to appear in the pane menu.

    Parameters

    • menuItemsMenuItem[]

      Array of menu items to use. Use the menu item builder method S.menuItem() to build these.

  • defaultLayout(layout): List

    Sets the default layout for this list. Currently the only supported layouts are default and detail.

    Parameters

    • layoutstring

      Either default or detail.

  • child(child): List

    Sets which structure node to use as the child of this list, when an item in the list is selected.

    Can either be a structure node (any list, document, component etc) or a child resolver - a function that either syncronously or asyncronously resolves to a structure node.

    Read more about child resolvers in the conceptual guide for the structure builder.

    Parameters

    • childnode | function
  • canHandleIntent(intentChecker): List

    Sets the method used to determined whether or not the pane can handle an intent of a certain type.

    The intent checker receives three arguments: intentName, params and context. It should return a boolean indicating whether or not it can handle the intent.

    • intentName is generally create or edit.
    • params usually contains id and type, representing the document ID and schema type to be created. Often it will also have template, a string representing the ID of an initial value template.
    • context is an object containing pane and index

    Parameters

    • intentCheckerfunction

      Intent checker function

  • getCanHandleIntent(): function

    Returns the configured intent checker

  • getChild(): node | function

    Returns the configured child or child resolver for this pane

  • getDefaultLayout(): string

    Returns the defined default layout for this pane (if any)

  • getId(): string

    Returns the configured ID for this pane, if any

  • getInitialValueTemplates(): InitialValueTemplateItem[]

    Returns the list of configured initial value templates, if any

  • getItems(): node[]

    Returns the list of configured list items, if any

  • getMenuItemGroups(): MenuItemGroup[]

    Returns an array of the configured menu item groups, if any

  • getMenuItems(): MenuItem[]

    Returns an array of the configured menu items, if any

  • getShowIcons(): boolean

    Returns whether or not the pane is configured to show icons for the list items

  • getTitle(): string

    Returns the configured title for the pane, if any

documentTypeList(schemaType):DocumentList

Convenience method for documentList(). Returns a list node for the specified document type with its configuration for list items, menus, initial value templates, and views.

Arguments

  • REQUIREDschemaTypestring

    The schema type name of an existing document type that's defined in the Studio’s schema file.

Methods

See the methods summary for documentList

Example

// src/structure.js (.ts)

// Exports a list of documents with the schema type “post”
export const structure = (S) => S.documentTypeList('post')

documentList():DocumentList

A variant of the list type is made specifically for displaying a list of documents. It lets you define which documents to list by using a GROQ filter expression (filter) plus optional parameters (params). Note that this list type does not have an items() method - if you want to use specific list items, use the list() method instead.

A document list lists documents

Methods

Shares methods from list

Example

// ./structure.js (.ts)

export const structure = (S) =>
  S.list()
    .title('Content')
    .items([
      S.listItem()
        .title('Future projects')
        .schemaType('sampleProject')
        .child(
          S.documentList()
            .title('Future projects')
            .filter('_type == "sampleProject" && publishedAt > now()')
        )
      ])

Gotcha

Selecting a custom sort order in the Studio will override defaultOrdering and retain that custom sort order in local storage. If your defaultOrdering configuration doesn't appear to be working, try clearing your local storage or opening the Studio in a different browser.

Examples

// src/structure.js

export const structure = (S) => S.documentTypeList('sampleProject')
  S.list()
    .title('Content')
    .items([
      S.listItem('category')
        .title('Projects by category')
        .child(
          S.documentList()
            .title('Projects by category')
            .schemaType('sampleProject') // Because we want menu items for “sampleProjects”
            .filter('_type == "category"')
            .child(id => // Returns the id for the selected category document
              S.documentList()
                .title('Projects by category')
                .schemaType('sampleProject')
                .filter('_type == "sampleProject" && $id in categories[]._ref')
                .params({id}) // use the id in the filter to return sampleProjects that has a reference to the category
            )
        )
      ])

Example

export const structure = (S) =>
  S.list()
    .title('Content')
    .items([
      /* list item(s) goes here */
    ])

List items

listItem():ListItem

A primitive for defining a list item within a list in a collapsible pane. Usually used within the array of S.list().items([/* here */]).

By using the child method on the item, you can control what opens in the next pane when you interact with a listItem. If not defined, it will use the parents' child resolver to determine the next pane.

Methods

  • id(id): ListItem

    Sets the ID for this list item.

    Setting an ID is highly recommended, but if no ID is provided it will be inferred from the title of the list item.

    Parameters

    • idstring

      ID of this list item. If you are intending to open a document, this should generally be a document ID.

  • title(title): ListItem

    Set the title of the list item.

    Parameters

    • titlestring

      Title of the list item

  • icon(icon): ListItem

    Set an icon for the list item.

    Parameters

    • iconfunction

      React component to use as icon.

  • child(child): ListItem

    Sets the child that should be rendered if this item is selected. If you have many list items that should resolve to the same type of child, you should usually set the child resolver on the parent (usually a list) and use the ID to resolve the correct child.

    Parameters

    • childnode | function

      Either a child node (list, document, component etc) or a child resolver function that returns a structure node.

  • schemaType(schemaType): ListItem

    Sets the schema type of this list item, if any. Only used if the list item represents a document.

    Parameters

    • schemaTypestring

      Schema type name

  • showIcon(showIcon): ListItem

    Decide whether or not to show the icon for the list item.

    Parameters

    • showIconboolean
  • getId(): string

    Get the id of the list item, if any

  • getTitle(): string

    Gets the title of the list item, if defined

  • getChild(): node | function

    Get the child or child resolver of the list item, if defined

  • getSchemaType(): string

    Gets the schema type for the list item, if defined

  • getShowIcon(): boolean

    Gets whether or not the icon is shown.

documentListItem():DocumentListItem

Convenience method for returning a list item representing a document.

Prefer this over a regular listItem when manually building a list of items representing documents.

Methods

Shares the same methods as listItem.

documentTypeListItem(schemaType):ListItem

Convenience method for returning a list item representing a document type. In other words, if you want a list item that opens a list of documents of a specific type when clicked, use this. It will automatically configure the title, icon, schema type, and similar.

Arguments

documentTypeListItems():ListItem[]

Convenience method. Returns an array of list items for all defined document types in your schema, and configure them with the correct titles, icons, initial value templates and similar.

Example

export const structure = (S) =>
  S.list()
    .title('Content')
    .items(
      // List all document types except "siteSettings"
      S.documentTypeListItems().filter(
        item => item.getId() !== 'siteSettings'
      )  
    )

divider():

Inserts a visual divider in a list.

Example

//sanity.config.js

import {structure} from './structure'

export default defineConfig({
  ...
  plugins: [
    structureTool({
      structure
    }),
  ],
  schema: schemaTypes
})

// ./structure.js (.ts)

export const structure = (S) =>
  S.list()
    .title('Content')
    .items([
      // Make a singleton of the document with ID “siteSettings”
      S.documentListItem()
        .id('siteSettings')
        .schemaType('siteSettings'),
      // Add a visual divider
      S.divider(),
      // Add the rest of the document types, but filter out the siteSettings type defined above
      ...S.documentTypeListItems().filter(
        item => item.getId() !== 'siteSettings'
      )
    ])

Document nodes

The document node type represents (as the title implies) a document. Often, it is referred to as "the editor node" since it's common for it to render a form allowing you to edit the document in question. However, it can also render other "views" of the document, which is why it has a more generic name.

The following methods let you configure what happens when you open a document. If no views are specified for a document node, it will return the default form view.

document():Document

A primitive for defining a document node.

Methods

  • id(id): Document

    Set the id for the document node. Usually picking something like document or documentView is enough to differentiate it. Alternatively, you can use the document ID.

    Parameters

    • idstring

      Identifier for the document node used to reflect the current structure state in the studio’s URL.


  • title(title): Document

    Set the title for the document. Leave blank to use the document title.

    Parameters

    • titlestring

      The title to use for the document

  • documentId(documentId): Document

    Sets the document ID this document node represents

    Parameters

    • documentIdstring

      Document ID to use for this node

  • schemaType(schemaType): Document

    Sets the schema type for this document

    Parameters

    • schemaTypestring

      The schema type name

  • initialValueTemplate(templateId, parameters): Document

    Sets which initial value template should be used for this document (if any).

    Parameters

    • templateIdstring

      ID of the initial value template to use

    • parametersobject

      Object of key-value pairs to be sent to the initial value template

  • views(views): Document

    Defines which views should be rendered for this document. If not defined, it will use the default form view as the only view.

    Currently, there are two view types: form and component.

    The S.form method renders the form for a given document, allowing it to be edited.

    A component renders a custom React component. See the document node views documentation for example usage.

    Parameters

    • viewsView[]

      Array of views to use for this document node

  • child(child): Document

    Sets which structure node to use as the child of this document, in the case where a view allows navigating to one.

    Can either be a structure node (any list, document, component etc) or a child resolver - a function that either syncronously or asyncronously resolves to a structure node.

    Read more about child resolvers in the conceptual guide for the structure builder.

    Parameters

    • childnode | function
  • getId(): string

    Returns the configured ID for this pane, if any

  • getTitle(): string

    Returns the configured title for the pane, if any

  • getDocumentId(): string

    Returns the configured document ID for this document node

  • getSchemaType(): string

    Returns the configured schema type for this editor, if any

  • getInitialValuesTemplate(): string

    Returns the configured initial value template ID, if any

  • getInitialValueTemplateParameters(): object

    Returns the configured parameters for the initial value template, if any

  • getViews(): View[]

    Returns an array of the configured views, if any

  • getChild(): node | function

    Returns the configured child or child resolver for this pane

documentWithInitialValueTemplate(templateId, parameters):Document

Convenience method for building a document node with a specific initial value template and set of parameters. Automatically configures the document with the correct schema type.

Returns a document node and as such, has the same builder methods as document().

Default document node

Many of the nodes in the structure builder (such as the document type list) automatically render a document node as a child if none is provided. While you can take full control of every node in the structure, this is sometimes a bit tedious if you usually return the same document node for every document or schema type.

The structure definition allows for defining a function which is called when the "default" should be resolved.

Gotcha

Note that this is not a function exposed on the Structure Builder API itself - rather, it is a function you declare and export for the Structure Builder to use as a fallback.

While the structure definition you provide is exported as the default export, you can also export a function named getDefaultDocumentNode that will be called in these situations:

getDefaultDocumentNode(options):Document

Export a function named getDefaultDocumentNode that returns an S.document() node to set the default configuration for document nodes (also often referred to as an "editor node" since it often contains the form view used to edit a document).

Arguments

  • optionsobject

    Object of contextual information that can be used to determine which properties the document node should have. Properties:

    • schemaType - The value of a document’s _type.
    • documentId - The ID of the document.

Example

// sanity.config.ts (.js)

import {defineConfig} from 'sanity'
import {structureTool} from 'sanity/structure'
import {structure, defaultDocumentNode} from './structure'
import { schemaTypes } from './schema'

export default defineConfig({
  name: 'default',
  title: 'My Cool Project',
  projectId: 'my-project-id',
  dataset: 'production',
  plugins: [
    structureTool({
      structure,
      defaultDocumentNode,
    }),
  ],
  schema: schemaTypes
})

// ./structure.js (.ts)
import { WebPreview, JsonView } from './previews'

export const structure = (S, context) =>
  S.list()
    .title('Content')
    .items([
      S.listItem()
        .title('Settings')
        .child(
          S.document()
            .schemaType('siteSettings')
            .documentId('siteSettings')
        ),
      ...S.documentTypeListItems()
    ])

export const getDefaultDocumentNode = (S, {schemaType}) => {
 // Conditionally return a different configuration based on the schema type
 if (schemaType === "post") {
   return S.document().views([
     S.view.form(),
     S.view.component(WebPreview).title('Web')
   ])  
 }
 return S.document().views([
   S.view.form(),
   S.view.component(JsonView).title('JSON')
 ])
}

export default S.defaults()

Document node views

Within a document pane, there can be one or more views. If there are more than one view node, they will appear as tabs. The views can be built using methods exposed on S.view - eg S.view.form()

A document can contain several different views that can be split into multiple panes.

View types

form():FormView

The form method returns the default form-based editor for the specified document type.

Methods

Example

S.view.form()

component(reactComponent):ComponentView

The component method takes a React component and renders it into the document view. It's most often used for showing the values of a document in alternative ways to the default document form.

Methods

  • id(id): ComponentView

    ID for the view, used for the URL

    Parameters

    • idstring

      ID of the view

  • title(title): ComponentView

    Sets the title of the view. Appears when there are more than a single view for a document node.

    Parameters

    • titlestring

      The title for the component.

  • component(component): ComponentView

    Sets the React component

    Parameters

    • componentfunction | Component

      The React component to render. The component is rendered with the following props:

      • document
        • published The published values of the document. Returns null if the document isn't published.
        • draft The values from the draft version of the document. Returns null if there isn't a draft, that is, no changes made since last publish, or if the document is in its initial state.
        • historical The values for the selected document revision in the history view.
        • displayed The values for the currently selected document state, in this order of presedence: initial, historical, draft, published.
      • documentId - The ID of the document
      • schemaType - The schema type of the document

  • icon(icon): Component

    Sets an icon for the views tab

    Parameters

    • iconfunction

      React component to use as icon

  • options(options): ComponentView

    Sets additional user-defined options that will be passed to the React component as the options property.

    Parameters

    • optionsobject

      Arbitrary key-value pairs of options for the React component

  • getId(): string

    Returns the ID of the view, if any

  • getTitle(): string

    Returns the title of the view, if any

  • getComponent(): function | Component

    Returns the defined React component to use for the view, if any

  • getIcon(): function

    Returns the defined icon for this view, if any

  • getOptions(): object

    Returns the user-defined options for this view, if any

Example


export const structure = (S) =>
  S.documentTypeList('sampleProject')
    .child(id =>
      S.document()
        .schemaType('sampleProject')
        .documentId(id)
        .views([
          // The default form for editing a document
          S.view.form(),
          
          // Render the current selected document’s values as JSON
          S.view.component(({document}) => (
            <pre>{JSON.stringify(document.displayed, null, 2)}</pre>
          )).title('View JSON')
        ])
    )

Menus

A menu is located at the top right corner in each collapsible pane

Each pane may have a menu in its upper right corner. This is where you usually find ordering options and affordances for adding new documents. Menus can also hold initial value templates. The convenience list methods will automatically set up default menus for you (some of these may also require that you add schemaType()).

menuItem():MenuItem

Methods

  • title(title): MenuItem

    Sets the title for the menu item.

    Parameters

    • titlestring

      Title of the menu item

  • icon(icon): MenuItem

    Sets the icon for the menu item.

    Parameters

    • iconfunction

      React component to use as the icon

  • action(action): MenuItem

    Sets the action that should be performed when the menu item is selected. Can either be a function or a string.

    If specifying a function, that function will be called with any configured params as the first argument when the item is clicked.

    If specifying a string, the menu will attempt to look for an object named actionHandlers on the React pane component holding the menu, and find a method with a matching name there. The function will be called with any configured params as the first argument when the item is clicked.

    Parameters

    • actionstring | function
  • params(params): MenuItem

    Sets an arbitrary object of parameters to pass to the action handler defined by action(), when clicked.

    Parameters

    • paramsobject

      Arbitrary set of key-value parameters for the action

  • intent(intent): MenuItem

    Sets an intent that should be performed when clicking this menu item.

    An intent is an object with a type key with either the value create or edit, and an optional set of parameters specified as params.

    For the edit intent, the type and id properties are required (document type name and document ID, respectively): {type: 'edit', params: {id: 'documentID', type: 'person'}}

    For the create intent, specifying a type is required. If you want to use a specific Initial Value Template, you can specify a template parameter with the ID of the template you want to use: {type: 'create', params: {type: 'person', template: 'book-author'}}

    If you want to pass arbitrary parameters to the initial value template, you can use the array form of specifying parameters, where the first element of the array defines the actual intent parameters, while the second element defines the arbitrary template parameters: {type: 'create', params: [{type: 'person', template: 'book-author'}, {some: 'template-param'}]}

    Note that intent and action are mutually exclusive.

    Parameters

    • intentIntent
  • showAsAction(showAsAction): MenuItem

    Sets whether or not the menu item should be displayed as an action instead of being part of the dropdown menu.

    Actions appear next to the pane title and must be given an icon, since they have no room for a title unless hovered.

    Parameters

    • showAsActionboolean
  • getTitle(): string

    Returns the title of the menu item.

  • getIcon(): function

    Returns the icon for the menu item.

  • getAction(): function | string

    Returns the defined action for the menu item, if any

  • getParams(): object

    Returns the parameters for the menu item.

  • getIntent(): Intent

    Returns the intent for the menu item.

  • getShowAsAction(): boolean

    Returns whether or not the menu item is set to show as an action or not.

orderingMenuItem({title, by}):MenuItem

Convenience method for populating the menu for selecting different fields and directions for ordering a list of documents.

Arguments

  • REQUIREDtitlestring

    Title of the ordering to show in the menu

  • REQUIREDbyarray

    An array of objects consisting of the field to sort by and the direction of the ordering (asc or desc). See example below.

Example

 S.documentList()
  .title("Products")
  .filter("_type == $type")
  .params({ type: "product" })
  .menuItems([
    ...S.documentTypeList("product").getMenuItems(),
    S.orderingMenuItem({title: 'Title ascending', by: [{field: 'title', direction: 'asc'}]}),
    S.orderingMenuItem({title: 'Title descending', by: [{field: 'title', direction: 'desc'}]})
  ])

orderingMenuItemsForType(typeName):MenuItem[]

Convenience method for returning an array of menu items used to order documents of a given schema type, based on the orderings defined in the schema definition.

Arguments

  • REQUIREDschemaTypestring

    Schema type name to return orderings for

menuItemsFromInitialValueTemplateItems(items):MenuItem[]

Convenience method for returning an array of menu items used to create new documents based on the given initial value template items.

Note: You should consider using the initialValueTemplates() method on the pane instead of this method unless you want the menu items to be nested inside the actual menu.

Arguments

  • REQUIREDitemsInitialValueTemplateItem[]

    Initial value template items. Use S.initialValueTemplateItem() to generate these.

Example

 S.documentList()
  .title('Craft beer & cider')
  .filter('_type in $types && isCraft == true')
  .params({types: ['beer', 'cider']})
  .menuItems(
    S.menuItemsFromInitialValueTemplateItems([
      S.initialValueTemplateItem('beer', {isCraft: true}),
      S.initialValueTemplateItem('cider', {isCraft: true}),
    ])
  )

Was this article helpful?