Fix Astro App Images: Use Contentful Custom Nodes
Fix Astro App Images: Use Contentful Custom Nodes

React: Fix Images Not Rendering in Rich Text from Contentful

Fix Contentful rich-text images not rendering in your React Astro app using @contentful/rich-text-react-renderer custom nodes6 min


Building a content-rich React application with Astro and Contentful can make content management easier and more efficient. Contentful is widely favored for its intuitive rich text editor, which allows editors and content creators to seamlessly integrate media and formatted text into web pages without needing technical know-how. However, developers often run into issues, especially when images embedded directly in Contentful’s rich-text don’t render correctly via React components. If you’re experiencing the frustration of images not appearing on your React-Astro website, you’re not alone—and there’s a straightforward path to solving it.

Understanding the Image Rendering Issue in Contentful Rich Text

The advantage of Contentful is its headless CMS architecture, which allows developers to query structured data and assemble it on-demand. Rich text content fetched from Contentful typically relies on the documentToReactComponents function provided by the @contentful/rich-text-react-renderer package.

What this method effectively does is transform the structured rich text JSON fetched from Contentful into React components ready for display. While text formatting like headers, paragraphs, lists, and even hyperlinks usually render flawlessly, images don’t behave the same way. These images typically don’t render out-of-the-box because their inclusion requires additional configuration that many developers accidentally overlook.

Examining a Real-World React Component Scenario: TrendingArticles Component

Let’s visualize this issue further with a realistic example of a simple React-Astro component called TrendingArticles, used to render rich text fetched from Contentful:


import React from 'react';
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';

const TrendingArticles = ({ article }) => {
  return (
    <div className="article-content">
      {documentToReactComponents(article.content)}
    </div>
  );
};

export default TrendingArticles;

At first glance, this component appears straightforward—fetch article.content JSON from Contentful, convert that JSON into React components, and render them. But while paragraph texts show fine, embedded images strangely stay invisible.

Why Aren’t Images Rendering from Contentful’s Rich Text?

What’s the issue? Contentful doesn’t directly embed images into the rich text JSON as plain image URLs. Instead, the images are structured as embedded assets using the BLOCKS.EMBEDDED_ASSET type. Without explicitly handling this node type in your rich text rendering setup, these images won’t appear.

This means that while the provided renderer automatically manages common elements like paragraphs (p), headers (h1, h2, etc.), and lists (ul, ol), it does nothing special for these embedded images unless explicitly instructed.

To double-check the JSON content you’re receiving, a simple inspection in the browser’s developer console or using a debugging tool might show something like this:


{
  nodeType: "embedded-asset-block",
  content: [],
  data: {
    target: {
      fields: {
        file: {
          url: "//images.ctfassets.net/abc123/example.jpg"
        }
      }
    }
  }
}

This confirms that the image data is there, just not correctly configured within your frontend renderer.

Resolving the Issue: Modifying React Component to Display Images

Luckily, resolving this problem is fairly simple—you must define your custom image-rendering function for documentToReactComponents. Here’s what a properly configured solution would resemble:


import React from 'react';
import { documentToReactComponents } from '@contentful/rich-text-react-renderer';
import { BLOCKS } from '@contentful/rich-text-types';

const TrendingArticles = ({ article }) => {
  
  const options = {
    renderNode: {
      [BLOCKS.EMBEDDED_ASSET]: (node) => {
        const { url, description } = node.data.target.fields.file;
        
        return (
          <img 
            src={`https:${url}`} 
            alt={description || 'Embedded Image from Contentful'} 
            style={{ maxWidth: '100%', height: 'auto' }} 
          />
        );
      }
    }
  };

  return (
    <div className="article-content">
      {documentToReactComponents(article.content, options)}
    </div>
  );
};

export default TrendingArticles;

This code snippet explicitly handles assets tagged as BLOCKS.EMBEDDED_ASSET. In simpler terms, it tells React exactly how to display embedded images, ensuring their visibility alongside other rich-text content.

Make sure to prepend https:// when accessing resource URLs from Contentful as it typically uses protocol-relative URLs beginning with “//”.

Testing the Updated Component to Confirm Image Rendering

After implementing the change, verify instantly in your local development environment. Start your React app or Astro frontend and navigate to a page displaying the problematic element. The previously missing image should now neatly appear embedded in the rich-text content.

If issues persist, a good debugging strategy includes:

  • Inspecting the browser’s developer console for any JavaScript errors or warnings.
  • Logging the node data structure directly to verify URLs and data shapes.
  • Ensuring your Contentful asset permissions and fields are accessible and properly filled.
  • Checking Contentful’s content delivery API documentation: Embedded Assets Documentation.

Always test thoroughly across multiple devices and resolutions to confirm image responsiveness and proper rendering.

Additional SEO & Performance Tips When Rendering Images from Contentful

Since images greatly influence SEO rankings and user experience, optimizing images fetched from Contentful includes:

  • Providing descriptive alt tags to enhance accessibility and SEO rankings.
  • Using optimized image file sizes, achievable using Contentful’s built-in image optimization APIs.
  • Consider implementing lazy loading to improve page performance.
  • Read related JavaScript-specific tips on optimizing images from this helpful collection of JavaScript articles.

Taking these extra steps ensures your image integrations produce high-performing and SEO-friendly websites.

Final Steps Toward Stable Image Rendering

By carefully implementing this explicit node handler within your Contentful-rich-text rendering setup, you confidently eliminate the headache of non-rendering images. It’s a straightforward fix and an excellent reminder to always double-check and test third-party rendering packages’ practical usage.

If you’ve encountered similar problems or discovered additional solutions, feel free to share your insights. How have you enhanced your rich-text experiences with Contentful and React on your projects? Let’s learn together!


Like it? Share with your friends!

Shivateja Keerthi
Hey there! I'm Shivateja Keerthi, a full-stack developer who loves diving deep into code, fixing tricky bugs, and figuring out why things break. I mainly work with JavaScript and Python, and I enjoy sharing everything I learn - especially about debugging, troubleshooting errors, and making development smoother. If you've ever struggled with weird bugs or just want to get better at coding, you're in the right place. Through my blog, I share tips, solutions, and insights to help you code smarter and debug faster. Let’s make coding less frustrating and more fun! My LinkedIn Follow Me on X

0 Comments

Your email address will not be published. Required fields are marked *