Rendering Rich Text elements in headless content management systems (CMS) like Storyblok can be
challenging. We decided to carry out this process with Astro. Here is what we learned in the
process.
Using an official integration
The Storyblok CMS has many integrations for various frontend frameworks including React, Vue,
and Svelte. Luckily for us, they also integrated it for Astro. Astro is the new kid on the
block, with a vibrant and active community and a responsive developer team. These are just a few
of the reasons that we chose Astro for website development.
Headless CMS platforms are designed to provide content through APIs, allowing developers to use
that content in various applications and front-end frameworks. The most straightforward way of
using Storyblok in the Astro framework is through its official{‘ ‘}
Storyblok-Astro integration.
Rich Text elements often contain HTML tags, inline styles, and other formatting options that
need to be properly rendered on the front end. Besides common WYSIWYG (“what you see is what you
get”) editor capabilities, Storyblok is capable of allowing content editors to embed such
elements as inline blocks (components), custom styling, emojis, quotes, and code snippets.
The official integration provides an easy way to render Rich Text by using the renderRichText
function that comes with @storyblok/astro.
{SHORTCODES.blogRelatedArticles}
A challenge
Although the renderRichText from @storyblok/astro works fine and covered our most basic needs,
it quickly turned out to be limiting and problematic for the following reasons:
The renderRichText utility cannot map Rich Text elements to actual Astro components and so
cannot render embedded Storyblok components inside the Rich Text field in CMS.
Links that you might want to pass through your app’s router cannot be reused because they
require the actual function to be mapped with data.
It is hard to maintain the string values, especially when complex needs arise — for example,
when setting classes and other HTML properties dynamically. It may be possible to minimize the
complexity by using some HTML parsers like{‘ ‘}
ultrahtml, but that does not
eliminate the problem entirely.
The solution
Instead of dealing with HTML markup,{‘ ‘}
storyblok-rich-text-astro-renderer
{‘ ‘}
provides a capability to convert any Storyblok CMS Rich Text data structure into the nested
component nodes structure — component, props, content — and render it with Astro. The
configuration is easily extended to meet all project needs.
The package delivers:
The renderRichText.astro helper component, which provides options to map any Storyblok Rich
Text element to any custom component (for example, Astro, SolidJS, Svelte, or Vue).
The resolveRichTextToNodes resolver utility can potentially reuse the transform utility before
rendering the structure manually.
Using the packageThe usage of storyblok-rich-text-astro-renderer is simple, yet flexible:
{`
---
import RichTextRenderer, { type RichTextType } from "storyblok-rich-text-astro-renderer/RichTextRenderer.astro";
import { storyblokEditable } from "@storyblok/astro";
export interface Props {
blok: {
text: RichTextType;
};
}
const { blok } = Astro.props;
const { text } = blok;
---
`}
Sensible default resolvers for marks and nodes are provided out of the box. You only have to
provide resolvers if you want to override the default behavior.
Use resolver to enable and control the rendering of embedded components, and schema to control
how you want the nodes and marks to be rendered.
Conclusion
That’s all there is to it! We just made rendering Storyblok Rich Text in Astro much easier.
The storyblok-rich-text-astro-renderer package offers customization options and improves
frontend development workflow, enabling you to tailor the rendering behavior to your project’s
specific requirements.
Even though Astro supports numerous integrations of React, Svelte, and Vue, when you want to go
with bare Astro, the storyblok-rich-text-astro-renderer package is the right choice.