@storyblok/richtext
@storyblok/richtext a custom resolver for the Storyblok rich text field to be used in JavaScript applications.
Installation
Add the package to a project by running this command in the terminal:
npm install @storyblok/richtext@latest
Usage
Basic
import { richTextResolver } from '@storyblok/richtext';
const { render } = richTextResolver();
const html = render(doc);
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
<div>
${html}
</div>
`;
Overwrite resolvers
import { MarkTypes, richTextResolver } from '@storyblok/richtext';
const html = richTextResolver({
resolvers: {
[MarkTypes.LINK]: (node) => {
return `<button href="${node.attrs?.href}" target="${node.attrs?.target}">${node.children}</button>`;
},
},
}).render(doc);
Optimize images
To optimize images, use the optimizeImages
property on the richTextResolver
options. For a full list of available options, refer to the Image Service documentation.
import { richTextResolver } from '@storyblok/richtext';
const html = richTextResolver({
optimizeImages: {
class: 'my-peformant-image',
loading: 'lazy',
width: 800,
height: 600,
srcset: [400, 800, 1200, 1600],
sizes: ['(max-width: 400px) 100vw', '50vw'],
filters: {
format: 'webp',
quality: 10,
grayscale: true,
blur: 10,
brightness: 10,
},
},
}).render(doc);
Framework usage
The @storyblok/richtext
package is framework-agnostic and can be used with any JavaScript-based frontend framework. Below are examples of how to use the package with different frameworks.
React
For a better developer experience, use the corresponding APIs available in the framework SDK, such as the StoryblokRichText
component in @storyblok/react
. Learn more in the @storyblok/react package reference.
import React from 'react';
import { richTextResolver } from '@storyblok/richtext';
const options: StoryblokRichTextOptions<ReactElement> = {
renderFn: React.createElement,
keyedResolvers: true,
};
const html = richTextResolver(options).render(doc);
// Convert attributes in element to JSX. Refer to the `convertAttributesInElement` function in the playground/react
const formattedHtml = convertAttributesInElement(html);
return <>{formattedHtml}</>;
Refer to playground/react in the package repository for a complete example.
Vue
For a better developer experience, use the corresponding APIs available in the framework SDK, such as the StoryblokRichText
component in @storyblok/vue
. Learn more in the @storyblok/vue package reference.
<script setup>
import type { VNode } from 'vue';
import { createTextVNode, h } from 'vue';
import { BlockTypes, richTextResolver, type StoryblokRichTextNode, type StoryblokRichTextOptions } from '@storyblok/richtext';
const options: StoryblokRichTextOptions<VNode> = {
renderFn: h,
textFn: createTextVNode,
keyedResolvers: true,
};
const root = () => richTextResolver<VNode>(options).render(doc);
</script>
<template>
<root />
</template>
Refer to playground/vue in the package repository for a complete example.
TypeScript Generics
Correct type support in a framework-agnostic way is ensured by using Typescript Generics, circumventing the need to import types and require framework packages as dependencies.
Vanilla: string
const options: StoryblokRichTextOptions<string> = {
resolvers: {
[MarkTypes.LINK]: (node: Node<string>) => {
return `<button href="${node.attrs?.href}" target="${node.attrs?.target}">${node.children}</button>`;
},
},
};
const html = richTextResolver < string > options.render(doc);
React: React.ReactElement
const options: StoryblokRichTextOptions<React.ReactElement> = {
renderFn: React.createElement,
keyedResolvers: true,
};
const root = () => richTextResolver < React.ReactElement > options.render(doc);
Vue: VNode
const options: StoryblokRichTextOptions<VNode> = {
renderFn: h,
keyedResolvers: true,
};
const root = () => richTextResolver < VNode > options.render(doc);
Further resources
Read the tutorial to learn how to sanitize the HTML string output of the rich text resolver.