Reputation:
Im trying to integrate contentful rich text in my blog and its only working with bold, paragraphs and italics. I cant make the images and embedded things appear.
First i have this component:
const Content = ({ content }) => {
return (
<div className="content-body-contentful">
{documentToReactComponents(content)}
</div>
)
}
Then, in the post page, i import that component and pass de data like this:
<Content content={article.fields.body} />
Any answer to this problem?
Upvotes: 0
Views: 3124
Reputation: 125
Hi @user13680445 the Richtext field in contentful always return something like this at least as a Graphql response
"richTextResponse": {
// JSON structure of the Rich Text field
"json": {
# ...
}
// all referenced assets/entries
"links": {
# ...
}
}
in the links field you get all the assets and entries you are embedded in your Richtext
Here I have an example in Typescript of how to add assets
export const renderOptions = (links: Links): Options => {
const assetMap = getAssets(links.assets.block);
const entryMap = getEntries(links.entries.block);
return {
renderNode: {
[BLOCKS.HEADING_1]: renderHeading,
[BLOCKS.PARAGRAPH]: renderParagraph,
[BLOCKS.EMBEDDED_ENTRY]: renderEntry(entryMap),
[BLOCKS.EMBEDDED_ASSET]: renderAsset(assetMap),
},
};
};
const renderAsset =
(assetMap: Map<string, ContentfulImage>): NodeRenderer =>
(node) => {
const asset = assetMap.get(node.data.target.sys.id);
if (!asset) {
return <></>;
}
switch (asset.contentType) {
case "video/mp4":
return (
<VideoAsset
url={asset.url}
width={asset.width}
height={asset.height}
/>
);
case "image/png":
case "image/jpeg":
return (
<ImageAsset
url={asset.url}
width={600}
height={450}
description={asset.description}
quality={75}
/>
);
default:
return "Nothing to see here...";
}
};
and then you can call that function like this:
{documentToReactComponents(json, renderOptions(links))}
it's a rudimentary way to do it but Contentful at the moment doesn't have a better way to do it.
there we got the asset data matching the sys.id in the nodeType and the sys.id in your asset link for example:
RichText Object
{
"nodeType": "embedded-asset-block",
"content": [],
"data": {
"target": {
"sys": {
"id": "2DdSHQJA8zoumehPzqWZrs",
"type": "Link",
"linkType": "Asset"
}
}
}
}
links object
"links": {
"assets": {
"block": [
{
"sys": {
"id": "2DdSHQJA8zoumehPzqWZrs"
},
"fileName": "GOPR0511.JPG",
"url": "https://images.ctfassets.net/",
"title": "GOPR0511"
}
]
}
}
we are connecting both based on the sys.id, in this case, is 2DdSHQJA8zoumehPzqWZrs
Upvotes: 1
Reputation: 839
Below is a sample for using image with Next.js via Contentful. You can implement rest of the items similarly.
import Image from 'next/image'
const renderProps = {
renderNode: {
[BLOCKS.EMBEDDED_ASSET]: node => {
let { description, file } = node.data.target.fields
return (
<picture>
<Image src={file.url} alt={description} />
</picture>
)
},
},
}
const Content = ({ content }) => {
return <div className="content-body-contentful">{documentToReactComponents(content, renderProps)}</div>
}
Upvotes: -1