urltoolskit.org
URL utilities, in the browser
Say hi →

Link header

build or parse RFC 8288 · preload, preconnect, next, canonical · HTML equivalent alongside

The Link header does what a <link> tag does, except it arrives before the HTML does — which is why it is the only way to preload a resource without waiting for the document to parse, and the only way to declare a canonical or hreflang for a PDF. Build one from plain lines, or paste an existing header to read it.

Links

Ready.

How to use

  1. Build mode: one link per line — the URL, then the rel, then any attributes as key=value. Order within the attributes does not matter.
  2. Copy the Link header into your server config, or the HTML into your <head>. Both are generated from the same input, so they cannot drift apart.
  3. Parse mode: paste a header you received — a leading Link: is optional — and each link value is broken into URL, rel and attributes.
  4. Problems are appended to the table: a preload with no as, a value with no rel, malformed syntax.

The rel values worth using

preload — fetch this now, at high priority, because the page will definitely need it. It requires an as attribute: without one, browsers ignore the hint, or worse, fetch the resource twice with different priorities because the second fetch does not match the first in the cache. Fonts additionally need crossorigin even when same-origin, which is the other half of the "my preload is downloading twice" problem.

preconnect — open a connection (DNS, TCP, TLS) to a host you will use shortly. Worth it for one or two critical third parties; harmful beyond that, since each held-open connection has a cost and browsers cap them.

dns-prefetch — the cheap version, DNS only. Fine to use more liberally.

prefetch — fetch at low priority for a likely next navigation. Not for the current page; using it for something the current page needs delays it behind everything else.

canonical — the header form of the canonical tag, and the only way to set one on a non-HTML resource. If a PDF is reachable at several URLs, this is the fix.

alternate with hreflang — language alternates for non-HTML files. The hreflang generator emits this form too, with validation.

next and prev — pagination relationships. Google stopped using them for indexing in 2019, but browsers may still use next for speculative prefetching, and they remain correct semantics.

Header versus tag

Use the header when timing matters or there is no HTML: preloading a stylesheet the parser has not reached yet, or declaring metadata for a PDF, an image or an API response. A CDN or edge worker can add it without touching the origin, and with HTTP/2 it arrives with the response headers, well before the body.

Use the tag for everything else — it is visible in view-source, easy to audit, and does not require server configuration. One caution: a Link: rel=preload header used to trigger HTTP/2 Server Push on some CDNs. Push has been removed from Chrome and is deprecated generally, so if you inherited a config that relies on it, the preload hint is now doing the work and is the better behaviour anyway.

A syntax detail that catches people: several links go in one header separated by commas, with the URI in angle brackets and parameters after semicolons — </a.css>; rel=preload; as=style, </b.js>; rel=preload; as=script. Because commas separate links and the URI is bracketed, a comma inside a URL must be percent-encoded or the header splits in the wrong place.

FAQ

Can I send several Link headers instead of one?

Yes — repeated Link headers are equivalent to one comma-separated header, and are often easier to manage in server config. Parse mode accepts either.

Do the URLs have to be absolute?

No. Relative URLs are resolved against the request URL, which is usually what you want for your own assets. It is flagged as a note so you can confirm the base is what you expect — the relative URL resolver will show you exactly where one lands.

Which as values are valid?

script, style, image, font, fetch, document, audio, video, track, worker, embed, object. Using fetch for JSON and API responses is the common one people miss.

How do I check the header is being sent?

curl -sI https://example.com | grep -i link, then paste the result into parse mode. DevTools also flags unused preloads in the console, which is the fastest way to catch a preload with a typo'd URL.