Proper way to enforce a single document type in Sanity schema, with deprecation warning for deskTool.

5 replies
Last updated: Mar 26, 2024
Hey Sanity Team. I am new to using sanity and am wanting to implement a single document type in my schema for my authors. I was looking at the following guide https://www.sanity.io/guides/singleton-document but when I tried to implement it, I got a deprecation warning for deskTool in sanity/desk. What is the proper way to enforce that the author can only implement a single document for one of my schema types? (ex. wanting to make the document for text on a webpage)
AI Update

The guide you're looking at uses the old import path that was updated in Sanity Studio v3! The deskTool from 'sanity/desk' was renamed to structureTool from 'sanity/structure' in v3.24.1, and this is still the current approach in Studio v4.

Here's how to properly implement a singleton document with the updated imports:

Import the correct module:

import { structureTool } from 'sanity/structure'

Full configuration in sanity.config.js:

import { defineConfig } from 'sanity'
import { structureTool } from 'sanity/structure'

// Define the actions that should be available for singleton documents
const singletonActions = new Set(['publish', 'discardChanges', 'restore'])

// Define the singleton document types
const singletonTypes = new Set(['authorSettings'])

export default defineConfig({
  // ... other config
  plugins: [
    structureTool({
      structure: (S) =>
        S.list()
          .title('Content')
          .items([
            // Your singleton document
            S.listItem()
              .title('Author Settings')
              .id('authorSettings')
              .child(
                S.document()
                  .schemaType('authorSettings')
                  .documentId('authorSettings')
              ),
            // Separator
            S.divider(),
            // All other document types
            ...S.documentTypeListItems().filter(
              (listItem) => !singletonTypes.has(listItem.getId())
            ),
          ]),
    }),
  ],

  schema: {
    types: [
      // your schema types including authorSettings
    ],
    // Filter out singleton types from the global "New document" menu
    templates: (templates) =>
      templates.filter(({ schemaType }) => !singletonTypes.has(schemaType)),
  },

  document: {
    // For singleton types, filter out actions that are not explicitly included
    actions: (input, context) =>
      singletonTypes.has(context.schemaType)
        ? input.filter(({ action }) => action && singletonActions.has(action))
        : input,
  },
})

This configuration does three important things:

  1. Creates a direct link to your singleton - The Structure Builder configuration creates a dedicated entry that points to a specific documentId, ensuring only one instance exists

  2. Hides it from the "New document" menu - The schema.templates configuration prevents users from accidentally creating additional instances

  3. Removes problematic actions - The document.actions configuration filters out actions like "duplicate" and "delete" that could cause issues with singletons

Important gotcha: Since this disables the UI for creating new instances, you should create your singleton document first before adding it to the singletonTypes set.

The key fix from the old guide is simply changing the import from deskTool and 'sanity/desk' to structureTool and 'sanity/structure'. Everything else in the singleton pattern works the same way!

If you want an even simpler approach, you can use the singleton-tools plugin which handles all of this configuration automatically.

You are on the right track however like you noticed there is a deprecation warning, switch sanity/desk for sanity/structure.
Or you could use the following plugin -
https://www.sanity.io/plugins/singleton-tools , just used on one of my projects and it's amazing
O snap, I will take a look. Thanks!
Oh hey! I made that plugin. Glad you like it!
Works like charm! Could be just because I am new, but if you impose the singleton option on a schema, how do you make it so that there is a new single document by default? Do I have to create the doc before I set the option?
If you use the
singletonDocumentListItem
in your structure it’ll create a singleton with whatever
id
you pass in the first time you open it.

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?