The Contentful Rich Text field is powerful. But how can you make the most of it? Level up your Rich-Text game with a growing list of top tips from the Contentful DevRel team.
How to wield the power of the Rich Text field
The flexibility of the Rich Text field makes it my favorite feature in Contentful. Developers in our community are adopting the power of the Rich Text field, because it offers exciting versatility for displaying content in your front-end applications. As a result, the DevRel team often receives questions about how to get the most out of this field type.
This post provides advice on how to level up your Rich-Text field game and will be updated regularly with new tips and tricks tailored for the growing Contentful community. Join us in our Community Slack to stay up to date!
If you’d like to learn more about how the Rich Text field is powered by a “what you see is what you get” (WYSIWYG) editor that is returned as pure JSON on the API response, check out this blog post.
We always recommend using a Rich Text renderer package provided by Contentful to speed up your process when working with the Rich Text response. Contentful Rich Text renderers allow you to customise how the JSON response is rendered to your needs. You can render custom HTML, CSS classes, React components, custom attributes and more! A full list of all Rich Text renderers is available on GitHub.
If you’re looking for the Rich Text docs, click here.
Last updated at: July 5, 2021.
Rendering video assets (not iframe embeds) in Rich Text
If you need to display a video file linked in your Rich Text field (rather than an iframe that displays a YouTube or Vimeo embed), here’s how it’s done.
Check out this blog post for more context on rendering linked entries and assets in the Rich Text field, with an example of how to render an iframe as a linked entry using both the GraphQL and REST APIs.
Using the GraphQL API
Here’s an example of a GraphQL query that fetches a blog post with a Rich Text field, and its linked asset blocks (which could be images or video files). The key property on the linked assets we need to query to distinguish between images or video is contentType
.
{
blogPostCollection(limit: 1) {
items {
sys {
id
}
richTextField {
json
links {
assets { // Fetch the linked block assets
block {
sys {
id
}
url
title
width
height
description
contentType // Make sure to request the contentType
}
}
}
}
}
}
}
Here’s an example of how to render a video asset from the GraphQL API response using a switch case alongside an image asset, inside the renderNode options of the @contentful/rich-text-react-renderer.
When you’ve fetched your data, look for the contentType property, and render the video with an HTML video tag to the DOM as you need.
import { BLOCKS } from "@contentful/rich-text-types";
function renderOptions(links) {
// create an asset map
const assetMap = new Map();
// loop through the linked assets and add them to a map
for (const asset of links.assets.block) {
assetMap.set(asset.sys.id, asset);
}
return {
renderNode: {
[BLOCKS.EMBEDDED_ASSET]: (node, next) => {
// find the asset in the assetMap by ID
const asset = assetMap.get(node.data.target.sys.id);
switch (asset.contentType) {
case "video/mp4":
return (
<video width="100%" height="100%" controls>
<source src={asset.url} type="video/mp4" />
</video>
);
case "image/png":
return (
<img
src={asset.url}
height={asset.height}
width={asset.width}
alt={asset.description}
/>
);
default:
return "Nothing to see here...";
}
},
},
};
}
Here’s an equivalent example using the data returned from the REST API using the Contentful JavaScript SDK. Notice how in this example, you don’t need to create a map of the linked assets as with the GraphQL API. The SDK has resolved the links inside the Rich Text field for you.
import { BLOCKS } from "@contentful/rich-text-types";
const renderOptions = {
renderNode: {
[BLOCKS.EMBEDDED_ASSET]: (node, children) => {
const assetType = node.data.target.fields.file.contentType;
switch (assetType) {
case "video/mp4":
return (
<video width="100%" height="100%" controls>
<source src={node.data.target.fields.file.url} type="video/mp4" />
</video>
);
case "image/png":
return (
<img
src={`https://${node.data.target.fields.file.url}`}
height={node.data.target.fields.file.details.image.height}
width={node.data.target.fields.file.details.image.width}
alt={node.data.target.fields.description}
/>
);
default:
return "Nothing to see here...";
}
},
},
};
Rendering line breaks in Rich Text
New lines in the Rich Text response are returned as \n
. You might question why the Rich Text renderers do not replace \n
with <br />
tags as standard — and this is to ensure that the Rich Text renderers remain unopinionated and can be used in applications where <br />
tags might not be valid syntax, such as React Native.
If you’re developing a web application in React, our recommendation is to use the renderText option in the @contentful/rich-text-react-renderer to replace all instances of \n
with <br />
as follows. This code example is taken directly from the @contentful/rich-text-react-renderer README on GitHub.
const renderOptions = {
renderText: text => {
return text.split('\n').reduce((children, textSegment, index) => {
return [...children, index > 0 && <br key={index} />, textSegment];
}, []);
},
};
Copying and pasting into the Rich Text field preserves formatting
Drafted a document in Google Docs? Need to copy some text into the Rich Text field from a web page? No sweat! Copy and paste to your heart’s content and watch as the Rich Text editor gracefully preserves formatting.
Harness the power of Grammarly in the Rich Text Field
The Rich Text Field in the Contentful web app allows for a Grammarly integration. Install the Grammarly browser extension and improve your writing skills as you work in Contentful.
Increase your productivity with Rich Text slash commands
You may already be familiar with the concept of slash commands in applications such as Slack, Discord, Microsoft Teams and Confluence that allow you to perform commands with your keyboard, whenever your cursor is in a text area. The same is available in the Contentful Rich Text field! (Thanks to Spiros for reminding me to add this feature to the list of the top tips!)
Type a “/” and view a list of commands available to you at your fingertips! Use the arrow keys and enter to create and embed inline entries, block entries and assets without leaving the editor — all from the comfort of your keyboard.
Rich Text to plain text? No problem!
There might be times when you need to convert a Rich Text response to plain text. For example, I convert Rich Text to plain text when I build the search results for my personal website, which are powered by Algolia. Read more about how I do this here.
Instead of looping through the Rich Text nodes and constructing the plain text string yourself, we’ve got you covered with a useful package available via npm or yarn.
Install the @contentful/rich-text-plain-text-renderer, and use the documentToPlainTextString function to convert your Rich Text document, like so:
import { documentToPlainTextString } from '@contentful/rich-text-plain-text-renderer';
const document = {
nodeType: 'document',
data: {},
content: [
{
nodeType: 'paragraph',
data: {},
content: [
{
nodeType: 'text',
value: 'Hello',
marks: [{ type: 'bold' }],
data: {}
},
{
nodeType: 'text',
value: ' world!',
marks: [{ type: 'italic' }],
data: {}
},
],
},
]
};
documentToPlainTextString(document); // -> Hello world!
More Rich Text top tips
We’ll update this blog post regularly with more community-tailored Rich Text tips. Is there something you’d like to know how to do in Rich Text or have some tips yourself? Let us know in the Contentful Community Slack.