Component API
The Component API enables you to change the look and feel of your studio and craft tailor-made editorial interactions.
The Component API lets you customize your editorial experience by overriding different parts of the Sanity Studio with your own components written in React. The components available to customize can be split into two main categories: studio components and form components.
The studio.components
configuration property accepts replacements for several parts of the studio UI, such as the layout
, logo
, navbar
, and toolMenu
. Studio components can be declared in your root workspace configuration, i.e. the defineConfig
function, or as part of a plugin config, i.e. the definePlugin
function.
// sanity.config.js
import {defineConfig} from 'sanity'
export default defineConfig({
// ...rest of config
studio: {
components: {
layout: MyLayout,
logo: MyLogo,
navbar: MyNavbar,
toolMenu: MyToolMenu,
},
},
})
The form.components
property deals with the rendering of form fields and inputs in the studio. The components available for customizing are field
, input
, item
and preview
. Form components can be declared in your root workspace configuration, i.e. the defineConfig
function, as part of a plugin config, i.e. the definePlugin
function, or individually on any field in your schemas.
// sanity.config.js
import {defineConfig} from 'sanity'
export default defineConfig({
// ...rest of config
form: {
components: {
field: MyField,
input: MyInput,
item: MyItem,
preview: MyPreview,
},
},
})
The components available in this API are rendered using a middleware pattern. This means that plugin customizations are applied cumulatively in a chain or cascade. Each component declaration receives a callback function named renderDefault
which, as the name implies, will defer to the default studio rendering of the component. When you call renderDefault
you also pass along the props
needed to render the component, with any changes you care to make.
import { Stack, Card, Flex, Text } from '@sanity/ui'
// Adds markup and invokes renderDefault()
function MyEnhancedNavbar(props) {
return (
<Stack>
<Card padding={3} tone="caution">
<Flex justify="center">
<Text>Important reminder! Remember this banner!</Text>
</Flex>
</Card>
<>{props.renderDefault(props)}</>
</Stack>
)
}
You may opt not to call renderDefault
if you want to replace the component in question in its entirety with your own markup, but be aware that doing so in a plugin might result in unexpected behavior as it breaks the middleware chain.
In the next example we’ll see how the studio handles rendering customization from two different custom logo
components.
import {defineConfig, definePlugin} from 'sanity'
// This custom component will be declared at the root configuration level
function MyCustomLogo(props) {
return (
<div style={{ border: '3px solid skyblue', padding: 4 }}>
{props.renderDefault({ ...props, title: props.title.toUpperCase() })}
</div>
)
}
// Then we add another custom logo component as part of a plugin
const myLogoPlugin = definePlugin({
name: 'my-logo-plugin',
studio: {
components: {
logo: (props) => (
<div style={{border: '3px solid hotpink'}}>
{props.renderDefault({...props, title: 'my improved title'})}
</div>
),
},
},
})
// We then include both components in our studio configuration
export default defineConfig({
name: 'components-api-tests',
title: 'Components API Tests',
projectId: '<projectId>',
dataset: 'production',
studio: {
components: {
logo: MyCustomLogo,
},
},
plugins: [deskTool(), myLogoPlugin()],
/* ...rest of studio config */
})
- Brand your studio with a custom
logo
or add a banner to yournavbar
- Hide certain tools when the studio is in development mode with a custom
toolMenu
- Wrap your studio with multiple context providers with a custom
layout
component - Create a custom
input
to display a range slider on anumber
field, or add a character counter on allstring
fields