FreeToGenerate.com

Shows what each Referrer-Policy value really sends — and why the last value in the header is the one your browser uses. Nothing is uploaded.

One header per line. A browser reads them as a single comma-separated list, and the last value it recognises is the one that wins.

Try one:

How a browser reads that header

  • originrecognised, then overridden by a later value
  • unsafe-urlused — the last value recognised
Resolved policy
unsafe-url
Policy in force
unsafe-url

More than one value was recognised. The specification says the latest wins, which is what makes a staged fallback work: an older browser stops at the value it knows, a newer one carries on to the last.

Both must be full URLs with a scheme. The scheme matters: it decides whether the request counts as same-origin, cross-origin, or a downgrade.

What this request would send

Relationship
Downgrade — secure page to an insecure destination
Referrer information
The full URL, path and query included
Referer header sent
https://example.com/page.html

Every policy, side by side

PolicySame originCross-originDowngrade — secure page to an insecure destination
no-referrerNothing at allNothing at allNothing at all
no-referrer-when-downgradeThe full URL, path and query includedThe full URL, path and query includedNothing at all
same-originThe full URL, path and query includedNothing at allNothing at all
originThe origin onlyThe origin onlyThe origin only
strict-originThe origin onlyThe origin onlyNothing at all
origin-when-cross-originThe full URL, path and query includedThe origin onlyThe origin only
strict-origin-when-cross-originThe full URL, path and query includedThe origin onlyNothing at all
unsafe-urlThe full URL, path and query includedThe full URL, path and query includedThe full URL, path and query included

Each row is transcribed from the sentence in the specification that defines that policy. The row in force is highlighted.

Everything here runs in your browser. No URL or header is uploaded.

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

Referrer-Policy: every value compared, and the rule nobody mentions

Work out which policy is in force, what a given request would actually put in the Referer header, and why sending two values is a documented technique.

What the Referrer-Policy header does

When a browser follows a link or fetches a resource, it usually tells the destination where the request came from, in a header called Referer. Referrer-Policy is how a site controls how much of that it gives away — the full URL with its path and query, only the origin, or nothing at all. There are eight values, and the specification defines each one against three situations: a request to the same origin, a request to a different origin, and a request that leaves a secure page for an insecure destination.

The default, if you send no header at all, is strict-origin-when-cross-origin. That sends the full URL within your own site, only the origin when leaving it, and nothing when the destination drops to plain HTTP. It is a sensible default, and it is worth knowing, because a header that a browser cannot parse leaves you with exactly this and nothing else.

One small thing the specification points out about its own name: the header does not repeat the famous misspelling. The request header is Referer with one r, a typo old enough to be permanent. The response header that controls it is Referrer-Policy, spelled properly. Getting them the same way round is a common way to write a header that silently does nothing.

How to use it

  1. Paste your header. One header per line if you send more than one — a browser reads several Referrer-Policy headers as a single comma-separated list. The panel underneath shows each value and says which one a browser will actually use.
  2. Put in the two URLs. The page doing the linking and the destination. Both need a scheme, because the scheme is what decides whether the request counts as same-origin, cross-origin, or a downgrade, and those three are the only distinctions any of the policies make.
  3. Read the Referer row. It shows the exact header the request would carry, or says that no header is sent. The table at the bottom puts all eight policies side by side, with the one in force highlighted.

Why the last value wins, and why that is useful

This is the part that catches people out, and it is written down clearly. The specification says that unknown policy values will be ignored, and that when multiple sources specify a referrer policy, the value of the latest one will be used. Not the first. The parsing algorithm is three steps long: start with nothing, then for every token in the header, if it is a policy you recognise, set the policy to it. Whatever you recognised last is what you end up with.

That inverts the usual instinct. A header value that looks like a list normally means alternatives in order of preference, and the natural way to write a parser is to take the first thing you understand and stop. Here you must keep going, and a parser that stops early gets the wrong answer on the specification's own example.

The reason is deployment. The specification works the case itself: send origin followed by unsafe-url, and a browser too old to know unsafe-url ignores it and uses origin, while a current browser walks to the end and uses unsafe-url. So Referrer-Policy: origin, unsafe-url is not a mistake or a duplicated line — it is the documented way to adopt a new policy value without abandoning older clients. The grammar is built for it: the specification permits an unknown token specifically so that a browser does not fail to parse the entire header field when it meets one.

The same rule has a sharper edge. If nothing in your header is recognised — a typo, a value from a blog post that never shipped, a policy name with an underscore in it — the browser is left with the empty string and falls back to its default. The header did nothing at all, and nothing in the response tells you so. That is what the panel above reports first.

What each policy actually sends

The eight-by-three table on this page is transcribed from the sentence in the specification that defines each policy, rather than assembled from memory or from other people's tables. Two rows are worth reading twice, because they are the ones most often mixed up.

origin and strict-origin look nearly identical — both send only the origin — and they differ on exactly one square. origin sends it everywhere, including to plain HTTP; strict-origin withholds it on that downgrade. The specification is explicit about the reason, noting that origin allows the origin of HTTPS referrers to be sent over the network as part of unencrypted HTTP requests, and that strict-origin addresses this concern. The same pair repeats one level up: origin-when-cross-origin and strict-origin-when-cross-origin differ only in the downgrade column.

There is also a case that surprises people who think of origins as being about hostnames. An origin includes the scheme, so moving from http to https on the same host is a cross-origin request, not a same-origin one — the specification calls out protocol upgrades explicitly. A different port does the same thing. If a policy behaves differently than you expect for a request that stays on your own domain, this is usually why.

And unsafe-url means what it says. The specification adds a note that reads almost like an apology: the policy's name doesn't lie, it is unsafe, and it will leak origins and paths from secure resources to insecure origins. Its worked example uses a document called sekrit.html for a reason.

What this will not tell you

This works out what a policy means. It does not know what your server sends. A browser cannot read another site's response headers for you, so the header in the box is the one you typed, not the one in production — check that with your browser's network panel or a request from the command line.

The classification of a destination as secure or not is a simplification, and worth stating. The specification defers to a separate standard for what counts as a potentially trustworthy URL, and that algorithm covers more ground than this page implements: https, wss and file, plus localhost and the loopback addresses, are treated as trustworthy here and everything else is not. That covers every example in the specification and every case you are likely to type, but a scheme registered as trustworthy by a browser extension or a packaged application will be judged wrongly.

A page's policy is also not the only thing in play. A single link can override it with a referrerpolicy attribute, rel=noreferrer removes the referrer entirely, an iframe can set its own, and a redirect can change the policy partway through a request. This page answers the question for one policy and one pair of URLs, which is the question the header is about, and the rest are per-element decisions made in your markup.

Finally, none of this is a privacy guarantee. Suppressing the Referer header stops one specific leak; it does nothing about a URL you passed in a query string, a script that reports the location itself, or anything the destination can infer from the request in other ways. It is one useful control, not a curtain.

Why is it free?

Reading a header and comparing two URLs is text work, 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 and nothing is stored. Reload the page and it has forgotten the URLs you typed.