Easily render the content of Strapi's new Blocks rich text editor in your Vue frontend.
Based on @strapi/blocks-react-renderer
- Zero runtime dependencies
- Renders line breaks (
\n) as<br>elements plainTextprop available oncodeandheadingblocksuseStrapiBlocksContext()composable for nested custom components- Custom block and modifier components
- Full TypeScript support
- Compatible with Nuxt
Install the Blocks renderer and its peer dependencies:
npm install vue-strapi-blocks-renderer vueAfter fetching your Strapi content, you can use the BlocksRenderer component to render the data from a blocks attribute. Pass the array of blocks coming from your Strapi API to the content prop:
<script setup lang="ts">
import { StrapiBlocks, type BlocksContent } from 'vue-strapi-blocks-renderer'
// Content should come from your Strapi API
const content: BlocksContent = [
{
type: 'paragraph',
children: [{ type: 'text', text: 'A simple paragraph' }],
},
]
</script>
<template>
<StrapiBlocks :content="content" />
</template>You can provide your own Vue components to the renderer, both for blocks and modifiers. They will be merged with the default components, so you can override only the ones you need.
- Blocks are full-width elements, usually at the root of the content:
paragraphheading(receiveslevel,plainText)list(receivesformat)quotecode(receivesplainText)image(receivesimage)link(receivesurl,target,rel)
- Modifiers are inline elements for text formatting:
bolditalicunderlinestrikethroughcode
To provide your own components, pass an object to the blocks and modifiers props. Each value should be a Vue render function that receives the props. Make sure to always render the children so nested content is displayed.
<script setup lang="ts">
import { h } from 'vue'
import {
StrapiBlocks,
type BlocksComponents,
type ModifiersComponents,
type BlocksContent,
} from 'vue-strapi-blocks-renderer'
const content: BlocksContent = [/* your content */]
const customBlocks: Partial<BlocksComponents> = {
paragraph: (props) => h('p', { class: 'mb-4' }, props.children),
heading: ({ level, plainText, children }) =>
h(`h${level}`, { id: plainText?.toLowerCase().replace(/\s+/g, '-') }, children),
}
const customModifiers: Partial<ModifiersComponents> = {
bold: (props) => h('strong', { class: 'font-bold text-blue-600' }, props.children),
}
</script>
<template>
<StrapiBlocks :content="content" :blocks="customBlocks" :modifiers="customModifiers" />
</template>If you need to access the blocks/modifiers context from within a custom component, use the useStrapiBlocksContext() composable:
import { h } from 'vue'
import { useStrapiBlocksContext, type BlockChildren } from 'vue-strapi-blocks-renderer'
const CustomParagraph = (props: { children?: BlockChildren }) => {
const { modifiers } = useStrapiBlocksContext()
const modifierCount = Object.keys(modifiers).length
return h('p', {}, [
props.children,
h('small', { class: 'text-gray-500' }, ` (${modifierCount} modifiers available)`),
])
}