Add a target="_blank" to hyperlink within Rich Text Content Type

Hello,

Does anyone know how to add a target="_blank" to hyperlinks within the Rich Text Content Type. I can’t see any options for opening a link in a new tab.

Cheers!

There’s no way to do this through the Contentful Web App. You can however do it when rendering rich text to HTML.

Check out this tutorial how to do this with JavaScript: https://www.contentful.com/developers/docs/javascript/tutorials/rendering-contentful-rich-text-with-javascript/#customized-rendering

Instead of overriding BLOCKS.PARAGRAPH, you’d override INLINES.HYPERLINK , test the url and then output different markup. That could look something like this:

const options = {
  renderNode: {
    [INLINES. HYPERLINK]: (node, next) => {
      return `<a href="${node.data.uri}"${node.data.uri.startsWith('https://mydomain.com') ? '' : ' target="_blank"'}>${next(node.content)}</a>`;
    }
  }
}
6 Likes

Perfect, this works great thanks. Using ‘next’ was giving me an error “next is not a function” (any idea why?) so I updated the code slightly and added a rel checker too.

import { INLINES } from '@contentful/rich-text-types'

const website_url = 'https://mydomain.com'

const options = {
  renderNode: {
    [INLINES.HYPERLINK]: (node) => {
      return <a href={node.data.uri} target={`${node.data.uri.startsWith(website_url) ? '_self' : '_blank'}`} rel={`${node.data.uri.startsWith(website_url) ? '' : 'noopener noreferrer'}`}>{node.content[0].value}</a>;
    }
  }
}

Thanks again :slight_smile:

@james.barber Where exactly did you implement the code you wrote? Also, were you using dangerouslySetInnerHTML? I am trying to get this to work for all pages of a certain contentful type but am lost.

7 posts were split to a new topic: Working with nested Rich Text fields

@Rouven is there still no plan to add the alternative to select the target within the CMS itself? It’s not always the case that the editors want to open external links in new tabs…

You could allow inline entries and handle this by using your own content model, but yes I agree, a simple checkbox for “open in new tab” or similar would be far more convenient.

Hi Rouven,
Why this doesn’t work with links inside a paragraph?
I have something like this and embedded link with a p element and I tried to use the same approach but doesn’t work, do you know If I need to use a different entry type?

Here’s what I use in 2022 - note there’s no next function, using INLINES type, and passing JSX element instead of string

import React from 'react';

import { INLINES } from '@contentful/rich-text-types';
import { documentToReactComponents } from "@contentful/rich-text-react-renderer";

const options = {
  renderNode: {
    [INLINES.HYPERLINK]: (node, children) => {
      return <a target="_blank" rel="noopener noreferrer" href={node.data.uri}>{children}</a>
    }
  }
}

export const RichText = ({ text }) => {
  const renderedText = documentToReactComponents(text, options);

  return <div className="rich-text">{renderedText}</div>;
};

The way I do it in gatsby…

import React from 'react'
import { INLINES } from '@contentful/rich-text-types'
import { renderRichText } from 'gatsby-source-contentful/rich-text'

const Component = ({ text }) => {  
  const options = {
    renderNode: {
      [INLINES.HYPERLINK]: (node, children) => {
        let anchorAttrs = {}
        
        if (!node.data.uri.includes('my-domain-name.com')) {
          anchorAttrs = {
            target: '_blank',
            rel: 'noopener noreferrer'
          }
        }
        
        return <a href={node.data.uri} {...anchorAttrs}>{children}</a>
      }
    }
  }
  
  return <div>{renderRichText(text, options)}</div>
}

export default Component