astro-portabletext
v0.11.0
Published
Render Portable Text with Astro
Downloads
14,050
Maintainers
Readme
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
- 🧩 Core components: Provides pre-built components for common Portable Text elements.
- 🔧 Customizable: Use
components
orslots
to tailor output to your needs. - 🛠 Flexible control: Use
render
function viausePortableText
to fine-tune rendering. - 📘 Typescript: Built with full TypeScript support.
Jump in and see it in action:
- Documentation: Read the full documentation including TypeScript type definitions.
- Examples: Browse practical examples to help you learn.
Pick your favorite package manager and run one of these:
npm install astro-portabletext
# or
pnpm add astro-portabletext
# or
yarn add astro-portabletext
# or
bun add astro-portabletext
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.
{
type: {
/* Custom types go here */
},
block: {
h1: /* <h1 {...attrs}><slot /></h1> */,
h2: /* <h2 {...attrs}><slot /></h2> */,
h3: /* <h3 {...attrs}><slot /></h3> */,
h4: /* <h4 {...attrs}><slot /></h4> */,
h5: /* <h5 {...attrs}><slot /></h5> */,
h6: /* <h6 {...attrs}><slot /></h6> */,
blockquote: /* <blockquote {...attrs}><slot /></blockquote> */,
normal: /* <p {...attrs}><slot /></p> */
},
list: {
bullet: /* <ul {...attrs}><slot /></ul> */,
number: /* <ol {...attrs}><slot /></ol> */,
menu: /* <menu {...attrs}><slot /></menu> */,
},
listItem: {
bullet: /* <li {...attrs}><slot /></li> */,
number: /* <li {...attrs}><slot /></li> */,
menu: /* <li {...attrs}><slot /></li> */,
},
mark: {
code: /* <code {...attrs}><slot /></code> */,
em: /* <em {...attrs}><slot /></em> */,
link: /* <a {...attrs} href="..."><slot /></a> */,
'strike-through': /* <del {...attrs}><slot /></del> */,
strong: /* <strong {...attrs}><slot /></strong> */,
underline: /* <span {...attrs} style="text-decoration: underline;"><slot /></span> */
},
text: /* Renders plain text */
hardBreak: /* <br /> */,
}
/* .astro */
---
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.
/* .astro */
---
import { PortableText } from "astro-portabletext";
const portableText = [
// ... your Portable Text content
];
const components = {
// custom types
type: { [_type]: Component } | Component,
unknownType: Component,
// block style
block: { [style]: Component } | Component,
unknownBlock: Component,
// list
list: { [listItem]: Component } | Component,
unknownList: Component,
// list item
listItem: { [listItem]: Component } | Component,
unknownListItem: Component,
// mark
mark: { [markType]: Component } | Component,
unknownMark: Component,
// strings; added in `v0.11.0`
text: Component,
// line break
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:
/* .astro */
---
import { PortableText } from "astro-portabletext";
const portableText = [
// ... your Portable Text content
];
---
<PortableText value={portableText}>
<fragment slot="mark">{({ Component, props, children }) => (
<Component {...props} class="mark">{children}</Component>
)}</fragment>
</PortableText>
<style>
.mark:where(strong) {
/* some styles */
}
</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.
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.
This project is licensed under the ISC License.