Getting images in your Gatsby/Contentful Blog Posts

April 18, 2019

Undoubtedly the most herculean task in building this blog has been learning how to get Contentful's rich text fields to output embedded images in a blog post. A variable Gordian knot of documentation is provided, littered with depreciated versions and scattered fragments of information, the deciphering and navigation of which has taken me the better part of a month to accomplish.

The difficulty of implementation is definitely in the lack of documentation. It seems that although there are many scattered guides on each component of the solution there are very few that actually bring it all together. Therefore to aid those who might be encountering similar problems in the future I'd like to shed some light on the subject through a quick tutorial.

Step 1 Dependencies

There are, two dependencies you'll have to have at the top of each page where you're displaying your rich text data.


You'll need to npm i @contentful/rich-text-react-renderer and npm i @contentful/rich-text-types

Your Gatsby-config.js file will also need to have the following included under plugins


Step 2 Query GraphQL

In order to actually retrieve data that rich-text-react-renderer can use instead of breaking your whole page you'll need to query your content model for JSON.

My query Looks like this:


So, if you just wanted to retrieve the rich text you would query "allContentfulBlog { edges { node { richContent { json } } } }" and "richContent" in this case would be whatever you name your rich text field.

Step 3 Putting it all together

This is the tricky bit, since a lot of the syntax here is unfamiliar to people who are newer to react.

In order to get rich-text-react-renderer to understand what an embedded image asset is you need to give it an options argument. The options argument is essentially a map function and BLOCKS.EMBEDDED_ASSET is their pre-built definition of the rich text image asset type.


So in this example we take the URL retrieved from the embedded asset and say, each time make it an <img> tag and set src to this external URL. Node.data.target.fields.file['en-US'].url is normally where the URL is stored in this situation - a lot of times however gatsby will give out the 'file is undefined' error in which case the solution that I've found would be to double check the 'gatsby-config.js' page and reload the application.

Now, remember when we imported 'documentToReactComponents' at the top of our page? This is where that will be used. 'documentToReactComponents' takes two arguments, the JSON string you retrieved from GraphQL and options which we have made above.


It's important to note that 'documentToReactComponents' directly outputs formatted content so it's pretty much the end of the line for outputting rich text fields.

And that it! rich text should be working and printing images wherever you implemented it, congratulations!