How would I go about making a document type not deletable? I’ve come as far as adding only once instance to the structurebuilder but it’s still possible to duplicate anddelete...

8 replies
Last updated: Feb 1, 2021
How would I go about making a document type not deletable? I’ve come as far as adding only once instance to the structurebuilder but it’s still possible to duplicate and delete it. Tried with the following: “__experimental_actions: [“update”, /* ‘create’, ‘delete’, */ “publish”],” but it didn’t do anything for it.
AI Update

You're on the right track! The __experimental_actions property you mentioned was from Sanity v2 and is no longer the correct approach in v3. Here's how to properly disable delete and duplicate actions for a document type in the current version of Sanity:

Configure Document Actions in sanity.config.ts

You need to use the document.actions configuration in your sanity.config.ts file. Here's how to filter out the delete and duplicate actions for a specific document type:

import {defineConfig} from 'sanity'

export default defineConfig({
  // ... rest of your config
  document: {
    actions: (prev, context) => {
      // For your singleton document type, remove delete and duplicate actions
      if (context.schemaType === 'yourDocumentType') {
        return prev.filter(
          (action) => action.action !== 'delete' && action.action !== 'duplicate'
        )
      }
      return prev
    },
  },
})

Replace 'yourDocumentType' with the actual name of your document type.

For Multiple Document Types

If you need to apply this to multiple document types:

document: {
  actions: (prev, context) => {
    const singletonTypes = ['settings', 'homepage', 'footer']
    
    if (singletonTypes.includes(context.schemaType)) {
      return prev.filter(
        (action) => !['delete', 'duplicate'].includes(action.action || '')
      )
    }
    return prev
  },
}

Complete Example with Structure Builder

For a singleton pattern, you'd typically combine this with Structure Builder configuration:

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

export default defineConfig({
  // ... other config
  plugins: [
    structureTool({
      structure: (S) =>
        S.list()
          .title('Content')
          .items([
            S.listItem()
              .title('Settings')
              .child(
                S.document()
                  .schemaType('settings')
                  .documentId('settings')
              ),
            // ... other items
          ])
    })
  ],
  document: {
    actions: (prev, context) => {
      if (context.schemaType === 'settings') {
        return prev.filter(
          (action) => action.action !== 'delete' && action.action !== 'duplicate'
        )
      }
      return prev
    },
  },
})

This approach:

  1. Removes delete and duplicate from the document actions menu
  2. Works with Sanity v3's document actions API
  3. Can be scoped to specific document types using the context parameter

The key difference from v2 is that you're now filtering the prev array of actions rather than setting a property on the schema type itself. You can read more about this in the Document Actions documentation.

you can set up custom document actions https://www.sanity.io/docs/document-actions and filter out the DeleteAction. Something like this:

import { DeleteAction } from "part:@sanity/base/document-actions";

export default function resolveDocumentActions(props) {
  if (props.type === "something") {
    return defaultResolve(props).filter(
      (Action) => Action !== DeleteAction
    );
  }
}
Thanks Arjen. That did it for me, I made the following solution:
import defaultResolve from "part:@sanity/base/document-actions";
import { DeleteAction } from "part:@sanity/base/document-actions";

export default function resolveDocumentActions(props) {
  if (props.type === "siteSettings") {
    return [
      ...defaultResolve(props).filter((Action) => Action !== DeleteAction),
    ];
  }
  return [...defaultResolve(props)];
}
user B
Is it possible not to show that menu entirely instead of just delete action? Can’t find it in the API docs
return an empty array?
user B
I tried that but then the publish button disappears
only return the publish action then?

return [PublishAction]
or maybe even

return PublishAction
haven't tried it
Thanks I was missing the name of it
user B
couldnt find it in the docs
This did the trick:
return [
      ...defaultResolve(props).filter((Action) => Action === PublishAction),
    ];

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?