Almost EVERYONE who tried headless systems said they saw benefits. Download the state of CMS now!

Storyblok now on AWS Marketplace: Read more

O’Reilly Report: Decoupled Applications and Composable Web Architectures - Download Now

Empower your teams & get a 582% ROI: See Storyblok's CMS in action

Skip to main content

How to render Richtext fields in Nuxt

  • FAQ
  • How to render Richtext fields in Nuxt

You can easily render rich text by using the renderRichText function that comes with @storyblok/nuxt and a Vue computed property:

<template>
  <div v-html="articleContent"></div>
</template>

<script setup>
  const props = defineProps({ blok: Object })
  const articleContent = computed(() => renderRichText(props.blok.articleContent));
</script>

You can also set a custom Schema and component resolver by passing the options as the second parameter of the renderRichText function:

<script setup>
  import cloneDeep from 'clone-deep'

  const mySchema = cloneDeep(RichTextSchema) // you can make a copy of the default RichTextSchema
  // ... and edit the nodes and marks, or add your own.
  // Check the base RichTextSchema source here https://github.com/storyblok/storyblok-js-client/blob/v4/source/schema.js

  const props = defineProps({ blok: Object })

  const articleContent = computed(() =>
    renderRichText(props.blok.articleContent, {
      schema: mySchema,
      resolver: (component, blok) => {
        switch (component) {
          case 'my-custom-component':
            return `<div class="my-component-class">${blok.text}</div>`
          default:
            return 'Resolver not defined'
        }
      },
    })
  )
</script>
hint:

These instructions apply for Nuxt 3, using @storyblok/nuxt. The approach for Nuxt 2 is very similar, with some minor differences. Detailed instructions can be found in the official SDK readme for @storyblok/nuxt-2.

Section titled Custom components workaround Custom components workaround

You can use custom blocks inside the RichText editor representing a Vue custom component in your application.

First, install the vue3-runtime-template to understand the Vue template syntax:

        
      npm install vue3-runtime-template
    

Then, to compile Vue templates on the fly, you will need to add an alias in nuxt.config.js:

nuxt.config.js
        
      export default defineNuxtConfig({
  hooks: {
    'vite:extendConfig': (config, { isClient, isServer }) => {
      if (isClient)
        config.resolve.alias.vue = 'vue/dist/vue.esm-bundler.js'
    },
  },
})
    
hint:

This example is made for Nuxt 3, for Nuxt 2 follow the steps in the README of the package itself: vue3-runtime-template

After creating the blocks in your space and the corresponding Vue components under the storyblok folder of your project (for Nuxt 3), it's time to create the resolver and use the runtime template:

YourContentType.vue
        
      <template>
  <div v-editable="blok">
    <Vue3RuntimeTemplate :template="resolvedRichText"></Vue3RuntimeTemplate>
  </div>
</template>

<script setup>
import Vue3RuntimeTemplate from "vue3-runtime-template"
const props = defineProps({ blok: Object })

const resolvedRichText = computed(() => renderRichText(props.blok.content, {
  resolver: (component, blok) => {
    return `<component :blok='${JSON.stringify(blok)}' is="${component}" />`
  },
}))
</script>
    

Now, when you add a component to your RichText field, your application will be able to render it.

Note:

This solution has been created by the community, and there is no official way to do it. You can always implement your custom solution.