Issue with opening links in new tab within BlockContent block

4 replies
Last updated: Jun 9, 2021
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
I tried that and it didn't work πŸ™
Here's what my
blockContent.js
file looks like:

marks: {
        // Decorators usually describe a single property – e.g. a typographic
        // preference or highlighting by editors.
        decorators: [{title: 'Strong', value: 'strong'}, {title: 'Emphasis', value: 'em'}, {title: 'Code', value: 'code'}, { "title": "Strike", "value": "strike-through" }],
        // Annotations can be any object structure – e.g. a link or a footnote.
        annotations: [
          {
            name: 'link',
            type: 'object',
            title: 'External link',
            fields: [
              {
                name: 'href',
                type: 'url',
                title: 'URL'
              },
              {
                title: 'Open in a New Tab',
                name: 'blank',
                type: 'boolean'
              }
            ]
          },
          {
            name: 'internalLink',
            type: 'object',
            title: 'Internal link',
            fields: [
              {
                name: 'reference',
                type: 'reference',
                title: 'Reference',
                to: [
                  { type: 'post' },
                ]
              }
            ]
          },
        ]
      },
    
    },
Hmm, I would double check your code against this guide . I was able to get
target='_blank'
to work by a)double checking that the boolean
blank
was set to true on the
link
object in portable text and b) changing your ternary as mentioned before:
return blank ? <a href={href} target="_blank" rel="noopener">{children}</a> : <a href={href}>{children}</a>
Hmm, I would double check your code against this guide . I was able to get
target='_blank'
to work by a)double checking that the boolean
blank
was set to true on the
link
object in portable text and b) changing your ternary as mentioned before:
return blank ? <a href={href} target="_blank" rel="noopener">{children}</a> : <a href={href}>{children}</a>

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?