How to automatically add target="_blank" to external links only?

Viewed 9640

I'm building a custom, industry-specific cms (using django). In the backend, webmasters can specify either an internal link, e.g. "/page1" or an external link to use for various navigation elements throughout the website (all use <a> when rendered) . The problem is that I would like internal links to open in the current tab, but external links should use target="_blank" to open a new tab or window.

How can I process the html to accomplish this?

I'd prefer a server-side solution, but am not aware of any clean way to pre-process rendered templates in django. So, I assume the most straightforward way to do this is probably a javascript/jquery solution: a script that runs when each page loads, which adds the target="_blank" attribute to all external links but not internal links. But I'm not sure how to do this, either.

8 Answers

As the great accepted answer from @Chris Pratt does not work for e.g. tel: links and other special cases I just use the following variant in order to not touch special links:

(function($) {

    $.expr[':'].external = function(obj){
        return (obj.hostname != location.hostname) && obj.href.startsWith("http");
    };

    $('a:external').attr('target', '_blank');

}) (jQuery);

Slight change in code, which doesn't give errors, additional = in !==

$.expr[':'].external = function(obj){
    return !obj.href.match(/^mailto\:/) && (obj.hostname !== location.hostname) && !obj.href.match(/^javascript\:/) && !obj.href.match(/^$/);
};
$('a:external').attr('target', '_blank');

Another JavaScript solution:

(() => {
  (document.querySelectorAll('a')).forEach(link => {
    link.hostname !== location.hostname && link.setAttribute('target', '_blank');
  })
})();
Related