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
→value
andserializers
→components
attribute name changes have been made. The property types remain the same. - Custom components now receive their data nested within a
props.value
object. 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>