astro-portabletext
TypeScript icon, indicating that this package has built-in type declarations

0.11.2 • Public • Published
astro-portabletext logo

astro-portabletext

npm license

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
# or
pnpm add astro-portabletext
# or
yarn add astro-portabletext
# or
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: {
    /* 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,
  spanToPlainText, // added in `v0.11.0`
} from "astro-portabletext";

💡 Refer to the utility functions 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.

Package Sidebar

Install

npm i astro-portabletext

Weekly Downloads

4,747

Version

0.11.2

License

ISC

Unpacked Size

68.2 kB

Total Files

25

Last publish

Collaborators

  • theisel