Is there a way to insert a custom component between two fields in schema?

5 replies
Last updated: Nov 9, 2020
Hello,is there a way to insert a custom component ( containing
<hr />
to separate them visually) between two fields in schema?
AI Update

Yes! You can insert a custom component with an <hr /> divider between fields by using a custom field component through the Form Components API.

The key is to use components.field in your schema definition. Field components wrap the entire field (including label and description), which is perfect for adding visual separators. Here's how:

Solution: Custom Field Component with HR Divider

First, create a custom field component:

// components/FieldWithDivider.tsx
import { FieldProps } from 'sanity'

export function FieldWithDivider(props: FieldProps) {
  return (
    <>
      {/* Add your divider before the field */}
      <hr style={{ 
        margin: '2rem 0 1.5rem', 
        border: 'none', 
        borderTop: '1px solid var(--card-border-color)' 
      }} />
      
      {/* Render the default field functionality */}
      {props.renderDefault(props)}
    </>
  )
}

Then apply it to specific fields in your schema:

import { defineField, defineType } from 'sanity'
import { FieldWithDivider } from './components/FieldWithDivider'

export default defineType({
  name: 'myDocument',
  type: 'document',
  fields: [
    defineField({
      name: 'title',
      type: 'string',
    }),
    defineField({
      name: 'description',
      type: 'text',
    }),
    // Add divider before this field
    defineField({
      name: 'content',
      type: 'string',
      components: {
        field: FieldWithDivider  // This adds the divider above
      }
    }),
    defineField({
      name: 'author',
      type: 'string',
    }),
  ],
})

How It Works

The Form Components API supports customization at four levels: field, input, item, and preview. For dividers between fields, you want the field level because it wraps the entire field including its label and validation UI.

The magic is in props.renderDefault(props) - this renders the original field with all its standard functionality (validation, real-time sync, collaboration features, etc.) while letting you add custom elements around it.

Styling Tips

You can customize the divider appearance:

<hr style={{ 
  margin: '2.5rem 0 1.5rem',
  border: 'none',
  borderTop: '2px solid var(--card-border-color)',
  opacity: 0.5
}} />

Or add a text label:

<div style={{ margin: '2rem 0 1rem' }}>
  <hr style={{ border: 'none', borderTop: '1px solid #e0e0e0' }} />
  <p style={{ 
    textAlign: 'center', 
    fontSize: '0.875rem', 
    color: 'var(--card-muted-fg-color)',
    marginTop: '-0.75rem',
    background: 'var(--card-bg-color)',
    display: 'inline-block',
    padding: '0 1rem'
  }}>
    Additional Information
  </p>
</div>
{props.renderDefault(props)}

This approach gives you complete control over where dividers appear and how they look, while maintaining all the standard Sanity field behavior!

I mean for the studio view it self. Something like this, where Break is adding an hr to visually separate the fields

{

title: 'Title',

name: 'title',

type: 'string',

},


{

name: 'Break'

type: 'break'

},


{

title: 'Slug',

name: 'slug',

type: 'slug',

readOnly: true,

},
Aha - the only way to do that today is by a custom input component, something like this:
import React from 'react'

const SectionBreak = () => <hr />

export default {
// ...
  {
    name: 'break',
    type: 'string',
    inputComponent: SectionBreak
  }
// ...  
}
Not super smooth, but it will do the job. That being said, we have plans to make stuff like this easier in the near future.
inputComponent, was looking for that part! Thanks

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?