rich-text: Embedded images are ignored
I had to use the following to have embedded images display:
let options = {
renderNode: {
'embedded-asset-block': (node) =>
`<img class="img-fluid" src="${node.data.target.fields.file.url}"/>`
}
}
let bodyHTML = body ? documentToHtmlString(body, options) : ''
Seems like this should be a default (minus that bootstrap class); out-of-the-box, images didn’t display for me.
About this issue
- Original URL
- State: open
- Created 5 years ago
- Reactions: 44
- Comments: 47 (2 by maintainers)
Try deleting Gatsby’s .cache folder. There’s an issue with relaonships and caching in the plug-in that I don’t really understand 😉
Here’s a stripeed down example of how i’m doing it with
documentToReactComponentsExample of embedded assets and a ‘blockquote’ content typeBlockquote component
I gave it a few minutes and the typescript and bootstrapping the dev environment was a headache. I’m sure one of your paid developers could do this much more quickly.
👍 Bump.
Completely agreed this should be defaulted or at least clearly written that “embedded assets” (ie simple images) will not be translated into html in the docs; and give examples on how to extend.
I cant get node.data.target.fields to show up no matter what I do and its driving me crazy.
I only get the following output node.data.target.sys
i’ve tried deleting the .cache and running gatsby clean and none of it works.
my query is this
and my options are set up as
the output is this… 👎
UPDATE This was the hardest most obscure error to fix and I question using contentful for anything other than hobby or test work. I wouldn’t dare sell this to a client but with that gripe out of the way… this is how i fixed it and got the data that i needed… HOPE THIS HELPS THOSE THAT HAD THE SAME ISSUE I WAS HAVING
First thing I had to do was create a utility component that would get the contentful asset using the
sys.idas a reference since thats the only data that i was getting for my queriesThen i imported that util component into my template component and queried the embedded assets like so…
AGAIN, I HOPE THIS HELPS ANYONE STRUGGLING WITH THIS ISSUE AS I DED FOR A FEW DAYS
For anyone who still stuck with this. The documentation is not clear enough that make this will not work. This change when fetching Contentful content will fix it
The big missing piece of the puzzle is adding
__typenamefield, which needed for the library (check source code) to resolve the embedded asset is not mentioned as part of BREAKING CHANGES documentationI will submit a PR after this
Well I further tested rendering images (EMBEDDED_ASSET) from rich-text. But there is a bug where in all of above cases, the code breaks.
For example:
In the first publish is all OK, you get the URL alright.
But, for example you are using rich-text in blog post, then after you do some edits, the JSON you get in return is not the same anymore for the assets.
It seems like the fields part is missing in the node.data.target
Thus, the break
Anyone has any idea how to fix these cases?
Can confirm that running
gatsby cleanmakesnode.data.target.fieldsre-appear.That’s the solution that fixed it for me.
I’m having the same problem as @agonqorolli, I cannot for the life of me get “fields” to show up under node.data.target. I can see the full asset data in the links section of the result, but I cannot figure out how to get it somewhere I can use it.
I’m probably just overlooking something dumb, is there anything obviously wrong with this query (ignoring the single-item collection)?
I’m building a statically-compiled NextJS that uses a script to export all of my Contentful data to JSON. Then importing that JSON directly into my source. So
section.fields.textis project specific, but it’s basically the JSON blob that comes from a rich text field. Also there’s JSX (NextJS is react-based if you didn’t know), but hopefully you get the idea and this helps.I wrote this code straight into the browser, so none of this is tested, or pretty…
@Nelrohd
I have come across this issue of not easily being able to display embedded assets in a Contentful Rich Text field using GraphQL. However I am using Next.js and Netlify, so the Gatsby solution does not apply. Here is what I ended up using as a work around using
documentToReactComponents():var embeddedAssetCount = 0; /** * Used to render embedded images or videos in a Rich Text field via the Contentful GraphQL API. * Since the "content.json" field that contains all of the content of a Rich Text field does not return * the asset's url and just its sys.id, we must also pass in the "content.links.assets.block" array where * the asset's url IS returned. * * In order to be able to display multiple embedded assets, we must keep track of which index of the "block" * array we are currently on, and increment each time the function is called. * * @param {block} The "block" array coming from Contentful */ function embeddedAssetOptions(block) { return { renderNode: { [BLOCKS.EMBEDDED_ASSET]: (node) => { const asset = block[embeddedAssetCount]; embeddedAssetCount++; if (asset?.contentType?.startsWith('image/')) { return ...image tag...; } else if (asset?.contentType?.startsWith('video/')) { return ...video tag... } }, }, } }and then to use it:
{documentToReactComponents( article.content.json, embeddedAssetOptions(article.content.links?.assets?.block) )}this totally worked.
Wanted to share what I found for those using Nextjs or NOT Gatsby. It seems there are different fields if you’re not using Gatsby’s package. So rather than data.target.fields, you need to look for the links field such as in the below comment.
Contentful is building an example that shows how to use these queries to render Rich text Content including embedded assets and entries. I was able to follow this and render embedded images for my content: https://github.com/whitep4nth3r/p4nth3rblog/blob/main/components/RichTextPageContent/index.js#L17-L23
Hope this helps!
hello, any progress on the issue? I have to use the code from @nijotz to make it work in Next.js
shouldn’t it be a default behaviour in rich text renderer?
@grgcnnr Why is that my
[BLOCKS.EMBEDDED_ASSET]: node.data.target.fieldsdoes not contain suchtitle['en-US']andfile['en-US']? It only directly have a string-typedtitleandfile?Had the same problem, solved with ‘embedded-asset-block’ in gatsby-config.js Thanks a lot !
By the way, is there any way to make a HTML hypertext link on any Contentful image asset ?
Does anyone know if there is a fix for this besides deleting the .cache folder?
Here is my workaround (Contentful+SvelteKit+GraphQL;
fieldsis missing from my rich text links): https://stackoverflow.com/a/77498343/135791@know-mad - right in the bullseye! Thanks a lot! I confirm that this is the only solution for now
@bannouheol I need to see your solution man! I have the same problem, can’t find where to fix. My problem is, “field” key is not showing.
const options = { renderNode:{ "embedded-asset-block": (node) => { const alt = node.data.target.fields.title['en-US'] const url = node.data.target.fields.file['en-US'].url return <img alt={alt} src={url} /> } } }Just for reference of anyone as stupid as me, I literally forgot to put the
contentstuff into my template page query on Gatsby and it worked 🙈…Thanks @grgcnnr - your code example made it really easy to understand this.
oh ya, using the constants would probably be a good idea
For sure, I have been checking just the first part if the mimetype (the “image” part of “image/jpeg”) that seems to be enough for most cases. I’ll try to put a minimal example together next week.
On Sat, 2 Mar 2019, 2:13 AM Jerry Harrison, notifications@github.com wrote: