BlockContent link serializer not opening in new tab with target="_blank

4 replies
Last updated: Jan 29, 2026
Hi! I'm having some issues opening new links in a new tab within the BlockContent block. Here's my serializer.js snippet

const serializers = {
  types: {
    mainImage: Figure,
    Image: Figure,
    code: ({node = {}})=> {
    const {code, language} = node 
      if(!code) {
        return null;
      }
    return (
      <SyntaxHighlighter language={language || 'text'}>{code}</SyntaxHighlighter>
    )
  },
  marks: {
    internalLink: ({mark, children}) => {
      const {slug = {}} = mark
      const href = `/post/${slug.current}`
      return <a href={href}>{children}</a>
    },
    link: ({mark, children}) => {
      // Read <https://css-tricks.com/use-target_blank/>
      const { blank, href } = mark
      return blank ?
      <a href={href}>{children}</a>
        : <a href={href} target="_blank" rel="noopener noreferrer">{children}</a>
      }

    }
  }
}
Is there something I'm missing?
AI Update

I can see the issue in your code! You have the logic reversed in your link mark serializer. Currently, you're opening links in a new tab when blank is false, but you want the opposite.

Here's the corrected version:

marks: {
  internalLink: ({mark, children}) => {
    const {slug = {}} = mark
    const href = `/post/${slug.current}`
    return <a href={href}>{children}</a>
  },
  link: ({mark, children}) => {
    const { blank, href } = mark
    return blank ?
      <a href={href} target="_blank" rel="noopener noreferrer">{children}</a>
      : <a href={href}>{children}</a>
  }
}

The key change is swapping the ternary operator's branches. Now it will:

  • When blank is true: add target="_blank" rel="noopener noreferrer" (opens in new tab)
  • When blank is false: render a regular link without target attribute (opens in same tab)

Just as a note, if you're working with Portable Text (which is the modern name for BlockContent), you might want to consider using the official @portabletext/react library if you haven't already. It provides a more standardized way to handle serialization with the components prop, though your current approach with the legacy serializers prop should still work fine!

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