Text fragment linking

Alex Chan published a post today that struck me immediately as something I should s̸t̸e̸a̸l̸ adapt for my own use. It’s a bookmarklet that creates a URL linking to the selected text within a web page. The selected text is called a text fragment, and a link to it will typically cause your browser to scroll to the text in question and highlight it. Here’s an example on the MDN page about text fragments.

Chan’s bookmarklet uses this JavaScript:

javascript:
 1:  const selectedText = window.getSelection().toString().trim();
 2:  
 3:  if (!selectedText) {
 4:    alert("You need to select some text!");
 5:    return;
 6:  }
 7:  
 8:  const url = new URL(window.location);
 9:  url.hash = `:~:text=${encodeURIComponent(selectedText)}`;
10:  
11:  alert(url.toString());

It gets the selected text in Line 1, combines it with the URL of the page and the necessary directives in Lines 8 and 9, and displays it in a alert window in Line 11. If no text is selected, the bookmarklet puts up an error message via Lines 3–6.

This is great, but using it as-is while writing a post would force me to select the fragment URL in the alert window, copy it, and then switch to BBEdit (where I do all my writing) and call a script named Clipboard Link, which creates a Markdown reference link from the URL on the clipboard.1 I wanted an automation that didn’t require that many steps.

So I made this Keyboard Maestro macro:

KM Safari text fragment link

As you can see, this macro is meant to be run while BBEdit is the active application and can be called with the ⌃⌥⌘F hotkey. It executes a slightly edited version of Chan’s JavaScript:

javascript:
1:  const selectedText = window.getSelection().toString().trim();
2:  
3:  const url = new URL(window.location);
4:  url.hash = `:~:text=${encodeURIComponent(selectedText)}`;
5:  
6:  return url.toString();

The differences are that there’s no error handling (that’s done elsewhere in the macro) and it puts the text fragment URL into a Keyboard Maestro variable named InstanceFragmentURL instead of displaying an alert.

If InstanceFragmentURL ends with text=, we know that there was no selected text when the macro was invoked. That’s an error, so the Basso sound is played to tell me I made a mistake, and the macro is canceled. Otherwise, the text fragment URL is put on the clipboard and the Clipboard Link script is run by choosing it from the Blogging submenu of BBEdit’s Scripts menu.

You should know that this macro, like Chan’s bookmarklet, creates only the simplest kind of text fragment URL, and it links to the first instance of the text on the page. That might not be the instance you want to link to. For example, if I select this instance of the word “bookmarklet” on Chan’s page,

Screenshot of blog post with selected text

and call the macro, it will make this link, which goes to the word “bookmarklet” in the post’s title.

The MDN page on text fragments explains a set of directives that can be added to the URL to adjust which instance is linked. The prefix- and -suffix directives should be sufficient to uniquely define the fragment. If I need to do so, I’ll add them manually. Like this. I doubt there’s a good way to automate the addition of these directives, so I’m not going to waste my time trying.

I always know I’m going to learn something when Chan’s blog appears in my RSS feed. Today I was able to use what I learned right away.

Update 15 Sep 2025 2:01 PM
A couple of things I’ve learned since posting:

First, Jeff Johnson asked on Mastodon why I wasn’t using the Copy Link with Highlight item from Safari’s context menu.

Context menu with text fragment link

The short answer is that I didn’t know it was there. This is what happens when you’ve been using software so long you think you know it all and don’t pay attention to minor updates.

I’m not certain how helpful this will be. Using it will add a step to my fragment-linking workflow, but maybe the extra step is small enough not to worry about. However that falls out, it’s good to know that menu item is there. Chrome has a similar context menu item; Firefox, as far as I can tell, does not.

Also on Mastodon, Juande Santander-Vela linked to an interesting post by Sangye Ince-Johannsen that talks about the value of text fragment linking and ties it to the wider problem of link rot. There’s no question but that fragment links are more likely to go bad than page links—even minor page edits can ruin a text fragment link. Ince-Johannsen’s solution is a little extreme for me, but it’s worth considering if you really need your links to survive. Me, I’ve kind of resigned myself to a certain degree of impermanence to the web. While I don’t like it when links here go bad, ANIAT is just a blog, and there’s a limit to what I’m willing to do to ensure link stability.


  1. I thought I’d written a post about Clipboard Link, but apparently not. I guess I’ll have to do that now.