Skip to main content

definePlugin

Defines a plugin for Sanity Studio. Plugins are reusable bundles of functionality that can extend the studio with custom schema types, tools, document actions, form components, and more.

Function Signature

function definePlugin<TOptions = void>(
  arg: PluginFactory<TOptions> | PluginOptions
): Plugin<TOptions>

type PluginFactory<TOptions> = (options: TOptions) => PluginOptions
The definePlugin function accepts either:
  • A plugin configuration object (for plugins without options)
  • A factory function that receives options and returns a plugin configuration (for configurable plugins)

Parameters

Plugin Configuration

name
string
required
The name of the plugin. Should be unique and descriptive.
schema
SchemaPluginOptions
Schema types and templates provided by the plugin.
schema.types
SchemaTypeDefinition[]
Array of schema type definitions to add to the studio.
schema.templates
Template[]
Initial value templates for creating new documents.
plugins
Plugin[]
Other plugins that this plugin depends on. Allows plugin composition.
tools
Tool[] | ComposableOption<Tool[], ConfigContext>
Tools to add to the studio. Can be an array or a function that receives previous tools and returns a new array.
document
DocumentPluginOptions
Document-level configuration.
document.actions
DocumentActionComponent[] | DocumentActionsResolver
Document actions to add or modify.
document.badges
DocumentBadgeComponent[] | DocumentBadgesResolver
Document badges to display.
document.inspectors
DocumentInspector[] | DocumentInspectorsResolver
Document inspectors for the inspect panel.
document.newDocumentOptions
NewDocumentOptionsResolver
Controls which document types appear in the “Create new” dialog.
form
SanityFormConfig
Form-level configuration.
form.components
FormComponents
Custom form components to override defaults.
form.image.assetSources
AssetSource[]
Asset sources for image fields.
form.file.assetSources
AssetSource[]
Asset sources for file fields.
studio
object
Studio-level component customization.
studio.components
StudioComponentsPluginOptions
Custom studio components (layout, navbar, etc.).
i18n
LocalePluginOptions
Internationalization configuration for the plugin.

Return Value

plugin
Plugin<TOptions>
Returns a plugin function that can be passed to the plugins array in defineConfig.

Examples

Simple Plugin

import {definePlugin, defineType} from 'sanity'

export const myPlugin = definePlugin({
  name: 'my-plugin',
  schema: {
    types: [
      defineType({
        name: 'customType',
        type: 'document',
        fields: [
          {
            name: 'title',
            type: 'string',
          },
        ],
      }),
    ],
  },
})

Plugin with Options

import {definePlugin} from 'sanity'

interface MyPluginOptions {
  customOption?: string
  enableFeature?: boolean
}

export const myPlugin = definePlugin<MyPluginOptions>((options) => {
  const {customOption = 'default', enableFeature = true} = options
  
  return {
    name: 'my-plugin',
    schema: {
      types: [
        // Schema types based on options
      ],
    },
    tools: enableFeature ? [
      {
        name: 'my-tool',
        title: 'My Tool',
        component: MyToolComponent,
      },
    ] : [],
  }
})

// Usage in sanity.config.ts
import {defineConfig} from 'sanity'
import {myPlugin} from './plugins/myPlugin'

export default defineConfig({
  // ...
  plugins: [
    myPlugin({
      customOption: 'custom',
      enableFeature: true,
    }),
  ],
})

Plugin with Document Actions

import {definePlugin} from 'sanity'
import {type DocumentActionComponent} from 'sanity'

const customAction: DocumentActionComponent = (props) => {
  return {
    label: 'Custom Action',
    onHandle: () => {
      // Action logic
    },
  }
}

export const myPlugin = definePlugin({
  name: 'my-plugin',
  document: {
    actions: (prev, context) => {
      // Add custom action to specific document types
      if (context.schemaType === 'post') {
        return [...prev, customAction]
      }
      return prev
    },
  },
})

Plugin with Custom Tool

import {definePlugin} from 'sanity'
import {MyToolComponent} from './components/MyTool'
import {RocketIcon} from '@sanity/icons'

export const myPlugin = definePlugin({
  name: 'my-plugin',
  tools: [
    {
      name: 'my-tool',
      title: 'My Tool',
      icon: RocketIcon,
      component: MyToolComponent,
    },
  ],
})

Plugin Composition

import {definePlugin} from 'sanity'
import {otherPlugin} from 'other-plugin'

export const myPlugin = definePlugin({
  name: 'my-plugin',
  // This plugin depends on another plugin
  plugins: [otherPlugin()],
  schema: {
    types: [
      // Types that may use features from otherPlugin
    ],
  },
})

Real-World Example from Source

import {definePlugin} from 'sanity'
import {structureTool} from 'sanity/structure'
import {visionTool} from '@sanity/vision'

const sharedSettings = ({projectId}: {projectId: string}) => {
  return definePlugin({
    name: 'sharedSettings',
    schema: {
      types: createSchemaTypes(projectId),
      templates: resolveInitialValueTemplates,
    },
    form: {
      image: {
        assetSources: [imageAssetSource, unsplashAssetSource],
      },
      file: {
        assetSources: [imageAssetSource],
      },
    },
    document: {
      actions: documentActions,
      newDocumentOptions,
    },
    plugins: [
      structureTool(),
      visionTool(),
    ],
  })()
}

Validation

The definePlugin function validates that:
  • projectId is not included in plugin configuration (only allowed in workspace config)
  • dataset is not included in plugin configuration (only allowed in workspace config)
These properties must be defined at the workspace level in defineConfig.

Source Location

packages/sanity/src/core/config/definePlugin.ts:26

Build docs developers (and LLMs) love