sanity-plugin-authoring

작성자: sanity-io

Explain and create Sanity Studio plugins using the public plugin and tool APIs. Use when creating user-facing plugins, adding tools through plugins, or when an…

npx skills add https://github.com/sanity-io/sanity --skill sanity-plugin-authoring

Sanity Plugin Authoring

What A Plugin Is

A Sanity Studio plugin is a named configuration bundle that can be added to a Studio through the plugins array. Plugin configuration accepts most workspace config properties, except workspace-owned settings such as dataset, projectId, auth, and theme.

Always give plugins a stable unique name. Prefer definePlugin() so editors expose useful types and autocomplete.

import {definePlugin} from 'sanity'

export const previewUrlPlugin = definePlugin({
  name: 'preview-url-plugin',
  document: {
    productionUrl: async (prev, {document}) => {
      const slug = document.slug?.current
      return slug ? `https://example.com/${slug}` : prev
    },
  },
})

Configurable Plugins

Use definePlugin((options) => ({...})) when callers need to configure behavior.

export const myPlugin = definePlugin<{enabled?: boolean}>((options) => ({
  name: 'my-plugin',
  tools: options.enabled === false ? [] : [myTool],
}))

Keep option namespaces extensible. Prefer object shapes such as {feature: {enabled: true}} instead of direct booleans when future settings are likely.

What Plugins Can Provide

Common plugin properties:

  • document: Document actions, badges, production URL resolvers, and new document defaults.
  • form: Form customizations, asset sources, and custom input rendering.
  • plugins: Nested plugins.
  • tools: Studio tools contributed by the plugin.
  • schema: Schema types and initial value templates.
  • studio: Studio component overrides and middleware.
  • i18n: Locale resource bundles used by plugin UI.
  • title: Human-readable plugin name.
  • onUncaughtError: Custom error handling, logging, or telemetry.

Use the smallest surface that solves the feature.

Tools In Plugins

A tool is a top-level Studio view with routing and predictable URLs. Tools commonly represent full-screen workflows such as Structure, Vision, Dashboard, or Presentation.

When adding a tool through a plugin:

  • Add it through the plugin tools property.
  • Give it a stable name, title, component, and router when needed.
  • Remember tool visual order is affected by the order tools are added, followed by tools added through plugins.
  • Use studio.components.toolMenu when the visual menu order needs custom rendering.
  • Use the top-level tools reducer pattern when changing the default opened tool, because visual menu order alone does not choose the default route.

Studio Components

studio.components can customize parts of the Studio UI. Components that receive renderDefault are middleware: call props.renderDefault(props) unless intentionally replacing the default UI.

Use this for UI wrappers, navigation changes, or tool menu ordering. Be careful not to change scroll containers or layout ownership accidentally.

Locale Resources

If a plugin renders UI text, add an i18n bundle instead of hard-coding user-facing strings. The usual file shape is:

feature/
├── i18n/
│   ├── index.ts
│   └── resources.ts
└── plugin/
    └── index.ts

In i18n/index.ts, define a namespace and default US English bundle:

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'

In i18n/resources.ts, export the default strings and key type:

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

export type FeatureLocaleResourceKeys = keyof typeof featureLocaleStrings

export default featureLocaleStrings

Then register the bundle from the plugin:

import {featureUsEnglishLocaleBundle} from '../i18n'

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

Before Coding

  1. Identify whether the feature is a plugin, a tool, a schema extension, a form extension, or a document extension.
  2. Check existing plugin examples in the repo.
  3. Choose a stable plugin name.
  4. Decide whether the plugin needs options.
  5. Add focused tests for the configured behavior.

For Sanity monorepo default plugin wiring, read sanity-core-plugin after this skill.

References

sanity-io의 다른 스킬

performance-optimization
sanity-io
애플리케이션 성능을 최적화합니다. 성능 요구사항이 있거나, 성능 회귀가 의심되거나, Core Web Vitals 또는 로드 시간이…
official
rxjs-like-a-pro
sanity-io
이 스킬은 관용적이고 조합 가능하며 일반적인 함정이 없는 RxJS 코드를 작성하는 데 도움을 줍니다. 핵심 철학: 로직을 observable 체인 안에 유지하세요. .subscribe()를 사용할 때마다 해당 작업을 .pipe() 내부의 변환으로 표현할 수 있는지 물어보세요.
official
find-skills
sanity-io
사용자가 "X를 어떻게 하죠", "X를 위한 스킬을 찾아줘", "X를 할 수 있는 스킬이 있나요..." 같은 질문을 하거나 특정 요구를 표현할 때 에이전트 스킬을 찾고 설치하도록 도와줍니다.
official
next-cache-components
sanity-io
Next.js 16 캐시 컴포넌트 - PPR, use cache 지시어, cacheLife, cacheTag, updateTag
official
vercel-react-best-practices
sanity-io
Vercel Engineering의 React 및 Next.js 성능 최적화 가이드라인입니다. 이 스킬은 React/Next.js 코드를 작성, 검토 또는 리팩토링할 때 사용해야 합니다.
official
frontend-design
sanity-io
차별화된 프로덕션 수준의 프론트엔드 인터페이스를 높은 디자인 품질로 제작합니다. 사용자가 웹 컴포넌트, 페이지 등을 구축해 달라고 요청할 때 이 스킬을 사용하세요.
official
plugin-transfer
sanity-io
에이전트가 copy-plugin 생성기 워크플로를 사용하여 기존 플러그인을 이 모노레포로 마이그레이션하도록 안내합니다.
official
test-studio-script-runner
sanity-io
dev/test-studio Script Runner 도구를 설명합니다. dev/test-studio/src/script-runner에서 스크립트를 추가, 편집, 실행 또는 문서화할 때 사용하거나...
official