Dev

ExternalLinks.js

Opening external links in a new tab with pure js

Opening external links in the same tab is a flow killer.

When taking users off site, it’s best to keep the source page open and force a new tab.

While you could manually add target="_blank" to all external links, a little bit of JavaScript will help maintain your sanity and ensure nothing gets missed (cause, stuff always gets missed).

A simple way to accomplish this is by checking that a link’s hostname is not equal to window.window.location.hostname

For Example:

link.hostname !== window.location.hostname

Legit Links

But, you’ll probably want to go a bit deeper and exclude potential false positives and special hrefs, like: mailto:, tel:, js click handlers, etc.

A utility to check for legit External Links, might look something like:


/**
 * Checks if link is really external
 * and not a 'fake' external (ie; mailto, tel, js handler)
 * @param {HTML Element} link - single link instance
 * @return boolean
 */
function isExternal(link) {
  return (
      link.hasAttribute("href")     &&
      !link.href.match(/^mailto\:/) &&
      !link.href.match(/^tel\:/)    &&
      !link.href.match(/^#\:/)      &&
      link.hostname !== window.location.hostname
    );
}

All Together Now

Our final JavaScript component:

  1. Loops through all a tags on the page (links)
  2. Checks that they’re a legit external link
  3. If so, adds target="_blank">

The JavaScript


/**
 * External Links
 * Adds target="_blank" to real external links
 * so they open in a new tab.
 *
 * @author Stephen Scaff
 */
const ExternalLinks = (() => {

  const links = document.getElementsByTagName('a');

  return {

     /**
      * Init
      */
     init() {
       if (!links.length > 0) return;
        this.bindEvents();
     },

     /**
      * Bind Events
      */
     bindEvents() {
       ExternalLinks.checkLinks();
     },

     /**
     * ForEach Helper
     * Ensure we can loop over a object or nodelist
     * @see https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/
     */
    forEach: function (array, callback, scope) {
      for (var i = 0; i < array.length; i++) {
        callback.call(scope, i, array[i]);
      }
    },

    /**
     * Helper to check if link is really external
     * and not a 'fake' external (ie; mailto, tel, js handler)
     * @param {HTML Element} link - single link instance
     * @return boolean
     */
    isExternal(link) {

      return (
        link.hasAttribute("href")     &&
        !link.href.match(/^mailto\:/) &&
        !link.href.match(/^tel\:/)    &&
        !link.href.match(/^#\:/)      &&
        link.hostname !== window.location.hostname
      );
    },

    /**
     * Check Links
     * Loops through page links, if external
     * calls Speed Bump modal and applies follow link to btn.
     */
    checkLinks() {
      ExternalLinks.forEach (links, function (index, link) {
        if (!ExternalLinks.isExternal(link)) return
        link.target = '_blank';
      });
    },
 };
})();

Init


// Initialize
ExternalLinks.init();

// Or, something like
import ExternalLinks from './components/_ExternalLinks.js'
ExternalLinks.init();

Github

You can go snag a version of ExternalLinks.js on the Githubs, Right Here.

The repo includes both ES5 and ES6 versions.

Reduced Example

Here's a simple CodePen demo.

Read Next

Add Featured Images to the WordPress API

Read Story