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

react-portable-text

v0.6.0

Published

An easy way to render Portable Text block content in React applications.

Downloads

10,342

Readme

React Portable Text

Latest version Open issues

An easy way to render Portable Text block content in React applications.

Quick Example

yarn add react-portable-text
import PortableText from "react-portable-text"

const YourComponent = ({ portableTextContent }) => (
  <div>
    <PortableText
      // Pass in block content straight from Sanity.io
      content={portableTextContent}
      // Optionally override marks, decorators, blocks, etc. in a flat
      // structure without doing any gymnastics
      serializers={{
        h1: (props) => <h1 style={{ color: "red" }} {...props} />,
        li: ({ children }) => <li className="special-list-item">{children}</li>,
        someCustomType: YourComponent,
      }}
    />
  </div>
)

Why not just use @sanity/block-content-to-react directly?

I found it difficult to create abstractions on top of @sanity/block-content-to-react. Remembering whether a serializer needed to be codified as a type, a mark, or as something under block was challenging, and the special treatment for lists and list items was confusing. Further, the props being wrapped in an object under the node property, or extraneous props for mark types meant I was creating intermediate component types just to avoid passing invalid props to the React elements (otherwise they render in the DOM).

React Portable Text uses @sanity/block-content-to-react under the hood, but maps each of these types to the correct place in the serializers for you and normalizing props to match the fields supplied by users in your Sanity Studio, simplifying the cognitive load required to author new ones.

Serializer Documentation

React Portable Text maps the following types explicitly, and treats all other properties of the serializers object as custom types. Custom types are used for both type and block blocks (i.e. custom marks as well as custom block-level insertion types).

| Serializer | Notes | | ----------------- | ---------------------------------------------------------------------------------------- | | Marks | | link | All link marks used for anchor links | | strong | Bold/strong text | | em | Emphasized/italic text | | underline | Underlined text | | del | Text with strikethrough styles | | code | Inline text with code styling | | Lists | | ul | Unordered lists | | ol | Ordered lists | | li | List items for any type of list | | Blocks | | h1 | Heading level 1 | | h2 | Heading level 2 | | h3 | Heading level 3 | | h4 | Heading level 4 | | h5 | Heading level 5 | | h6 | Heading level 6 | | normal | Paragraph styles | | blockquote | Blockquote styles | | Special Types | | | container | Override the component wrapping the blocks | | block | Override the default block serializer (not recommended) | | span | Override the default span serializer (not recommended) | | hardBreak | Serializer for newlines; defaults to br; pass false to preserve newlines | | unknownType | Fallback for blocks of unknown type, if ignoreUnknownTypes is set to false (default) | | unknownMark | Fallback for marks of unknown type; defaults to a plain span |

Additional Props

Additional props are passed through to @sanity/block-content-to-react, so if you want to configure imageOptions or set the projectId and dataset options you can just pass them directly to React Portable Text:

<PortableText
  content={blockContent}
  projectId={process.env.SANITY_PROJECT_ID}
  dataset={process.env.SANITY_DATASET}
/>

Rendering Plain Text

As a bonus, react-portable-text offers a function that will render your portable text content to a plaintext string. This is often useful for previews and such in the Studio and for ancillary uses of content in contexts where formatting is not supported (e.g. calendar invite descriptions, meta tags, etc.).

import { blockContentToPlainText } from "react-portable-text"

const MetaDescription = ({ content }) => (
  <meta name="description" content={blockContentToPlainText(content)} />
)

Contributing

Did I miss something? Is something not compatible with your setup? Open an issue with details, and if possible, a CodeSandbox reproduction. Pull requests are also welcomed!

License

Copyright ©2022 Corey Ward. Available under the MIT License.