Helpers
Portable Text
Global helper
This module defines a global <SanityContent> component that can turn portable text into HTML. It is a lightweight functional component without an instance.
As of v2, <SanityContent> uses @portabletext/vue for rendering portable text. This means features and properties available to @portabletext/vue also work with <SanityContent>. Please refer to their Usage guide for advanced configuration options.
This render change introduces breaking changes for
<SanityContent> v2 components. Refer to the following upgrade guide:- To reflect
@portabletext/vue's props,blocks→valueandserializers→componentsattribute name changes have been made. The property types remain the same. - Custom components now receive their data nested within a
props.valueobject. When defining components, you need to extract your props from this structure using object spreading:{...props.value}. This applies to all component types (blocks, marks, styles).
Example
<template>
<SanityContent :value="content" />
</template>
Example with custom components
<template>
<SanityContent :value="content" :components="components" />
</template>
<script setup>
import { defineAsyncComponent, h, resolveComponent } from 'vue'
import CustomBlockComponent from '~/components/CustomBlockComponent.vue'
const components = {
types: {
// This is how to access a component registered by `@nuxt/components`
lazyRegisteredComponent: props => h(resolveComponent('LazyCustomSerializer'), {
...props.value,
}),
// A directly imported component
importedComponent: props => h(CustomBlockComponent, {
...props.value,
}),
// Example of a more complex async component
dynamicComponent: props => h(defineAsyncComponent({
loadingComponent: () => 'Loading...',
loader: () => import('~/other/component.vue'),
}), {
...props.value,
}),
},
marks: {
// Custom marks handling
internalLink: props => h('a', { href: props.value.href }, props.text)
}
}
</script>
If you want to use the same components in multiple places, consider creating your own component (e.g.
<MySanityContent>) which wraps SanityContent with your default components. By creating ~/components/MySanityContent.vue you should be able to use this everywhere in your app without importing it.Advanced Props
The SanityContent component accepts all props from @portabletext/vue:
<template>
<SanityContent
:value="content"
:components="components"
:onMissingComponent="handleMissingComponent"
:listNestingMode="'html'"
/>
</template>
<script setup>
const handleMissingComponent = (message, options) => {
console.warn(`Missing component: ${options.type} (${options.nodeType})`)
}
</script>