Open Wagtail Rich Text Block Links in a New Tab


You'd think being able to set external link targets in rich text blocks to open in a new tab would be something offered out of the box. I put this in as a feature request with Wagtail which was promptly shut down with the explanation that "it's against UX best practice" and that it should be up to the visitor to decide if they want to open in a new tab.

Personally, I find it sloppy when a link to an external site isn't opened in a new tab by default. I've lost my place in the site I was on, and now have to navigate back or reload from history. If the opened page is something I want to keep open and save for later while I continue on the original site, then the new tab is the only route for this. I'm more likely to just not return to the referring page.

Much more importantly, leaving your site to visit another is extremely bad practice from a business/marketing/retention viewpoint where the very aim is to retain the visitor, not to send them elsewhere.

fa-solid fa-circle-info Clarification
This applies only to links created using the External Link option in Wagtail's built-in rich text block editor (Draftail). Links that you create in custom blocks or any other way are entirely up to the developer. Since linking from text is such a common feature, this requires extra consideration.


There are two routes that I've come across to circumvent this: adding a site-wide policy via wagtail hooks or dropping in a block of JQuery into the relevant page types.

A note about the rel attribute

When opening a link to an external site, I add to attributes to the <a> element: rel="nofollow noopener"

These are optional and included for the following reasons:

noopener - this closes down an old security flaw and instructs the browser to navigate to the target resource without granting the new browsing context access to the document that opened it by not setting the Window.opener property on the opened window (it returns null). This is included for older browsers where target="_blank" used an opener which was vulnerable to exploit. noopener is now the default behaviour in all major browsers. See here for a discussion on this.

nofollow - instructs web crawlers to not follow the link. A couple of reasons for doing this: it avoids circular references (a link to a page that links back to the current page) which will score negative points on your SEO; it avoids giving SEO to your competitors (not sure why you'd want to link to your competitors, but it's here for completeness).

Opening Links in New Tabs via JQuery

This is a very simple override that amends the attributes of your href a tags if they point to an address using http or https protocols. There are a couple of benefits to using this over a site-wide policy that affects every 'external link':

  1. In a site where there are Django pages alongside Wagtail pages (such as this one), linking to your internal Django pages has to be done using the External Link option since they don't feature in the Page Chooser. These should be opened in the same tab, only opening truly external links in new tabs. The JQuery method allows this, provided you use relative paths for internal URL's. You may also be using the External Link option to point to aliased domains or routable pages, all of which you'd want in the same tab.
  2. You can apply this method only to the page types you want, rather than the entire site.
  3. It doesn't involve messing with Wagtail internals which can potentially break with future updates.
    $('a[href^="http://"]').attr('target', '_blank');
    $('a[href^="http://"]').attr('rel', 'nofollow noopener');
    $('a[href^="https://"]').attr('target', '_blank');
    $('a[href^="https://"]').attr('rel', 'nofollow noopener');

That's all there is to it. I've dropped this into my site-wide JavaScript as I don't have any special requirements. It doesn't mess with the OAuth links and leaves my "internal external" Django links alone as well.


Opening Links in New Tabs via Wagtail Hooks

Doing this will apply a site-wide policy on all 'External Links', even those that point to internal links.

Starting with Wagtail 2.5 the following is possible in your

from django.utils.html import escape
from wagtail.core import hooks
from wagtail.core.rich_text import LinkHandler

class NewWindowExternalLinkHandler(LinkHandler):
    # This specifies to do this override for external links only.
    # Other identifiers are available for other types of links.
    identifier = 'external'

    def expand_db_attributes(cls, attrs):
        href = attrs["href"]
        # Let's add the target attr, and also rel="noopener" + noreferrer fallback.
        # See
        return '<a href="%s" target="_blank" rel="noopener noreferrer">' % escape(href)

def register_external_link(features):

Now in your text block declaration, remove the 'link' option and add 'extended_link'.


body = blocks.RichTextBlock(features=['h1', 'h2', 'h3', 'h4', 'bold', 'italic', 'ol', 'ul', 'hr', 'extended_link', 'image'])),


Well, my vote goes with the JQuery option for the reasons listed above. It's simple, non-intrusive and only applies to those 'external links' while leaving relative links alone.

Should it break, your links simply open in the same tab. Nothing disastrous. It's the method applied to this website.

  Please feel free to leave any questions or comments below, or send me a message here