astro-portabletext
A flexible and customizable library for rendering Portable Text content in Astro projects.
⚠️ Prerequisites:
- Astro v4.6+ (as of
v0.11.0
)
Table of Contents
🚀 Features
- 🧩 Core components: Provides pre-built components for common Portable Text elements.
- 🔧 Customizable: Use
components
or slots
to tailor output to your needs. - 🛠 Flexible control: Use
render
function via usePortableText
to fine-tune rendering. - 📘 Typescript: Built with full TypeScript support.
🎮 Demonstration
Jump in and see it in action:
📖 Resources
📦 Installation
Pick your favorite package manager and run one of these:
npm install astro-portabletext
pnpm add astro-portabletext
yarn add astro-portabletext
bun add astro-portabletext
🧑💻 Usage
Sanity Integration
This library is officially recommended by Sanity for rendering Portable Text in Astro projects.
Helpful resources:
PortableText
component
This component provides a simple and flexible way to display rich text, from
using slots
to custom components
.
Basic usage
Import the PortableText
component and start rendering. This library provides sensible defaults for rendering common Portable Text elements, which you can easily override.
Use the following default mapping to understand what each node type outputs.
View the default structure and output
{
type: {
},
block: {
h1: ,
h2: ,
h3: ,
h4: ,
h5: ,
h6: ,
blockquote: ,
normal:
},
list: {
bullet: ,
number: ,
menu: ,
},
listItem: {
bullet: ,
number: ,
menu: ,
},
mark: {
code: ,
em: ,
link: ,
'strike-through': ,
strong: ,
underline:
},
text:
hardBreak: ,
}
---
import { PortableText } from "astro-portabletext";
const portableText = [
{
_type: "block",
children: [
{
_type: "span",
marks: [],
text: "This is a ",
},
{
_type: "span",
marks: ["strong"],
text: "bold",
},
{
_type: "span",
marks: [],
text: " text example!",
},
],
markDefs: [],
style: "normal",
},
];
---
<PortableText value={portableText} />
Custom components
Custom components allow for better control over rendering of rich text elements. You can map a component to a node type or map the component to the property of the node type.
---
import { PortableText } from "astro-portabletext";
const portableText = [
];
const components = {
type: { [_type]: Component } | Component,
unknownType: Component,
block: { [style]: Component } | Component,
unknownBlock: Component,
list: { [listItem]: Component } | Component,
unknownList: Component,
listItem: { [listItem]: Component } | Component,
unknownListItem: Component,
mark: { [markType]: Component } | Component,
unknownMark: Component,
text: Component,
hardBreak: Component
};
---
<PortableText value={portableText} components={components} />
💡 Refer to custom
components documentation for more details.
Slots
Added in v0.11.0
Slots provide a flexible way to enhance the rendering of Portable Text elements by passing additional props to the component. This allows you to customize the output in various ways, such as:
- Applying custom styles or classes
- Wrapping elements in custom components
- Modifying the output based on specific conditions
Here's an example of using a slot to apply custom styles to strong
elements:
---
import { PortableText } from "astro-portabletext";
const portableText = [
];
---
<PortableText value={portableText}>
<fragment slot="mark">{({ Component, props, children }) => (
<Component {...props} class="mark">{children}</Component>
)}</fragment>
</PortableText>
<style>
.mark:where(strong) {
}
</style>
💡 Refer to slots
documentation for more details.
PortableText
component properties
Property | Type | Description |
---|
value | array or object | Portable Text payload |
components (optional) | object | Mapping of components to node types or its properties. |
onMissingComponent (optional) | function or boolean | Disable warning messages or handle unknown types. Default prints to console. |
listNestingMode (optional) | "html" or "direct" | List nesting mode. Default is html . See ToolkitListNestMode |
Utility functions
This library provides utility functions to help you work with Portable Text content:
import {
usePortableText,
mergeComponents,
toPlainText,
} from "astro-portabletext";
usePortableText
usePortableText(node
: TypedObject): Context
Gives you access to helper functions like render
(added in v0.11.0
), which allows you to fine-tune the output of child nodes in your custom components.
mergeComponents
mergeComponents(components
: SomePortableTextComponents, overrideComponents
: SomePortableTextComponents): object
Combines two sets of components
options, where overrideComponents
takes precedence.
toPlainText
toPlainText(block
): string
Extracts the text content from Portable Text blocks, preserving spacing.
💡 Refer to @portabletext/toolkit
toPlainText documentation for more details.
🙌 Contributing
We welcome contributions to improve astro-portabletext
!
If you find a bug or have a feature request, please open an issue on GitHub.
If you'd like to contribute code, feel free to submit a pull request.
📄 License
This project is licensed under the ISC License.