/ react

Building AutoLink component in React

Today, I had to implement a React component which takes text and adds links to the detected URLs:

  This text contains link to http://example.com and https://example.com

This generates the following HTML:

  This text contains link to <a href="http://example.com" target="_blank">http://example.com</a> and <a href="https://example.com" target="_blank">https://example.com</a>

In order to build this component, I had to use а little know feature of the String.prototype.split method. Most people know that if you have the following string a,c,d,e you can split it by ,, you get an array:

"a,b,c".split(/,/) // => ["a", "b", "c"]

Today I learned, that you can actually include the separator in the results:

"a,b,c".split(/(,)/) // => ["a", ",", "b", ",", "c"]

This uses the regular expression group feature.

Using this feature, I created a mapLinks function. It takes the text and yields the links it detects.

const EXP = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi; 

export function mapLinks(text, fn)) {
  // this splits the text, by links but it still keeps those links in the result
  return text.split(EXP).map((chunk, i) => {
    if (chunk.match(EXP)) {
      return fn(chunk, i);

    return chunk;

Then I just used this function for the component itself:

export default React.memo(({ children }) => (
    {mapLinks(children, (url, i) => (
      <a href={url} target="_blank" key={i}>