Add Inline blocks for the Portable Text Editor - Guide
Enrich your content and add inline blocks to your Portable Text Editor. This guide takes you from schema to query output
Go to Add Inline blocks for the Portable Text EditorPortable Text Editors are a fantastic tool!
Learn how to reduce the height and add a character counter based on the max length set in the field validation.
Sometimes, you need a Portable Text Editor but want it to take up less space in your document form.
In my example, we have a PTE that can only use decorators and annotations, and we need to keep track of the character count. Custom input components make this possible.
// schemas/portableText/overview.tsx
import { CharacterCountInputPTE } from '@/sanity/components/inputs/CharacterCount'
import { defineArrayMember, defineType, PortableTextBlock } from 'sanity'
/** ## `overview` Type - reduced Portable Text
*
* The height of the input is reduced to 2 lines.
*
* @name overview
* @type {PortableTextBlock[]}
* @validation {Rule} - Required, max 280 characters
* @description Used both for the <meta> description tag for SEO, and the personal website subheader.
*
* ### Blocks
* - **Decorators**: `em`, `strong`
* - **Annotations**: none
* - **Styles**: none
* - **Lists**: none
*
*
*/
export default defineType({
name: 'overview',
description: 'Short and on point – max. 280',
title: 'Meta & SEO Description',
type: 'array',
// You can override the max values from the schema by setting a validation on the field
validation: (Rule) => Rule.required().max(280),
components: {
input: CharacterCountInputPTE,
},
of: [
// Paragraphs
defineArrayMember({
lists: [],
marks: {
annotations: [],
decorators: [
{
title: 'Italic',
value: 'em',
},
{
title: 'Strong',
value: 'strong',
},
],
},
styles: [],
type: 'block',
}),
],
})
// * * * Title * * *
defineField({
name: 'title',
type: 'overview',
description: 'This will be used as the H2 of the Sections. Short and on point – max. 200',
// setting a validation on the field will override the validation on the overview schema
validation: (Rule) => Rule.required().max(200),
}),
We use the max
values set on the field schema definition (validation
) and then use them in the component to show users how many characters they already used.
Then we also wrap renderDefault
in a container that we use to change the height of this specific PTE, making sure it's resizable, using styled-components
.
initialActive
set to true allows editors to just focus on the PTE and start writing without the need to activate it.
// CharacterCountInputPTE.tsx
import { Stack, Text } from '@sanity/ui'
import { toPlainText } from 'next-sanity'
import { PortableTextInputProps, StringInputProps } from 'sanity'
import styled from 'styled-components'
import { toPlainText } from 'next-sanity'
export function CharacterCountInputPTE(props: PortableTextInputProps) {
// check if validations exist
// @ts-ignore
const validationRules = props.schemaType.validation[0]._rules || []
const characters = props.value ? toPlainText(props.value).length : 0
//check if max Character validation exists and get the value
const max = validationRules
.filter((rule) => rule.flag === 'max')
.map((rule) => rule.constraint)[0]
return (
<Stack space={3}>
<Container id={'PTE-height-container'}>
{props.renderDefault({
...props,
// remove the need to activate the PTE
initialActive: true,
})}
</Container>
<Text muted align={'right'} size={1}>
Characters: {characters}
{max ? ` / ${max}` : ''}
</Text>
</Stack>
)
}
// add a specific height to the PTE without losing the ability to resize it
const Container = styled.div`
[data-testid='pt-editor'][data-fullscreen='false'] {
height: 100px;
}
`
And that's it! 🥳
Sanity Composable Content Cloud is the headless CMS that gives you (and your team) a content backend to drive websites and applications with modern tooling. It offers a real-time editing environment for content creators that’s easy to configure but designed to be customized with JavaScript and React when needed. With the hosted document store, you query content freely and easily integrate with any framework or data source to distribute and enrich content.
Sanity scales from weekend projects to enterprise needs and is used by companies like Puma, AT&T, Burger King, Tata, and Figma.
Enrich your content and add inline blocks to your Portable Text Editor. This guide takes you from schema to query output
Go to Add Inline blocks for the Portable Text EditorThis Guide will lead you through the all the steps you need to level-up your use of Portable Text: from setting up block content, adding custom blocks and renderers for the Portable Text Editor in your studio. But also help you query for everything and render your awesome content in React!
Go to Adding things to Portable Text - From block content schema to React componentHelp you editors restore deleted documents in a dataset using a webhook and a singleton bin document type.
Go to Create a recycling bin for logging and restoring deleted documentsIn this guide you will learn how to setup such a listener-based structure and also how to combine the results with the workflow plugin metadata.
Go to Dynamic folder structure using the currentUser and workflow statesImplement single sign-on authentication with the SAML protocol and Microsoft Azure AD as the identity provider.
Go to Set up SSO authentication with SAML and AzureAdd values for title, alt text and description to image assets through a custom input component with validation and all! (Code in JS & TS)
Go to Awesome custom input component for metadata