This document outlines the differences between @portabletext/vue and sanity-blocks-vue-component so you can adjust your code to use the newer @portabletext/vue.
PortableText is an open-source specification, and as such we're giving it more prominence through the library and component renaming.
From:
<script setup>
import { SanityBlocks } from 'sanity-blocks-vue-component';
</script>
<template>
<SanityBlocks ... />
</template>
✅ To:
<script setup>
import { PortableText } from '@portabletext/vue';
</script>
<template>
<PortableText ... />
</template>
This component renders any Portable Text content or custom object (such as codeBlock
, mapLocation
or callToAction
). As blocks
is tightly coupled to text blocks, we've renamed the main input to value
.
From:
<template>
<SanityBlocks
:blocks="[
/*...*/
]"
/>
</template>
✅ To:
<template>
<PortableText
:value="[
/*...*/
]"
/>
</template>
"Serializers" are now named "Components".
From:
<template>
<SanityBlocks
:serializers="{
marks: {
/* ... */
},
types: {
/* ... */
},
list: {
/* ... */
},
}"
/>
</template>
✅ To:
<template>
<PortableText
:components="{
marks: {
/* ... */
},
types: {
/* ... */
},
list: {
/* ... */
},
}"
/>
</template>
The props passed to custom components (previously "serializers") have changed. Previously, all properties of the block or mark object (excluding _key
and _type
) were flattened and passed to components as props.
Block or mark properties are now passed via a value
prop. This better aligns the Vue renderer with those built for other frameworks. Refer to the readme to see the list of props passed and how to write component prop definitions.
We've removed the only Sanity-specific part of the module, which was image handling. You'll have to provide a component to specify how images should be rendered yourself in this new version.
We've seen the community have vastly different preferences on how images should be rendered, so having a generic image component included out of the box felt unnecessary.
<script setup>
import urlBuilder from '@sanity/image-url';
import { getImageDimensions } from '@sanity/asset-utils';
// Barebones lazy-loaded image component
const SampleImageComponent = ({ value }) => {
const { width, height } = getImageDimensions(value);
return h('img', {
src: urlBuilder().image(value).width(800).fit('max').auto('format').url(),
alt: value.alt || ' ',
loading: 'lazy',
style: {
// Avoid jumping around with aspect-ratio CSS property
aspectRatio: width / height,
},
});
};
</script>
<template>
<!-- You'll now need to define your own image component -->
<PortableText
:value="input"
:components="{
// ...
types: {
image: SampleImageComponent,
},
}"
/>;
</template>