FreeToGenerate.com

A Link header is a list of links, not a lookup table keyed by relation — and the difference is where links quietly disappear. Nothing is uploaded.

The whole field value. Several links are separated by commas, but a comma inside angle brackets or a quoted string does not separate anything.

Try one:

Relative targets and anchors resolve against this, and it is what each link is about unless an anchor says otherwise.

Links

RelationTargetAboutAttributes
alternatehttps://api.example.com/frthe page itselfhttps://api.example.com/items?page=2hreflang: fr
alternatehttps://api.example.com/dethe page itselfhttps://api.example.com/items?page=2hreflang: de

How many links is that?

Links in this header
2
Distinct relation types
1

A parser that returns a map keyed by relation type can hold only the distinct ones, so it would silently drop the rest. The last one of each relation wins and the others vanish without an error.

Worth knowing

  • Two or more links share a relation type. This is ordinary and correct, and it is what a parser keyed by relation cannot represent.

Everything runs in your browser. Nothing is uploaded, and reloading the page forgets what you typed.

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

Link header parser: every link, not one per relation

Paste an HTTP Link header and see each link, what it is about, and how many a relation-keyed parser would drop.

What is the Link header?

The Link header does in HTTP what a link element does in HTML: it points from the response to some other resource and says how the two are related. Each link is a target in angle brackets followed by parameters, of which rel is required. A paginated API sends rel=next and rel=prev; a document might send rel=describedby; a page with translations sends one rel=alternate per language.

RFC 8288 defines it, and the shape it defines is a list. That sounds obvious and is the thing most tooling gets wrong, because the convenient way to hand a Link header to application code is as an object keyed by relation type, where you can write links.next.url. That representation cannot hold two links with the same relation, and the specification not only permits those, it relies on them.

This page parses the header as a list, applies each link's anchor so you can see which resource it is actually about, expands a multi-valued rel into the several links the specification says it establishes, and tells you how many links a relation-keyed parser would have room for.

How to use it

  1. Paste the header value. The whole field, without the field name. Commas separate links, except inside angle brackets or a quoted string, which is the single most common way a hand-rolled split goes wrong.
  2. Give the URL the header came with. Relative targets and anchors resolve against it, and it is what each link is about unless an anchor says otherwise. A base element in the page body does not affect this, and the specification says so explicitly.
  3. Read the count underneath. It shows how many links the header carries and how many distinct relation types they use. When those differ, a parser that returns a map keyed by relation is silently dropping the difference.

Where links disappear

Nothing in RFC 8288 says a relation type may appear once. The canonical counter-example is language alternates: a page available in French and German sends two links, both rel=alternate, differing only in their hreflang. A parser that returns an object keyed by relation type can hold one of them. The other is gone, with no error and no warning.

This was measured while the page was built. Of two published Link header parsers, one returns exactly such a map: given two alternates it returns a single entry, and given two links with different relations it returns both. That control matters, because it shows the loss is a property of the return type rather than of the parsing. The other parser returns both links every time.

Two things worth saying plainly, because they were guesses of mine that turned out to be wrong. Both parsers correctly expand a multi-valued rel into several links, and both surface the anchor parameter. The problem is not that the ecosystem parses the header badly. It is that one popular shape for the answer cannot express what the header is allowed to say.

Relation types are compared case-insensitively, and the parsing algorithm in the specification's own appendix case-normalises them to lowercase, so rel=NEXT and rel=next are the same relation. Two links written that way collide in a keyed map for the same reason.

The anchor changes what a link is about

By default a link's context is the resource the header came with: the page you fetched. The anchor parameter overrides that, and the specification is explicit that it may point at a fragment of the same resource or at a third resource entirely. A response about one document can carry a link describing a relationship belonging to another.

That is not a detail a parser can leave to the caller. RFC 8288 says link applications must not process the link without applying the anchor, and that an application unable to apply it should ignore the link completely. Treating anchor as one more attribute in a bag, next to type and hreflang, produces exactly the error the specification is warning about: a relationship recorded against the wrong resource.

So every link here shows what it is about, resolved, rather than listing anchor as a parameter and leaving you to notice. Where an anchor has moved the context, the row says so.

What this cannot tell you

It cannot tell you what a server sends. You paste a header; the page reads it. If you want to see the real headers for a URL, your browser's network panel or a command-line HTTP client will show them, including the several separate Link headers a response is allowed to send, which count as one list.

It does not check that a relation type means anything. Registered types come from an IANA registry and extension types are supposed to be URIs, but a header full of invented relations is still well-formed, and this page will parse it happily. The list of registered relations on this site is the place to check whether a name is real.

It also does not follow anything. A target is resolved to an absolute URL and left there; nothing is fetched, no link is verified, and a target that 404s looks exactly like one that works. And the type parameter is a hint by the specification's own wording, so a link claiming text/html tells you nothing reliable about what you would actually get.

Why is it free?

Parsing a header is string handling, and it runs in your browser. There is no server in the loop, so there is nothing to bill for and no account to create.

Nothing is uploaded. The header you paste never leaves the tab.