How To Use The Contentful Rich Text Field with Gatsby

Contentful’s Rich Text Editor provides content creators with powerful text editing capabilities via the use of Contentful’s “What you see is what you get” (wysiwyg) editor. When using the editor, content can be easily formatted using all the usual text formatting methods; bold, italic, underline etc, along with providing support for headings, embedded images, block quotes, code snippets, links and lists. 

I used Rich Text recently in the Gatsby Contentful Demo for the blog posts body. You can see the demo site here: Gatsby Demo Contentful 

If you’re looking for the source code this can be found on Gatsby’s GitHub here: gatsby-demo-contentful

Before you dive into the code here’s a quick summary for adding Rich Text to your content models in Contentful. 

Content models in Contentful

After creating a new Content Type from the Contentful App interface Rich Text is made available under the Add field option.

Contentful Rich Text Field

After Rich Text has been added to your content model you can inspect the settings where you’ll see the available formatting options named above.

Contentful Rich Text Settings

With Rich Text enabled creative control can now be handed over to the content creators. Using the wysiwyg editor it’s possible to embed images, format headings, add paragraphs and so forth. But Contentful also makes it simple to limit some of this functionality, striking a balance between authoring creativity and actual development bumpers.

Contentful Rich Text Editor


Data sourcing with Rich Text

With the gatsby-source-contentful plugin installed and configured it’s possible to query the richText field using GraphQL


There are two types of nodes available on richText, the first is called raw, the second is references, i’ll come back to references later.  

Using GraphQL you can query the raw data for e.g all blog posts like this.

This GraphQL query will return a large chunk of some rather spurious looking data, but hang in there I’ll explain this shortly. 

If you have a look at the image below you may notice that amongst the jumbled mass of data are some “clues” as to what the data actually is.

You might notice a line that contains the following…

This loosely translates to: The word “Bacon” uses the mark type bold, and as you might expect the desired result would be that when this pops out in the browser, the word Bacon is in fact bold.

Contentful Rich Text GraphQL

However, you will need to give Rich Text a helping hand in transforming the nodes to their respective HTML types using the “clues” mentioned above. 

To do this the Gatsby Contentful plugin comes with a helper function called renderRichText 

The helper function can be used to “catch” these marks or node types and gives you a little more control over how they will eventually appear in the browser.


To use the helper function import it from the gatsby-source-contentful package

The helper function accepts two arguments, the first is the raw data as queried by GraphQL above, and the second in an options object.

Options object

The options object can be configured as follows. You can see that for the bold text I’ve wrapped it with an HTML <b> element and applied a class name of font-bold. This makes the bold text semantically correct and styles it in an appropriate fashion. 

For hyperlinks i’ve used a similar approach but this time used an HTML <a> element, also note the href attribute which is given the data returned by which is the actual link applied in the wysiwyg editor, i’ve also applied a class name of underline 

Naturally the styles you apply will depend on your requirements but hopefully this will give you an idea of how to transform and style each node type. For the Gatsby Contentful Demo i’ve used TailwindCSS

  • renderMark catches node types like bold, italic, underline.
  • renderNode catches node types like headings, links, lists etc

Each of the types come from Contentful’s rich-text-types package, and you can import them into your page or component like so

You can see the full set of types in the Contentful’s GitHub repository using the links below

Image sourcing with Rich Text

I mentioned earlier that the richText GraphQL type contains two node types, i’ve covered raw above and in this next section i’ll discuss references


References can be used to query Contentful’s Assets. In this case i’ll be using it to query  images that have been embedded using the wysiwyg editor

The two child nodes I query are; description which i’ll use later as alt text, and gatsbyImageData which is all the gatsby-plugin-image goodness! 

I set a default width of 1000px to ensure that even if very large image files are uploaded by content creators Gatsby’s Image plugin will resize them to keep your site blazing fast! 

To “catch” assets of type image I use BLOCKS.EMBEDDED_ASSET and pass the gatsbyImage data onto the <GatsbyImage /> component via the image prop, you’ll also notice I pass the description on via the alt prop.

The GatsbyImage component and the getImage helper function can be imported from the gatsby-plugin-image package as per the below

As with <b> and <a> you can also apply any class names to the <GatsbyImage /> component to suit your needs.

To see the full Rich Text component and all the options i’ve used in the Gatsby Contentful Demo it can be found on GitHub here: gatsby-demo-contentful/src/components/contentful-rich-text.js

I use the component inside the {contentfulPosts.url}.js collection route. You can see that in action on GitHub here: 



You may notice in the demo I’ve applied a few other tricks. For instance, node types that are “headings” have been transformed to apply a jump link so when clicked the blog post will move the browser window to the position of the heading. I achieved this by using Gatsby’s onRouteUpdate from the gatsby-browser API which fires whenever a url is changed. You can see that code in the demo repo on GitHub here: gatsby-demo-contentful/gatsby-browser.js

I also transform all nodes of type <h1> to <h2>. This ensures there’s only ever one <h1> tag used on a blog post regardless of how the wysiwyg editor is used to style headings. 

That just about sums it up. It can be strange at first when looking at that huge lump of data but personally I prefer Contentful’s approach of returning JSON rather than actual HTML as it gives you greater control over the final HTML output for each node type.

I hope you’ve found this helpful and if you have any questions feel free to find me on Twitter: @PaulieScanlon