npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

astro-portabletext

v0.11.0

Published

Render Portable Text with Astro

Downloads

14,050

Readme

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

  • 🧩 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.

Jump in and see it in action:

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.