rich-text icon indicating copy to clipboard operation
rich-text copied to clipboard

documentToReactComponents doesn't include images embedded in rich text fields

Open Erythros opened this issue 4 years ago • 7 comments

I am using React and Contentful with Gatsby. I have defined a rich text field in Contentful. When adding content, I embedded an asset (image) inside the field. I looks like this image

When I query the data, I get the image inside the json response like this

file": {
             "en-US": {
              "url": "//images.ctfassets.net/ijv74p5w2k9k/4K8hxN40bRHqnq4iD2OLrw/6392cc793c3bc6ec7c/my-image.jpg",
              "details": {
                          "size": 269327,
                          "image": {
                            "width": 1747,
                            "height": 1240
                          }
                        },
                        "fileName": "my-image.jpg",
                        "contentType": "image/jpeg"

In my project, I fetched the entire json and rendered it like this

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

<div className={styles.content}>
    {documentToReactComponents(article.content.json)}
</div>

The result is that the text is correctly displayed, but the embedded asset is not displayed. image

I am not sure if I'm doing something wrong, not doing something at all or if this is just a bug.

Any suggestions?

Erythros avatar Oct 20 '20 09:10 Erythros

I'm having the same issue on Next.js

talentedunicorn avatar Oct 20 '20 12:10 talentedunicorn

@Erythros try this it worked for me. You apparently need to define how the method handles the BLOCKS.EMBEDDED_ASSET. Good luck

talentedunicorn avatar Oct 20 '20 12:10 talentedunicorn

@talentedunicorn thank you! That worked for me

pjtf93 avatar Nov 02 '20 22:11 pjtf93

119 might have your answer

angelod1as avatar Nov 26 '20 23:11 angelod1as

#119 Doesn't solve anything. It just fallback in case where theres no asset fields Which is my case, querying with GraphQL and using NextJS.

foxieManel avatar Dec 08 '20 07:12 foxieManel

Yep, found that as well. I'm was having the same problem and switched back to the SDK

angelod1as avatar Dec 08 '20 11:12 angelod1as

I had the same issue, like @talentedunicorn says here and I fixed by creating a component that request the asset to the Contentful CDN:

My snippet on rendering the content:

  const renderOptions = {
    renderNode: {
      [BLOCKS.EMBEDDED_ASSET]: (node) => {
        return <ContentfulAsset node={node} className={classes.logo} />;
      },
    },
  };

return (<>{documentToReactComponents(contentFullResponse.fields.myFieldId, renderOptions)}</>);

My ContentfulAsset component:

import React, { useCallback, useEffect, useState } from "react";
import { getAsset } from "helpers/providers/contentful";

const ContentfulAsset = ({ node, style, className, testid }) => {
  const [isLoading, setIsLoading] = useState(true);
  const [asset, setAsset] = useState(null);

  const Asset = ({ type, url, alt }) => {
    const attr = {
      src: url,
      style,
      className,
      ["data-testid"]: testid,
    };
    return (
      <>
        {type === "image" && <img alt={alt} {...attr} />}
        {type === "video" && <video {...attr} />}
      </>
    );
  };

  const loadContent = useCallback(() => {
    (async () => {
      try {
        const nodeFields =
          node.data.target?.fields ??
          (await getAsset(node.data.target.sys.id))?.fields;
        const newAsset = {
          type: nodeFields?.file?.contentType.split("/")[0],
          url: nodeFields?.file?.url,
          alt: nodeFields?.title,
        };
        setAsset(newAsset);
        setIsLoading(false);
      } catch (e) {
        console.error("ContentfulAsset - loadContent", e);
      }
    })();
  }, [node.data.target?.fields, node.data.target.sys.id]);

  useEffect(() => {
    loadContent();
  }, [loadContent]);

  return (
    <>
      {isLoading ? null : (
        <>{typeof asset === "object" && <Asset {...asset} />}</>
      )}
    </>
  );
};

export default ContentfulAsset;

matiasperrone avatar Nov 04 '22 16:11 matiasperrone