⚡️ Gearbox Sanity Schema Tool
Fully typed Sanity plugin to make writing Sanity schema faster and better with thoughtful defaults, succinct field definition syntax, and useful helpers. Built on top of Sanity's defineField
functions to benefit from their improved DX.
Features:
- Shorthand syntax for defining fields (ie.
F.slug()
,F.string({ name: 'Foo' })
) - Custom fields for common schema use cases
-
group
andfieldset
helpers to make grouping fields simple and clear - Configurable default schema values for schema types
-
Extendible custom schema types (ie.
F.dropdown()
)
Installation
yarn
yarn add @gearbox-built/sanity-schema-tool
npm
npm install @gearbox-built/sanity-schema-tool
Usage
By default, this plugin doesn't require any initialization. Custom configuration is handled via a Higher-Order Function (HOF). Adding the plugin to the
sanity.config.ts
(or.js
) config is not required.
Import @gearbox-built/sanity-schema-tool
to start using. Exports are organized by field types:
-
F
: Fields -
FS
: Fieldsets -
G
: Groups -
P
: Preview -
V
: Validation
Simple Example
https://www.sanity.io/docs/document-type
import { F } from `@gearbox-built/sanity-schema-tool`
export const movie = F.document({
name: 'movie',
fields: [
F.title(),
F.image({ name: 'poster' }),
F.array({ name: 'directors', of: [F.string()]})
]
})
export const movie = {
title: 'Movie',
name: 'movie',
type: 'document',
fields: [
{
title: 'Title',
name: 'title',
type: 'string',
},
{
title: 'Poster',
name: 'poster',
type: 'image',
},
{
title: 'Directors',
name: 'directors',
type: 'array',
of: [{type: 'string'}],
},
],
}
Groups Example
import {AiOutlineHome as icon} from 'react-icons/ai'
import {F, G, P} from '@gearbox-built/sanity-schema-tool'
export const page = F.document({
icon,
name: 'page',
groups: [G.define('content'), G.define('meta'), G.define('seo', {title: 'SEO'})],
fields: [
...G.group('content', [F.title(), F.field('hero'), F.field('components')]),
...G.group('meta', [F.slug(), F.field('path')]),
...G.group('seo', [F.seo()]),
],
preview: P.titleImage(),
})
export const page = {
icon
title: 'Page',
name: 'page',
type: 'document',
groups: [
{ name: 'content', title: 'Content' },
{ name: 'meta', title: 'Meta' },
{ name: 'seo', title: 'SEO' },
],
fields: [
{
title: 'Title',
name: 'title',
type: 'string',
group: 'content',
},
{
title: 'Hero',
name: 'hero',
type: 'hero'
group: 'content',
},
{
title: 'Components',
name: 'components',
type: 'components',
group: 'content',
},
{
title: 'Slug',
name: 'slug',
type: 'slug',
group: 'meta',
},
{
title: 'Path',
name: 'path',
type: 'path',
group: 'meta',
},
{
title: 'SEO',
name: 'seo',
type: 'seo',
group: 'seo',
}
],
preview: {
select: {
title: 'title',
media: 'image',
}
}
}
Customization
Use the provided withConfig
function to configure the Schema Tool to set meaningful defaults for your project.
// schemaTool.ts
import {F as _F, withConfig} from '@gearbox-built/sanity-schema-tool'
const {F, FS, G, P, V} = withConfig({
image: {
components: {input: ImageInput},
fields: [_F.string({name: 'lqip', hidden: true})],
},
slug: {
required: false,
},
})
export {F, FS, G, P, V}
export type * from '@gearbox-built/sanity-schema-tool'
If you don't want to rename your F
import because of reasons, you can just export the configured Schema Tool with types in this manner:
// schemaTool/config.ts
import {F, withConfig} from '@gearbox-built/sanity-schema-tool'
export default withConfig({
image: {
components: {input: ImageInput},
fields: [F.string({name: 'lqip', hidden: true})],
},
slug: {
required: false,
},
})
// schemaTool/index.ts
import schemaToolConfig from './config'
export type * from '@gearbox-built/sanity-schema-tool'
const {F, FS, G, P, V} = schemaToolConfig
export {F, FS, G, P, V}
Usage
import { F } from `@/schemaTool` // or your path `../../schemaTool`
export const movie = F.document({
name: 'movie',
fields: [
F.title(),
F.image({ name: 'poster' }),
F.array({ name: 'directors', of: [F.string()]})
]
})
Extension
The withConfig
allows for the definition of custom types by passing an object with the keys of F
, FS
, G
, P
, or V
as the second parameter.
import {F, withConfig, StringField, FieldReturn} from '@gearbox-built/sanity-schema-tool'
export const customTypes = {
F: {
dropdown: (list: string[], props: StringField): FieldReturn =>
F.string({options: {list, layout: 'dropdown'}}, props),
},
}
export default withConfig({}, customTypes)
For the best DX, you'll want to extend the appropriate types to get IntelliSense to pick up your custom types:
declare module '@gearbox-built/sanity-schema-tool' {
export namespace F {
var dropdown: typeof customTypes.F.dropdown
}
}
Usage
You can then use your custom types in your schema:
import { F } from `@/schemaTool` // or your path `../../schemaTool`
export const movie = F.document({
name: 'movie',
fields: [
F.title(),
F.image({ name: 'poster' }),
F.array({ name: 'directors', of: [F.string()]}),
F.dropdown(['a', 'b', 'c'], { name: 'type' }),
]
})
Example Config
import {F as _F, withConfig, StringField, FieldReturn} from '@gearbox-built/sanity-schema-tool'
declare module '@gearbox-built/sanity-schema-tool' {
export namespace F {
var dropdown: typeof customTypes.F.dropdown
}
}
export const customTypes = {
F: {
dropdown: (list: string[], props: StringField): FieldReturn =>
_F.string({options: {list, layout: 'dropdown'}}, props),
},
}
export default withConfig(
{
image: {
components: {input: ImageInput},
fields: [_F.string({name: 'lqip', hidden: true})],
},
slug: {
required: false,
},
},
customTypes
)
License
MIT © Gearbox Development Inc.
Develop & test
This plugin uses @sanity/plugin-kit with default configuration for build & watch scripts.
See Testing a plugin in Sanity Studio on how to run this plugin with hotreload in the studio.