[Fixed]-How to automatically add target="_blank" to external links only?

43👍

I’ve been using the following for awhile. Can’t remember where I found it originally:

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

That adds an :external jQuery selector, so then you can just do:

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

The nice part about using the custom selector, is that if you need to modify what contitutes an “external” link, you can change it in one place and not worry about the rest of your code. For instance in my organization, we have certain subdomains that aren’t “external”, but that we still want to open in new windows.

8👍

Try something like

for (var links = document.links, i = 0, a; a = links[i]; i++) {
        if (a.host !== location.host) {
                a.target = '_blank';
        }
}

Don’t forget to run the script by the time all links exist in the document tree – in window.onload event.

👤duri

4👍

You could do something like this:

$(document.body).on('mouseover', 'a[target!=_blank]:not(.local)', function (evt) {
    var a = $(this);
    var href = a.attr('href');
    var domain = href.match(/^https?:\/\/([^:\/]+)/);
    if (domain && domain[1] && domain[1] !== "yourdomain.com") {
        a.attr('target', '_blank');
    } else {
        a.addClass('local');
    }
});

This will process each link as you click it, and shouldn’t process each link more than once. If it needs to be external, the target will be set to _blank and it should open in a new window. Here’s a working jsfiddle.

Update: My method of determining if the link stays on-site or not is quite crude. The method in this answer is more thorough. I would probably replace my simple regex match with that test instead.

2👍

I recommend you do that server side.
Modify the template of the page depending on the locality of the link.

1👍

Another JavaScript solution:

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

1👍

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);

0👍

You could also do this:

$("a[href^='http://']").attr("target","_blank");

or

$('a').each(function() {
   var a = new RegExp('/' + window.location.host + '/');
   if(!a.test(this.href)) {
       $(this).click(function(event) {
           event.preventDefault();
           event.stopPropagation();
           window.open(this.href, '_blank');
       });
   }
});

0👍

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');
👤Dupls

Leave a comment