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
- 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.
- 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.
- 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.