I'm trying to render the Contentful Document
to html, using rich-text-html-renderer. However, if the richtext contains nodes of the type entry-hyperlink
, this just renders out like this:
<span>type: entry-hyperlink id: QUfIK1T2dFDnubS5Ztc9N</span>
According to the documentation you'll need to pass an options object to the documentToHtmlString
.
But how do I do an async call within this render method to get the actual Contentful entry for this id?
In my case I am trying to do this within a Vue component in a Nuxt environment.
After digging further through the documentation I found the missing link:
I needed to load the content entry in my rich text component again and not only relying on the parent entry.
The parent entry loads this rich text entry which seems apparently complete, but if I load it within my component it loads more content and the this entry-hyperlink
node contains all the information I need to render the link.
Here my richt text vue component:
<template>
<!-- eslint-disable-next-line vue/no-v-html -->
<div class="text" v-html="html"></div>
</template>
<script lang="ts">
import { computed, defineComponent, useAsync } from '@nuxtjs/composition-api';
import { Block, INLINES, Inline } from '@contentful/rich-text-types';
import {
documentToHtmlString,
Options,
} from '@contentful/rich-text-html-renderer';
import { IText } from '~/types/generated/contentful';
import useContentful from '~/plugins/contentful';
export default defineComponent({
props: {
entry: {
type: Object as () => IText,
required: true,
},
},
setup(props) {
const { client } = useContentful();
const text = useAsync(() => client.getEntry<IText>(props.entry.sys.id));
const html = computed(() => {
if (text.value) {
const options: Partial<Options> = {
renderNode: {
[INLINES.ENTRY_HYPERLINK]: (node: Inline | Block) => {
return `<a href="/${node.data.target.fields.slug}">${node.content[0].value}</a>`;
},
},
};
return documentToHtmlString(text.value.fields.text, options);
}
});
return {
html,
};
},
});
</script>