FreeToGenerate.com

Link to an exact phrase on any page. The part after the delimiter is hidden from the page it points at — the spec says so. Nothing is uploaded.

Try one:

Build a link

The page you want to link into. Any fragment already there is kept.

The only required part. Copy it exactly as it appears on the page, including punctuation.

Give this to highlight a passage: the match runs from the first occurrence of the text above to the first occurrence of this after it. Useful when the passage is long.

Used to disambiguate when the phrase appears more than once. It has to be present for the match to succeed and is not itself highlighted.

The same, on the other side.

Your link

https://example.com/article#:~:text=an%20example%20text%20fragment

Nothing in this text needs special handling; the naive encoding would work too.

Inspect a link

Useful for a link somebody sent you that lands in the wrong place, and for seeing what the target page is told.

Everything here runs in your browser. Nothing you paste is uploaded.

Also available in: Español · Português · Français · العربية

Text fragment generator: link to specific text on a page

Build a link that scrolls to and highlights an exact phrase, and take apart one somebody sent you.

What is a text fragment?

A text fragment is a link that opens a page and jumps straight to a phrase inside it, highlighting the match. You do not need the page to have an anchor there, and you do not need to control the page at all — the target is the words themselves. It is written into the ordinary URL fragment, after a delimiter of three characters, so it looks like a normal link with a tail on the end.

That matters because the alternative is telling somebody to open a long article and search for a sentence. A text fragment does it for them, which is why browsers added a Copy link to highlight command and why the same syntax turns up in search results that drop you at the relevant paragraph rather than the top of the page.

This page builds one from the text you want to highlight, and takes one apart in the other direction. Both halves matter, because the syntax has two edges that quietly produce a link pointing somewhere other than where you meant.

How to use it

  1. Give the page URL and the text. Copy the phrase exactly as it appears on the page, punctuation included. Everything else is optional: an end term makes it a range, and the two context fields disambiguate a phrase that appears more than once.
  2. Copy the link. If your text contains a character the syntax reserves, the tool also shows what the usual JavaScript encoder would have produced and what that version actually means, which is rarely the same thing.
  3. Or paste a link to take apart. The inspector shows each directive it finds, and separately the URL the target page receives — which is not the one you pasted.

The part the page it points at cannot see

The directive is separated from the rest of the fragment by three characters: a colon, a tilde and another colon. That delimiter exists so the syntax can be added to URLs without breaking pages that already use fragments for their own purposes, and it has a second consequence that is easy to miss.

The specification is explicit: the directive is stripped from the APIs a page can reach, to prevent it interacting with author script. So the page you link into never sees the phrase you used. Its own code, reading the current URL, gets everything up to the delimiter and nothing after it. The section describing the mechanism is even titled around hiding the directive from script.

That is a deliberate privacy decision — a link containing a sentence somebody was reading is more revealing than a link to a page — and it is also why the format can grow. Because pages cannot observe directives, browsers can define new ones without breaking anything, which is why an unrecognised directive is allowed rather than being an error. The inspector here shows unknown directives as such rather than rejecting them.

The character the obvious encoder gets wrong

Text in a fragment has to be percent-encoded, and the specification names three characters that must be escaped inside a text parameter: the dash, the ampersand and the comma. They carry meaning in the syntax, so a literal one changes what the link says.

The standard JavaScript encoder escapes two of those three. It leaves the dash alone, because a dash is a perfectly ordinary URL character everywhere else — and that is exactly the character the syntax uses to mark context terms. A prefix is written as text, a dash, then a comma; a suffix is a comma, a dash, then text. So a dash sitting next to a comma is structural.

The consequence is a link that works, opens the page, highlights the wrong thing, and gives no indication anything went wrong. Ask for a range from the well-known- to problem, encode it the familiar way, and the result reads as a prefix of the well-known followed by a start of problem: different terms, a different match, no error. The tool shows both versions side by side whenever your text can trigger it, and says nothing when it cannot — most text contains none of the three characters and encodes identically either way.

Anyone who has built a mailto link will recognise the shape of this. That format also looks like a query string and also treats one character differently from the encoder everybody reaches for.

Honest limitations

This tool cannot tell you whether the text is actually on the page. It has no way to fetch the target — a browser will not let one site read another's content — so it builds a link that is correct by the syntax and says nothing about whether it will find a match. If the phrase has changed since you copied it, the browser opens the page normally and scrolls nowhere.

It also cannot promise the browser will act on it. Support is checked the way the specification suggests, by looking for the fragment directive interface on the document, and that answer appears above for whatever browser you are reading this in. Beyond support, browsers apply their own restrictions about when a fragment is honoured, and a link that works when clicked from one place may do nothing when opened from another.

Finally, matching is on the rendered text, not the markup. Whitespace between context terms and the target is allowed to vary, which lets a phrase span element boundaries, but a phrase broken up by markup in the middle may still not match. When a long phrase fails, a range with a short start and a short end is usually more robust than one long start term.

Why is it free?

Building a link is percent-encoding a few strings and joining them, and your browser does it as you type. No server is involved, so there is nothing to meter and no account to create.

Nothing is uploaded. The text you type and any URL you paste stay in this tab.