sanity-default-plugins

Create and wire Sanity core plugins using the monorepo's default plugin conventions. Use when adding, modifying, or reviewing plugins under…

npx skills add https://github.com/sanity-io/sanity --skill sanity-default-plugins

Sanity Core Plugin

Start Here

Before adding a core plugin, read the sanity-plugin-authoring skill at ../sanity-plugin-authoring/SKILL.md to understand the general Sanity plugin API and what plugins can provide. Then inspect nearby plugins and these files:

  • packages/sanity/src/core/config/resolveDefaultPlugins.ts
  • packages/sanity/src/core/config/types.ts
  • packages/sanity/src/core/config/studio/types.ts
  • A similar plugin under packages/sanity/src/core/*/plugin/

The new plugin should be added inside core so it can be imported into the default plugins.

Prefer local patterns over new abstractions.

Plugin Shape

Use definePlugin and export a stable internal name constant:

import {definePlugin} from '../../config/definePlugin'

export const FEATURE_NAME = 'sanity/feature'

export const feature = definePlugin({
  name: FEATURE_NAME,
  studio: {
    components: {
      layout: FeatureStudioLayout,
    },
  },
  i18n: {
    bundles: [featureUsEnglishLocaleBundle],
  },
})

Use ../../config/definePlugin when matching existing internal plugin files. ../../config is also available in some folders.

Locale Resources

Default core plugins that render UI text should add a locale resource bundle. Follow the pattern from packages/sanity/src/core/singleDocRelease:

  • packages/sanity/src/core/<feature>/i18n/index.ts: exports the locale namespace, US English bundle, and resource key type.
  • packages/sanity/src/core/<feature>/i18n/resources.ts: exports default locale strings and keyof resource type.
  • packages/sanity/src/core/<feature>/plugin/index.ts: imports the bundle and registers it under i18n.bundles.

Example i18n/index.ts:

import {type LocaleResourceBundle} from '../../i18n'

export const featureNamespace: 'feature' = 'feature'

export const featureUsEnglishLocaleBundle: LocaleResourceBundle = {
  locale: 'en-US',
  namespace: featureNamespace,
  resources: () => import('./resources'),
}

export type {FeatureLocaleResourceKeys} from './resources'

Example i18n/resources.ts:

const featureLocaleStrings = {
  'action.example': 'Example',
}

export type FeatureLocaleResourceKeys = keyof typeof featureLocaleStrings

export default featureLocaleStrings

Example plugin registration:

import {featureUsEnglishLocaleBundle} from '../i18n'

export const feature = definePlugin({
  name: FEATURE_NAME,
  i18n: {
    bundles: [featureUsEnglishLocaleBundle],
  },
})

Default Plugin Wiring

Default core plugins are listed in resolveDefaultPlugins.ts.

  1. Import the plugin and its name constant.
  2. Add the plugin to defaultPlugins(options) in the desired composition order.
  3. If gated, add a plugin.name === FEATURE_NAME branch in getDefaultPlugins.
  4. Add any required options to DefaultPluginsWorkspaceOptions in types.ts.
  5. In getDefaultPluginsOptions, build default plugin options directly from workspace config defaults and spreads. Do not call config property reducers here; reducers belong to resolved source/workspace config, while default plugin options are a lightweight workspace-level input for plugin insertion.
  6. Update packages/sanity/src/core/config/__tests__/resolveConfig.test.ts with focused default plugin tests:
    • The plugin is not added by default.
    • The plugin is added when the proper config flag is enabled.
  7. Add ordering coverage when plugin order affects UI composition.

Example default option shape:

variants: {
  enabled: false,
  ...workspace.beta?.variants,
}

Remember: user plugins are appended before default plugins in prepareConfig.tsx, then the component middleware chain reverses flattened config order. Check the existing chain before relying on wrapper order.

Verification

For default plugin changes, run:

pnpm vitest run --project=sanity packages/sanity/src/core/config/__tests__/resolveConfig.test.ts

Also run lint/read diagnostics for edited files. Add component-level tests only when the plugin changes runtime rendering beyond insertion.

More skills from sanity-io

tdd
sanity-io
Test-driven development with red-green-refactor loop. Use when user wants to build features or fix bugs using TDD, mentions "red-green-refactor", wants…
performance-optimization
sanity-io
Optimizes application performance. Use when performance requirements exist, when you suspect performance regressions, or when Core Web Vitals or load times…
content-experimentation-best-practices
sanity-io
Structured guidance for designing, executing, and analyzing content experiments to improve conversion and engagement. Covers hypothesis frameworks, metric selection, sample size calculation, and statistical significance testing across A/B and multivariate experiments Includes detailed resources on p-values, confidence intervals, power analysis, and Bayesian methods for interpreting results Provides CMS integration patterns for managing variants at the field level and connecting external...
content-modeling-best-practices
sanity-io
Structured content modeling guidance for schema design, reusability, and multi-channel delivery. Covers core principles: treating content as data rather than pages, maintaining single sources of truth, designing for future channels, and optimizing for editor workflows Includes decision frameworks for references versus embedded objects, separation of concerns, and content reuse patterns Provides taxonomy and classification guidance for flat, hierarchical, and faceted approaches Applies to...
portable-text-conversion
sanity-io
Convert HTML and Markdown content into Portable Text blocks for Sanity. Use when migrating content from legacy CMSs, importing HTML or Markdown into Sanity,…
portable-text-serialization
sanity-io
Render and serialize Portable Text to React, Svelte, Vue, Astro, HTML, Markdown, and plain text. Use when implementing Portable Text rendering in any frontend…
sanity-best-practices
sanity-io
Comprehensive best practices and integration guides for Sanity CMS development across frameworks and topics. Covers 10+ framework integrations including Next.js, Nuxt, Astro, Remix, SvelteKit, and Angular with framework-specific patterns and setup guidance Includes topic guides for schema design, GROQ query optimization, Visual Editing, Portable Text, images, TypeGen, localization, and content migrations Provides quick-reference structure for loading only relevant guides based on task type,...
sanity-migration
sanity-io
Plans, implements, and reviews migrations from other CMSes and content systems into Sanity. Use when migrating or replatforming to Sanity from AEM, Adobe Experience Manager, Contentful, Strapi, Webflow, WordPress, Payload, Drupal, Markdown/MDX/frontmatter files, WXR/XML exports, CMS APIs, database dumps, static HTML, or when designing extraction, transformation, Portable Text conversion, asset migration, redirects, validation, and cutover workflows.
data-analysisdatabasedevelopment