Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save shprink/bf9599e1d66b9dc4d151e89c1199ccb8 to your computer and use it in GitHub Desktop.
Save shprink/bf9599e1d66b9dc4d151e89c1199ccb8 to your computer and use it in GitHub Desktop.
@danielgamage
Copy link

For anyone swinging by, it's worth noting that this is client-side only, and I can't think of a great way of doing this in a server-side context, unless you want to pull in a variable from your process.env or a store.

But if anyone has ideas on making this universal...

@lsei
Copy link

lsei commented Dec 18, 2016

Noticed some issues with this on IE.

  • toLocation.host returns the port number.
  • Also doesn't work in IE when using urls without a fully qualified path.

Here's my updated script:

export default class Link extends React.Component {
  
  parseTo(to) {

    let parser = document.createElement('a');
    parser.href = to;
    return parser;

  }

  isInternal(to) {
    
    // If it's a relative url such as '/path', 'path' and does not contain a protocol we can assume it is internal.
    
    if(to.indexOf("://")=== -1) return true;

    const toLocation = this.parseTo(to);
    return window.location.hostname === toLocation.hostname;

  }

  render() {

    const {to, children, ...rest} = this.props;
    const isInternal = this.isInternal(to);

    if (isInternal) {
      return (<ReactLink to={to} {...rest}>{children}</ReactLink>);
    } else {
      return (<a href={to} target="_blank" {...rest}>{children}</a>);
    }

  }
}

@andrewmartin
Copy link

This is great, thanks for sharing!

@edina-a
Copy link

edina-a commented Mar 29, 2017

👍

@MichalCz
Copy link

MichalCz commented Nov 29, 2018

Perhaps you'd consider ditching the semicolon from '://' - protocol agnostic links won't work with your class (like //static.example.com/some/image.png which work well and creating a element is not necessary - at least if there's a // on the first char. :)

@gkiely
Copy link

gkiely commented Feb 19, 2019

V4 uses import {Link as ReactLink} from 'react-router-dom';

@colinschoen
Copy link

Here is an alternative utility function:

const isInternalURL = (to: string) => {
  try {
    const url = new URL(to, window.location.origin);
    return url.hostname === window.location.hostname;
  } catch {
    return false;
  }
};

@evadecker
Copy link

evadecker commented Apr 14, 2020

Here is an alternative utility function:

const isInternalURL = (to: string) => {
  try {
    const url = new URL(to, window.location.origin);
    return url.hostname === window.location.hostname;
  } catch {
    return false;
  }
};

This is awesome, thank you @colinschoen!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment