Tips for opening links in a new tab using custom annotation in Sanity.io

4 replies
Last updated: Apr 14, 2020
any hints on supporting opening links in a new tab (via block content)?
AI Update

Great question! Adding support for opening links in a new tab with Portable Text involves two main steps: adding a field to your schema and customizing your serializer/component.

Schema Configuration

First, you'll need to add a boolean field to your external link annotation. Here's how to set it up in your Portable Text schema:

// portableText.js
export default {
  name: 'portableText',
  type: 'array',
  title: 'Content',
  of: [
    {
      type: 'block',
      marks: {
        annotations: [
          {
            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 the Studio UI that content editors can toggle when adding external links.

Frontend Rendering

Now you need to handle this in your frontend. Here's how to do it with React using @portabletext/react:

import React from 'react'
import {PortableText} from '@portabletext/react'

const components = {
  marks: {
    link: ({value, children}) => {
      // Read https://css-tricks.com/use-target_blank/
      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} />
}

Important security note: Always include rel="noopener" (or rel="noopener noreferrer") when using target="_blank" to prevent potential security vulnerabilities.

For Other Frameworks

The approach is similar for other frameworks. For Vue.js with sanity-blocks-vue-component:

link: ({mark, children}) => {
  const { blank, href } = mark
  return blank 
    ? `<a href=${href} target="_blank" rel="noopener">${children}</a>`
    : `[${children}](${href})`
}

For more complete examples including internal links and other frameworks, check out the official Sanity guide on Portable Text links.

user M
😅
I’ve been doing it using a custom annotation like this, and then in the frontend project I can get the data from
markDefs
and check if
blank
is true or false to add the appropriate
target="_blank"
user R
user Q
thx! 🙇‍♂️

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?