
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can help you with translating local URLs in Portable Text to proper Nuxt links in a Vue/Nuxt project. Based on the Sanity documentation, here's how to handle this:
When rendering Portable Text in a Vue/Nuxt application, you need to create custom serializers (called "components" in the newer libraries) to handle link annotations and convert them to <NuxtLink> or Vue Router's <RouterLink>.
First, make sure you're using the @portabletext/vue package for rendering Portable Text in your Vue/Nuxt project.
You'll need to define custom components for your link marks. Here's an example of how to handle internal links and convert them to <NuxtLink> components:
<script setup>
import { PortableText } from '@portabletext/vue'
import { h, resolveComponent } from 'vue'
const components = {
marks: {
// Handle internal links - convert to NuxtLink
internalLink: ({ value, children }) => {
return h(resolveComponent('NuxtLink'), {
to: value.slug?.current ? `/${value.slug.current}` : '/'
}, () => children)
},
// Handle external links - use regular anchor
link: ({ value, children }) => {
return h('a', {
href: value.href,
target: value.blank ? '_blank' : undefined,
rel: value.blank ? 'noopener noreferrer' : undefined
}, children)
}
}
}
</script>
<template>
<PortableText :value="content" :components="components" />
</template>Make sure your GROQ query joins the referenced document data so you have access to the slug:
*[_type == "post"]{
...,
body[]{
...,
markDefs[]{
...,
_type == "internalLink" => {
"slug": @.reference->slug
}
}
}
}Your Portable Text schema should define the link annotation like this:
marks: {
annotations: [
{
name: 'internalLink',
type: 'object',
title: 'Internal link',
fields: [
{
name: 'reference',
type: 'reference',
title: 'Reference',
to: [{ type: 'page' }, { type: 'post' }]
}
]
}
]
}marks property in your components configuration to override how annotations (like links) are renderedh() function with resolveComponent('NuxtLink') to create NuxtLink components programmatically@.reference-> syntax to get the slug or path informationThis approach gives you full control over how links are rendered and ensures internal navigation uses Nuxt's router for optimal performance with client-side routing, while external links work as standard anchors.
For more details, check out the Portable Text Vue serializer documentation and Sanity's guide on presenting Portable Text.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store