Product
Introducing Java Support in Socket
We're excited to announce that Socket now supports the Java programming language.
@contentful/rich-text-react-renderer
Advanced tools
React renderer for the Contentful rich text field type.
@contentful/rich-text-react-renderer is an npm package that allows developers to render Contentful's rich text content in React applications. It provides a set of tools to convert Contentful's rich text JSON structure into React components, making it easier to display rich text content in a React-based frontend.
Rendering Rich Text
This feature allows you to render Contentful's rich text JSON structure as React components. The code sample demonstrates how to convert a simple rich text document into React elements.
const { documentToReactComponents } = require('@contentful/rich-text-react-renderer');
const richTextDocument = {
nodeType: 'document',
content: [
{
nodeType: 'paragraph',
content: [
{
nodeType: 'text',
value: 'Hello, world!',
marks: [],
data: {}
}
],
data: {}
}
],
data: {}
};
const RichTextComponent = () => (
<div>
{documentToReactComponents(richTextDocument)}
</div>
);
Customizing Renderers
This feature allows you to customize how different node types are rendered. The code sample shows how to apply a custom class to paragraph elements in the rich text content.
const { documentToReactComponents } = require('@contentful/rich-text-react-renderer');
const options = {
renderNode: {
'paragraph': (node, children) => <p className="custom-paragraph">{children}</p>
}
};
const richTextDocument = {
nodeType: 'document',
content: [
{
nodeType: 'paragraph',
content: [
{
nodeType: 'text',
value: 'Hello, world!',
marks: [],
data: {}
}
],
data: {}
}
],
data: {}
};
const RichTextComponent = () => (
<div>
{documentToReactComponents(richTextDocument, options)}
</div>
);
Rendering Embedded Assets
This feature allows you to render embedded assets such as images within the rich text content. The code sample demonstrates how to render an image from the rich text document.
const { documentToReactComponents } = require('@contentful/rich-text-react-renderer');
const options = {
renderNode: {
'embedded-asset-block': (node) => (
<img src={node.data.target.fields.file.url} alt={node.data.target.fields.title} />
)
}
};
const richTextDocument = {
nodeType: 'document',
content: [
{
nodeType: 'embedded-asset-block',
data: {
target: {
fields: {
file: { url: 'https://example.com/image.jpg' },
title: 'Example Image'
}
}
}
}
],
data: {}
};
const RichTextComponent = () => (
<div>
{documentToReactComponents(richTextDocument, options)}
</div>
);
react-markdown is a React component that converts Markdown text to React components. It is similar to @contentful/rich-text-react-renderer in that it transforms a text-based format into React elements, but it specifically handles Markdown rather than Contentful's rich text JSON structure.
draft-js is a framework for building rich text editors in React. It provides a more comprehensive set of tools for creating and managing rich text content, including editing capabilities, whereas @contentful/rich-text-react-renderer focuses on rendering Contentful's rich text JSON.
slate is another framework for building rich text editors in React. It offers a high degree of customization and control over the editor's behavior and output, making it more suitable for complex editing needs compared to @contentful/rich-text-react-renderer, which is primarily for rendering purposes.
React renderer for the Contentful rich text field type.
Using npm:
npm install @contentful/rich-text-react-renderer
Using yarn:
yarn add @contentful/rich-text-react-renderer
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
const document = {
nodeType: 'document',
data: {},
content: [
{
nodeType: 'paragraph',
data: {},
content: [
{
nodeType: 'text',
value: 'Hello world!',
marks: [],
data: {},
},
],
},
],
};
documentToReactComponents(document); // -> <p>Hello world!</p>
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
const document = {
nodeType: 'document',
content: [
{
nodeType: 'paragraph',
content: [
{
nodeType: 'text',
value: 'Hello',
marks: [{ type: 'bold' }],
},
{
nodeType: 'text',
value: ' world!',
marks: [{ type: 'italic' }],
},
],
},
],
};
documentToReactComponents(document);
// -> <p><b>Hello</b><u> world!</u></p>
You can also pass custom renderers for both marks and nodes as an optional parameter like so:
import { BLOCKS, MARKS } from '@contentful/rich-text-types';
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
const document = {
nodeType: 'document',
content: [
{
nodeType: 'paragraph',
content: [
{
nodeType: 'text',
value: 'Hello',
marks: [{ type: 'bold' }],
},
{
nodeType: 'text',
value: ' world!',
marks: [{ type: 'italic' }],
},
],
},
],
};
const Bold = ({ children }) => <p className="bold">{children}</p>;
const Text = ({ children }) => <p className="align-center">{children}</p>;
const options = {
renderMark: {
[MARKS.BOLD]: (text) => <Bold>{text}</Bold>,
},
renderNode: {
[BLOCKS.PARAGRAPH]: (node, children) => <Text>{children}</Text>,
},
renderText: (text) => text.replace('!', '?'),
};
documentToReactComponents(document, options);
// -> <p class="align-center"><p class="bold">Hello</p><u> world?</u></p>
Last, but not least, you can pass a custom rendering component for an embedded entry:
import { BLOCKS } from '@contentful/rich-text-types';
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
const document = {
nodeType: 'document',
content: [
{
nodeType: 'embedded-entry-block',
data: {
target: (...)Link<'Entry'>(...);
},
},
]
};
const CustomComponent = ({ title, description }) => (
<div>
<h2>{title}</h2>
<p>{description}</p>
</div>
);
const options = {
renderNode: {
[BLOCKS.EMBEDDED_ENTRY]: (node) => {
const { title, description } = node.data.target.fields;
return <CustomComponent title={title} description={description} />
}
}
};
documentToReactComponents(document, options);
// -> <div><h2>[title]</h2><p>[description]</p></div>
The renderNode
keys should be one of the following BLOCKS
and INLINES
properties as defined in @contentful/rich-text-types
:
BLOCKS
DOCUMENT
PARAGRAPH
HEADING_1
HEADING_2
HEADING_3
HEADING_4
HEADING_5
HEADING_6
UL_LIST
OL_LIST
LIST_ITEM
QUOTE
HR
EMBEDDED_ENTRY
EMBEDDED_ASSET
EMBEDDED_RESOURCE
INLINES
EMBEDDED_ENTRY
(this is different from the BLOCKS.EMBEDDED_ENTRY
)EMBEDDED_RESOURCE
HYPERLINK
ENTRY_HYPERLINK
ASSET_HYPERLINK
RESOURCE_HYPERLINK
The renderMark
keys should be one of the following MARKS
properties as defined in @contentful/rich-text-types
:
BOLD
ITALIC
UNDERLINE
CODE
The renderText
callback is a function that has a single string argument and returns a React node. Each text node is evaluated individually by this callback. A possible use case for this is to replace instances of \n
produced by Shift + Enter
with <br/>
React elements. This could be accomplished in the following way:
const options = {
renderText: (text) => {
return text.split('\n').reduce((children, textSegment, index) => {
return [...children, index > 0 && <br key={index} />, textSegment];
}, []);
},
};
key
prop in custom renderers:It is possible to pass a key
prop in the components returned by custom renderers. A good use case for this is in embeded entries using the node's target.sys.id
. It is important not to pass anything that is index-like (e.g. 1 or "1") as it may clash with the default renderers which automatically inject a key
prop using their index in the Contentful rich text AST.
To work around this limitation, just append any non-numeric character to your custom key.
const options = {
renderMark: {
[MARKS.BOLD]: (text) => {
return <b key={`${text}-key`}>{text}</b>;
},
},
};
The options
object can include a preserveWhitespace
boolean flag. When set to true
, this flag ensures that multiple spaces in the rich text content are preserved by replacing them with
, and line breaks are maintained with <br />
tags. This is useful for content that relies on specific formatting using spaces and line breaks.
Note that preserveWhitespace
is not compatible with the renderText
option. When the functionality of preserveWhitespace
is desired along with a custom renderText
callback, it should be implemented within the callback instead.
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
const document = {
nodeType: 'document',
content: [
{
nodeType: 'paragraph',
content: [
{
nodeType: 'text',
value: 'Hello world!',
marks: [],
},
],
},
],
};
const options = {
preserveWhitespace: true,
};
documentToReactComponents(document, options);
// -> <p>Hello world!</p>
In this example, the multiple spaces between "Hello" and "world!" are preserved in the rendered output.
FAQs
React renderer for the Contentful rich text field type.
The npm package @contentful/rich-text-react-renderer receives a total of 273,484 weekly downloads. As such, @contentful/rich-text-react-renderer popularity was classified as popular.
We found that @contentful/rich-text-react-renderer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
We're excited to announce that Socket now supports the Java programming language.
Security News
Socket detected a malicious Python package impersonating a popular browser cookie library to steal passwords, screenshots, webcam images, and Discord tokens.
Security News
Deno 2.0 is now available with enhanced package management, full Node.js and npm compatibility, improved performance, and support for major JavaScript frameworks.