Knut Melvær
Knut is a principal developer marketing manager at Sanity.io
How to automatically generate linked headings with a custom serializer
import PortableText from "@sanity/block-content-to-react";
export const serializers = {
type: {
block: (props) => {
const { node, children } = props
const { style, _key } = node
if (/^h\d/.test(style)) {
const HeadingTag = style;
// Even though HTML5 allows id to start with a digit, we append it with a letter to avoid various JS methods to act up and make problems
const headingId = `h${_key}`;
return (
<HeadingTag id={headingId}>
<a
href={`#${headingId}`}
aria-hidden="true"
tabIndex={-1}
>#</a>
<span>{children}</span>
</HeadingTag>
)
}
// ... you can put in other overrides here
// or return the default ones 👇
return PortableText.defaultSerializers.types.block(props)
}
},
// more custom types here…
}
This is a minimal example of how you can add extra attributes and markup to headings from Portable Text in React. You'd approach this similarly in other frameworks. Here we have a custom serializer for the block
type. It looks after a style
property that contains the pattern with the letter h
and a digit
(so h1
, h2
, h3
, etc).
Then we generate an id from the _key
that comes from the block data. This _key
will be stable as long as the block (that is, the heading) exists. Alternatively, you can generate a readable id from the heading text data in children
.
This markup put's a linked #
inside of the heading, but you can of course do it however you want and add styling to it.
Knut is a principal developer marketing manager at Sanity.io
This can be used for blogs or articles where you want to possibly display next and previous article buttons
Go to Get current post, previous post, and next postMigration script to convert plain text to block content across your content lake
Go to Migrate plain text field to Portable TextSimple content type for a question and answer pattern
Go to Frequently asked questionsSchemas for adding richer quotes within Portable Text
Go to Rich quotations in Portable Text