An Astro plugin to open external links in a new tab

By default, when writing markdown content in Astro, all links are rendered to <a> tags that open in the same tab. This is not ideal for external links, as you might want to keep the user on your site.

The solution is pretty simple, and it does involve writing a simple rehype plugin.

Writing the Rehype plugin

To put it simply, a rehype plugin is just a function that takes the AST (Abstract Syntax Tree) of the HTML as input and modifies it in some way.

The following visits all the elements in the tree while adding target="_blank" to external links:

// src/plugins/targetBlank.ts

import type { RehypePlugin } from '@astrojs/markdown-remark';
import { visit } from 'unist-util-visit';
import type { Element } from 'hast';

export const targetBlank: RehypePlugin = ({ domain = '' } = {}) => {
  return (tree) => {
    visit(tree, 'element', (e: Element) => {
      if (
        e.tagName === 'a' &&
        e.properties?.href &&
        e.properties.href.toString().startsWith('http') &&
        !e.properties.href.toString().includes(domain)
      ) {
        e.properties!['target'] = '_blank';
      }
    });
  };
};

Enabling the plugin

To enable the plugin, update astro.config.ts with the following:

// astro.config.ts

import { targetBlank } from './src/plugins/targetBlank';

export default defineConfig({
  // ...
  markdown: {
    rehypePlugins: [[targetBlank, { domain: 'yourdomain.com' }]],
  },
});

And that’s it! Now all external links will open in a new tab.

And here is a test with an internal link which should open in the same tab.