Skip to content

Portable Text

Portable Text renders rich text content with embedded blocks. It follows the Portable Text 🔗 specification and allows for rich formatting and embedded content.

// In your feature descriptor
import { PortableTextDescriptor } from '@vyuh/sanity-schema-system';
export const myFeature = new FeatureDescriptor({
name: 'myFeature',
title: 'My Feature',
contents: [
new PortableTextDescriptor({
// Optional: Define custom marks and blocks
marks: [
// Custom marks
],
blocks: [
// Custom blocks that can be embedded
],
}),
],
});
// Portable Text content object structure
interface PortableText {
_type: 'vyuh.portableText';
blocks: {
_type: 'block';
style: string;
children: {
_type: 'span';
text: string;
marks?: string[];
}[];
markDefs?: {
_key: string;
_type: string;
// Mark-specific properties
}[];
}[];
}

The PortableTextDescriptor in the schema system provides the following extensibility points:

  • annotations: Register custom marks (annotations) for text formatting
  • blocks: Define custom block types that can be embedded within portable text
  • styles: Define custom block styles beyond the default ones
// Schema-side descriptor
new PortableTextDescriptor({
annotations: [highlightMark, tooltipMark],
blocks: [codeBlock, { type: 'vyuh.card' }],
styles: [{ title: 'Callout', value: 'callout' }]
})

In the React system, portable text content is configured using the PortableTextDescriptor:

// React-side registration
import { PortableTextDescriptor } from '@vyuh/react-feature-system';
import { ContentExtensionDescriptor } from '@vyuh/react-extension-content';
import { FeatureDescriptor } from '@vyuh/react-core';
new FeatureDescriptor({
name: 'myFeature',
extensions: [
new ContentExtensionDescriptor({
contents: [
new PortableTextDescriptor({
blockTypes: [
{ type: 'codeBlock', component: CodeBlockComponent },
{ type: 'vyuh.card', component: PortableTextConfig.shared.renderContentItem },
],
marks: [
{ type: 'highlight', component: HighlightComponent },
],
blockStyles: [
{ style: 'callout', component: CalloutComponent },
],
}),
],
}),
],
});