Portable Text links not rendering in @portabletext/svelte - missing <a> tags

15 replies
Last updated: Jan 27, 2026
Hello all, I think I asked this question earlier in the year and someone answered it and I then promptly forgot to note it down and its now disappeared as it was a few months back.
Basically, links are not rendering in portable text - as in a standard piece of text, highlighted and a link attached to it. The text is being displayed but the
a
tag is not.
I always under the impression that this works out of the box on Portabletext renderers but
@portabletext/svelte
doesn't seem to.
Anyone have any ideas what I need to add?
AI Update

You're right that links not rendering in @portabletext/svelte is a common issue! The key thing is that you need to provide custom components for marks like links – they don't render automatically out of the box.

The Solution

The @portabletext/svelte package requires you to pass custom components through the components prop (not serializers as some older examples might show). Here's how to handle link rendering:

<script>
  import {PortableText} from '@portabletext/svelte'
  import Link from './Link.svelte' // Your custom link component
</script>

<PortableText 
  value={yourBlocks} 
  components={{
    marks: {
      link: Link
    }
  }}
/>

Then create your Link.svelte component:

<script lang="ts">
  import type {MarkComponentProps} from '@portabletext/svelte'
  import {Snippet} from 'svelte'
  
  interface Props {
    portableText: MarkComponentProps<{href?: string}>
    children: Snippet
  }
  
  let {portableText, children}: Props = $props()
  let {value} = $derived(portableText)
</script>

{#if value.href}
  <a href={value.href}>
    {@render children()}
  </a>
{:else}
  {@render children()}
{/if}

Important Notes

For Svelte 5+: The library requires Svelte 5.0.0 or higher and uses the modern runes syntax ($props(), $derived()) as shown above. The components prop structure is the current standard.

Your schema is fine: The standard Portable Text block type in Sanity Studio already includes link annotations by default – the issue is purely on the rendering side with how @portabletext/svelte handles marks.

Why links need custom components: The library doesn't provide default implementations for annotation marks (like links with href data), only for decorator marks (like strong or em). This is by design since link rendering often needs customization (external link icons, target="_blank", routing library integration, etc.).

You can check out the official svelte-portabletext repository for more examples of customizing marks, blocks, and other components!

Show original thread
15 replies

Sanity – Build the way you think, not the way your CMS thinks

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.

Was this answer helpful?