How to control if link opens in new tab or same tab?

9 replies
Last updated: Nov 29, 2025
How can I choose whether a link opens in a new tab or in the same one?
AI Update

When working with Portable Text in Sanity, you can add a field to your link annotations that lets content editors choose whether a link opens in a new tab or the same one. Here's how:

Adding the field to your schema

In your Portable Text schema definition, add a boolean field to your link annotation:

{
  name: 'link',
  type: 'object',
  title: 'External link',
  fields: [
    {
      name: 'href',
      type: 'url',
      title: 'URL'
    },
    {
      title: 'Open in new tab',
      name: 'blank',
      description: 'Read https://css-tricks.com/use-target_blank/',
      type: 'boolean'
    }
  ]
}

This adds a checkbox in Sanity Studio that editors can toggle to control the link behavior.

When rendering with React using @portabletext/react:

import {PortableText} from '@portabletext/react'

const components = {
  marks: {
    link: ({value, children}) => {
      const { blank, href } = value
      return blank ?
        <a href={href} target="_blank" rel="noopener">{children}</a>
        : <a href={href}>{children}</a>
    }
  }
}

export const Body = ({blocks}) => {
  return <PortableText value={blocks} components={components} />
}

The rel="noopener" attribute is important for security when using target="_blank" - it prevents the new page from accessing the window.opener property.

For Vue.js with sanity-blocks-vue-component:

<template>
  <PortableText
    :blocks="blocks"
    :serializers="serializers"
  />
</template>

<script>
import PortableText from 'sanity-blocks-vue-component'

export default {
  components: { PortableText },
  data() {
    return {
      serializers: {
        marks: {
          link: ({mark, children}) => {
            const { blank, href } = mark
            return blank ?
              <a href={href} target="_blank" rel="noopener">{children}</a>
              : <a href={href}>{children}</a>
          }
        }
      }
    }
  }
}
</script>

For other frameworks or when rendering to Markdown, you'd follow a similar pattern in your custom serializers, checking the blank value and conditionally adding the target="_blank" attribute.

You can find complete examples for React, Vue, and Markdown rendering in the Internal and external links with Portable Text guide.

Show original thread
9 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?