Mendhak / Code

Automatically hyperlinking the selected text when pasting a URL

A really nice quality of life feature I’ve noticed in some applications is the ability to automatically hyperlink some selected text when pasting a URL over it. To be clear this isn’t about automatically converting URLs in text into hyperlinks, rather when you have some text selected and you paste a URL over it, the text becomes a hyperlink to the URL just pasted.

Here it is in action. Try selecting some text, then copy a URL, and paste it over the selected text.

See the Pen Create hyperlink when pasted over selected text by mendhak (@mendhak) on CodePen.

This is a feature that I’ve seen in only a few applications: Slack, Notion, Confluence, Github, and the WordPress editor. It’s a small thing, it feels so natural, and it’s a nice touch that saves on clicks and keystrokes. It’s not present in VSCode natively, but is possible through the Markdown All In One extension.

Aside from those places, it’s sadly not a common feature; I find myself trying it out in various other applications and missing it. Having to highlight text and click an additional button or press a shortcut is now a small but noticeable friction.

The implementation is actually quite simple. In the paste event, inspect the clipboard data. Check if it’s a URL, and if it is, surround the selected text with an anchor tag.

document.querySelector('div').addEventListener("paste", (event) => {
  
  
  if(window.getSelection().toString()){
    let paste = (event.clipboardData || window.clipboardData).getData("text");
    if(isValidHttpUrl(paste)){
      event.preventDefault();
      var a = document.createElement('a');
      a.href = paste;
      a.title = paste;
      window.getSelection().getRangeAt(0).surroundContents(a);
    }
  }
});

The isValidHttpUrl function can be as simple or as crude as you’d like.
The event.preventDefault() is to let the browser know we’ll be handling the paste event for the special case of URLs.

It would be great if this became more commonly seen in more applications, and I hope this post helps someone implement it.