3

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.

Thomas
  • 6,325
  • 4
  • 30
  • 65
  • Not sure of what is the issue here. You're not sure how to write an async call in Nuxt or some code that you've already wrote is not rendering as expected? – kissu Jun 15 '21 at 09:48
  • @kissu I'm trying to render the richtext with internal links. It seems I need to load the target async in the render options. Or I misunderstand some concepts... – Thomas Jun 15 '21 at 09:57
  • Can you show us what you did so far? It will also help me see what is the issue because I'm not sure of what is to call here. Did you read this one already? https://www.contentful.com/developers/docs/javascript/tutorials/integrate-contentful-with-vue-and-nuxt/ – kissu Jun 15 '21 at 10:01

1 Answers1

1

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>
Thomas
  • 6,325
  • 4
  • 30
  • 65