vincentdnl

Adding nofollow noopener noreferrer to external links when you use gatsby-plugin-mdx

February 23rd, 2020

In this article I talked about gatsby-remark-external-links. It turns out that it doesn't work well with gatsby-plugin-mdx as I've had an issue creating my about.mdx page.

Fortunately I found a simpler solution to the problem of adding rel="nofollow noopener noreferrer" as well as target="_blank" to your external links.

We will use the MdxProvider component to pass a component that will override the default one for links.

Open the file of the component responsible for displaying one post (it should be something like src/components/post.js or src/gatsby-theme-blog/components/post.js if you used the gatsby-theme-blog plugin and shadowed this component, like I did).

This part in the file is responsible for rendering the body of the MDX blog post:

//...
<MDXRenderer>{post.body}</MDXRenderer>
//...

We will wrap this component with a MdxProvider and pass it a new component to override the <a> tag:

//...
<MDXProvider components={mdxComponents}>
    <MDXRenderer>{post.body}</MDXRenderer>
</MDXProvider>
//...

now defining mdxComponents:

const mdxComponents = {a: BetterLink}

and the BetterLink component:

const BetterLink = ({children, href}) =>
    href.startsWith("/")
        ? <Styled.a as={Link} to={href}>{children}</Styled.a>
        : <Styled.a href={href} rel="nofollow noopener noreferrer" target="_blank">{children}</Styled.a>

What it does is check if the href url starts with a / (meaning it is an internal link to another blog article). If it does, it uses Link from the Gatsby Link API to render the link. The end result is that it loads the content when hovering the link and preload it so that when you click on it, the page change happens without a full reload. This kind of detail really make your site look slick!

If it's an external link, it adds rel="nofollow noopener noreferrer" target="_blank" to the link.

Here is an example of the result for an internal link:

And an external link:

If this tip has been useful to you, please tell me on Twitter! 😊