[![CI](https://github.com/Shelob9/block-content/actions/workflows/main.yml/badge.svg)](https://github.com/Shelob9/block-content/actions/workflows/main.yml) ![npm](https://img.shields.io/npm/v/@shelob9/block-content?style=flat-square)

Usage no npm install needed!

<script type="module">
  import shelob9BlockContent from 'https://cdn.skypack.dev/@shelob9/block-content';


Block Content Renderer

CI npm

Renders "raw" post content with WordPress block markup in it using React components you optionally provide. Uses @wordpress/block-serialization-default-parser.

This works with the "raw" value returned by WordPress REST API for post title, content, excerpt, etc. You must request with ?context=edit which requires permission to edit the post.

BETA Probably don't use. An experiment by Josh Pollock.

Why / Status

WordPress parses block-based content to HTML before displaying it in a front-end theme. This HTML is also returned by the REST API and WPGraphQL. With a JavaScript front-end, in a headless site or what not, you may want to treat the block content as an object for several reasons.

  • Change the markup -- add classes to paragraphs, change element types, etc.
  • Sanitize content
  • Re-order or reformat content.

WordPress' block parser converts blocks to objects. These objects have block attributes and the inner HTML. This library will provide the ability to:

  • ✔️ Remove script and style tags
  • Set a list of allowed elements and attributes (TODO)
  • ✔️ Use your own component library to render block-based content.
  • ✔️ Use block columns.
    • Needs CSS


yarn add @Shelob9/block-content


The <BlockContent> component parses raw blocks to React elements and renders it:

import BlockContent from "@shelob9/block-content";
const Post = ({postTitleRaw,postContentRaw}) => {
  return (
      <BlockContent rawContent={postTitleRaw} />
      <BlockContent rawContent={postContentRaw} />

For saftery reasons, it's best to use <RenderBlockContent />. If given raw content, it works the same as <BlockContent>, but falls back to using rendered HTML.

import {RenderBlockContent} from "@shelob9/block-content";

const PostContent = ({post}) => {
  return (

Theme Provider

Customize Components

To provide your own custom components, wrap your app in the <ThemeProvider> and provide an object of render functions for each element you wish to customize:

import {ThemeProvider} from "@shelob9/block-content";

//A map like object of element type and a render function for each
const components = {
  p => ({children,className}) => (
    <p className={`${className} custom-class`}>{children}</p>
//Wrap everything in the theme provider
const App = () => {
    <ThemeProvider components={}>
      <div>Put the rest of your app here</div>

By default, each allowed element has a basic render function. You can use this to replace a elements with a <Link> element from Gatsby or NextJS.

Restricting Element Types

By default, script and style tags are removed. The rest of this feature is not yet implimented.


yarn start

This builds to /dist and runs the project in watch mode so any edits you save inside src causes a rebuild to /dist.

Then run either Storybook or the example playground:


yarn release


Run inside another terminal:

yarn storybook

This loads the stories from ./stories.


Copyright Josh Pollock. License: GPL 2.0 or later. Please share with your neighbor and feal free to contribute.