Headless CMS > Integrations
(Legacy) Render Rich Text Content
Learn how to render rich text content from Headless CMS.
- how to render rich text content from Headless CMS in React
Overview
One of the commonly used field types in our Headless CMS is a rich text field. This field uses https://editorjs.io/ with several additional Webiny plugins. The output data structure of editorjs is an array of objects.
You can render this data as you want by traversing the array and implementing renderers for each block type, but more often than not, you just want to use a predefined React component and move on.
To learn how to use Headless CMS GraphQL API, make sure to check out the Using GraphQL API key topic.
Rendering Rich Text Content
To render rich text content created with editorjs in your React app, Webiny provides a package @webiny/react-rich-text-renderer
with a React component to do just that.
Installation
In your React app, install the following dependency:
npm install --save @webiny/react-rich-text-renderer
Or if you prefer yarn:
yarn add @webiny/react-rich-text-renderer
Default Rendering
Fetch your data from Headless CMS, then pass it to the component like this:
import { RichTextRenderer } from "@webiny/react-rich-text-renderer";
// Load content from Headless CMS (here we show what your content might look like).
const content = [
{
type: "paragraph",
data: {
text: "A well written paragraph of text can bring so much joy!",
textAlign: "left",
className: ""
}
}
];
// Mount the component
<RichTextRenderer data={content} />;
Adding Custom Renderers
You can override the default renderers or add new renderers for your custom block types like this:
import { RichTextRenderer, RichTextBlockRenderer } from "@webiny/react-rich-text-renderer";
const customRenderers: Record<string, RichTextBlockRenderer> = {
// Override the default renderer for "delimiter" block
delimiter: () => {
return <div className={"my-custom-delimiter"} />;
},
// Add a renderer for "youtube" block
youtube: block => {
return <iframe width="560" height="315" src={block.data.url} title={block.data.title} />;
}
};
const content = [
// This block will use the default renderer
{
type: "paragraph",
data: {
text: "A well written paragraph of text can bring so much joy!",
textAlign: "left",
className: ""
}
},
// This block will use the custom "delimiter" renderer
{
type: "delimiter"
},
// This block will use the new "youtube" renderer
{
type: "youtube",
data: {
url: "https://www.youtube.com/embed/gOGJKHXntiU",
title: "Webiny Overview"
}
}
];
// Mount the component
<RichTextRenderer data={content} renderers={customRenderers} />;
Styling the Output
Styles for default renderers are included in the package and you can import them into your app like this:
@import "~@webiny/react-rich-text-renderer/styles.scss";
If you don’t want to use the default styles, skip this import and implement your own styling.
HTML Sanitization
This feature is available since Webiny v5.37.2.
In order to minimize the possibility of cross-site scripting (XSS) attacks, the HTML that’s returned by the rich text editor is sanitized, which is done with the help of the sanitize-html library.
Sanitization Configuration
Use configureSanitization
function to set your global sanitization preference.
To provide sanitize configuration to specific component, use sanitizationConfig
prop.
import { RichTextRenderer, configureSanitization } from "@webiny/react-rich-text-renderer";
const globalSanitizaionConfig = {
allowedTags: ["b", "i", "em", "strong", "a"],
allowedAttributes: {
a: ["href"]
},
allowedIframeHostnames: ["www.youtube.com"]
};
// This is global configuration.
configureSanitization(globalSanitizaionConfig);
/*
* Set sanitization configuration options for specific component.
* Note: Provided configuration will override your global configuration options.
* */
const sanitizationConfig = {
// change the configuration only for this option.
allowedIframeHostnames: ["www.webiny.com"]
};
<RichTextRenderer sanitizationConfig={sanitizationConfig} />;
Please check sanitize-html
configuration options on their GitHub page.