Storyblok RichText in-line block support for nuxt3 with ssr and prerender.

cetchells on github raised an issue on my github repo for this website to discuss in-line blocks in richtext from contentful. This is not something that I have tried or looked into, but felt like a challenge and something that I will probably want in the future.

Since I use SSR with prerender in nuxt3, there is no built-in way of doing the rendering of blocks inside of richtext, so I had to figure out a custom way of doing it. I settled with looping through the richtext nodes and adding the blocks and HTML to an array. This way I can render the richtext in the correct way and still have support for in-line blocks.

To add a block in richtext you use:
which places a block list inside of the richtext.

After placing a block it looks like this:
which renders like this:

Here is the code for how to do this:

<script setup lang="ts">
import { Richtext } from 'storyblok-js-client';
const props = defineProps({ blok: Object });
const nuxtApp = useNuxtApp();
const textObject = { ...props.blok.text };
const nodes = [];
// Proof of concept for custom handling of inline blok nodes.
Object.entries(textObject.content).forEach(([key, node]) => {
if (node.type === 'blok') {
const blok = {
content: node.attrs?.body?.[0],
};
nodes.push({
key,
type: 'blok',
content: {
blok,
},
});
} else {
nodes.push({
key,
type: 'html',
content: nuxtApp.$formatRichText(useStoryblokApi().richTextResolver.render({
type: 'doc',
content: [
node,
],
} as Richtext)),
});
}
});
</script>
<template>
<div v-editable="blok" class="text">
<div v-for="node in nodes" :key="node.key">
<component
:is="$resolveStoryBlokComponent(node.content.blok)"
v-if="node.type === 'blok'"
:blok="node.content.blok.content"
/>
<div v-else v-html="node.content" />
</div>
</div>
</template>
<style>
.text img {
max-width: 100%;
}
</style>
view raw Text.vue hosted with ❤ by GitHub