What Referrer-Policy puts in Referer: the full URL, the origin, or nothing
Referrer-Policy decides what goes in Referer when a page loads an image or follows a link. The eight values, what is always stripped, where the policy is set, redirects and the Origin header.
Say a password reset page lives at https://example.com/account/reset?token=8f3a. If that page has one link to an outside help site, or one image from another domain, the browser may put the page’s address in the Referer header of that request, token and all. The W3C Referrer Policy spec opens with cases like this one: an HTTPS application with a session identifier in its URLs, and “capability URLs”, where the URL itself grants access.
Referrer-Policy is the rule for what goes into that header. Every policy ends up sending one of three things: the full URL (with some parts removed), only the origin, or no header at all.
What every policy strips
No policy sends the URL exactly as it is. The “strip url” algorithm in section 8.4 of Referrer Policy removes:
- the fragment (everything after
#) - the username and password (
user:passinhttps://user:pass@host/)
RFC 9110 section 10.1.3 asks for the same thing: a user agent MUST NOT include the fragment and userinfo components when it generates a Referer value. The same algorithm also returns no referrer at all if the URL’s scheme is a local scheme.
The origin-only policies go further and drop the path and the query, leaving scheme, host and port. The browser appends a / so the result is a valid URL, which is why an origin referrer looks like https://example.com/.
The “full URL” keeps the path and the query string. In the example above, https://example.com/account/reset?token=8f3a goes out unchanged; only a fragment would have been removed.
The eight values
Take a document at https://example.com/page?q=1 making requests to three places. Each policy gives the following, straight from the “Determine request’s Referrer” algorithm in section 8.3 of Referrer Policy and the examples in section 3.
| Policy | Same origin https://example.com/other |
Cross-origin https://not.example.com/ |
HTTPS to HTTP http://not.example.com/ |
|---|---|---|---|
no-referrer |
none | none | none |
no-referrer-when-downgrade |
full URL | full URL | none |
same-origin |
full URL | none | none |
origin |
origin | origin | origin |
strict-origin |
origin | origin | none |
origin-when-cross-origin |
full URL | origin | origin |
strict-origin-when-cross-origin |
full URL | origin | none |
unsafe-url |
full URL | full URL | full URL |
The strict- prefix is about the last column. The spec’s condition is a request from a TLS-protected document to a URL that is not “potentially trustworthy”, and in the spec’s examples an http:// address is that case. The strict- policies and no-referrer-when-downgrade send nothing there. A document that was served over plain HTTP in the first place doesn’t meet the condition, so strict-origin on such a page sends the origin anywhere.
A few details are easy to miss:
- Same origin means the request’s origin compared with the origin of the URL the request is currently going to. A note under
origin-when-cross-originsays that even a scheme upgrade, such ashttp://example.com/tohttps://example.com/, counts as a cross-origin request. - Section 10.1 says
origin,origin-when-cross-originandunsafe-urlcan leak the origin or URL of a secure site over insecure transport. Forunsafe-urlthe spec adds that the policy’s name doesn’t lie. strict-originsends only the origin even for same-origin requests. If you want to know which page within your own site a visitor came from, it isn’t the right choice.
Where the policy is set
Section 4 of Referrer Policy lists five ways a request gets its policy:
- the
Referrer-Policyresponse header <meta name="referrer" content="...">- a
referrerpolicyattribute ona,area,img,iframeorlink rel="noreferrer"ona,areaorlink- inheritance (an
srcdociframe, or a context created from a blob URL)
The header name doesn’t copy the old misspelling: the policy header is Referrer-Policy, the request header is Referer.
fetch() lets you set it per request. The Request constructor in the Fetch Standard uses the referrerPolicy option as the request’s policy, and referrer: "" sets the request’s referrer to no-referrer.
// Send only the origin with this request
await fetch("https://api.partner.example/v1/items", {
referrerPolicy: "strict-origin",
});
// Send no Referer with this request
await fetch("https://cdn.partner.example/pixel.gif", { referrer: "" });
When neither an element attribute nor a fetch() option sets anything, the request’s policy is the empty string. The current Fetch Standard’s main fetch algorithm then fills it in from the request’s policy container. Section 6 of Referrer Policy explains that the HTML Standard records a policy on the document from its response and uses it as the baseline for requests that document makes. So a request with no policy of its own gets the document’s.
Several values in one header
Section 8.1 reads the tokens of the Referrer-Policy header from left to right and overwrites the policy each time it recognises one. Unknown tokens are skipped, so the last recognised value wins. Section 11.1 presents this as the way to roll out new values: put a value older browsers understand first and the newer one after it.
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
A browser that knows the second value uses it; one that doesn’t stays with the first. The spec points out that this does not apply to the referrerpolicy attribute. For the attribute, it suggests setting the value from script and reading it back to see whether it’s supported.
A redirect response can change the policy
Before following a redirect, the Fetch Standard’s HTTP-redirect fetch calls “Set request’s referrer policy on redirect” from Referrer Policy. That algorithm parses the redirect response’s Referrer-Policy header the same way as section 8.1 and replaces the request’s policy only when the result is a recognised, non-empty value. If the header is missing or holds only unknown tokens, the policy stays as it was.
What matters is what the new policy is applied to. Main fetch works out the request’s referrer before the first request goes out and stores the result on the request. When the redirect is followed, main fetch runs again on the same request: a referrer that is already no-referrer is skipped, and a URL is reduced again under the new policy, starting from the value stored on the first hop.
So a redirect can change how much of what remains gets sent, but it can’t bring back what was already removed:
- A request sent under
no-referrerhasno-referreras its referrer from the start. A redirect response withReferrer-Policy: unsafe-urlstill doesn’t produce aReferer. - If only the origin survived the first hop, the path and query are already gone. A looser policy later on can send at most that origin.
- If the full URL survived the first hop, for example a same-origin request under
strict-origin-when-cross-origin, and the redirect response setsunsafe-urlwhile redirecting to another origin, that full URL goes to the other origin. Section 10.2 says the spec does not forbid switching to a less strict policy.
It also works the other way: if your own server returns the redirect, for a short link or a login hop, a strict policy on that response cuts down what the next request carries. Redirect status codes themselves are covered in the post on HTTP redirects.
It changes the Origin header too
Referrer-Policy affects more than Referer. “Append a request Origin header” in section 3.2 of the Fetch Standard checks the request in this order:
- If the request’s response tainting is
cors, or its mode iswebsocketorwebtransport, the origin is added as is and the policy plays no part. Main fetch sets response tainting tocorsfor a cross-origin request incorsmode, such as a cross-originfetch(). - Otherwise, a
GETorHEADrequest gets noOriginfrom this algorithm. - Otherwise, a request whose mode is
corsalso gets its origin unchanged, without the policy. A same-originfetch()POST lands here:fetch()defaults tocorsmode, and a same-origin request keepsbasicresponse tainting. - Any other request, such as one in
navigateorno-corsmode, hasOriginset tonulldepending on the policy:no-referrer: alwaysnullno-referrer-when-downgrade,strict-origin,strict-origin-when-cross-origin:nullwhen going from an HTTPS origin to a non-HTTPS URLsame-origin:nullfor a different origin
If your server checks Origin as part of its CSRF defence and you set no-referrer for the whole site, a request that is neither GET nor HEAD and is already in navigate mode reaches the policy switch in step 4, and under no-referrer that branch sets Origin to null. A same-origin fetch() POST under the same policy still carries the real origin. The note under this algorithm says the referrer policy is taken into account for every fetch where the fetcher did not explicitly opt into sharing its origin, for example through the CORS protocol. CORS and the Origin header are covered in the post on CORS preflight.
Where the default comes from
If nothing sets a policy, the browser default applies, and the document that defines that default has changed.
- The W3C document at
https://www.w3.org/TR/referrer-policy/is a Candidate Recommendation dated 26 January 2017. That version treats an empty policy asno-referrer-when-downgrade. - The Fetch Standard dated 6 October 2026 fills an empty policy from the HTML Standard’s policy container, and its Referrer Policy reference points to
https://w3c.github.io/webappsec-referrer-policy/.
So the default Fetch follows today is decided by the HTML Standard and the version Fetch points to, not by the 2017 document. That is why this post doesn’t present the 2017 default as what browsers do now. In practice you can sidestep the question: don’t rely on the default, and state the policy in a response header. motitory.com sends Referrer-Policy: strict-origin-when-cross-origin on every static response from public/_headers.
How to choose a value:
- Pages whose URLs carry tokens or personal identifiers:
no-referrerorsame-origin. If you need analytics within your own site,same-origin. - Ordinary pages:
strict-origin-when-cross-originis a reasonable choice. Same-origin requests get the full URL, other origins get the origin, plain HTTP gets nothing. unsafe-url,originandorigin-when-cross-origincan put information from an HTTPS page into HTTP requests. Use them only for a clear reason.
What the policy doesn’t do
- Referrer-Policy is a promise by the sender. Section 9.1 of Referrer Policy allows user agents to give users an option to suppress the referrer, and the Fetch Standard repeats this in a note. RFC 9110 says some intermediaries remove
Refererindiscriminately. Servers should handle requests with a missing or reducedReferer, and must not rely on it for access control; RFC 9110 also says not all requests contain it. - Section 1.2 notes that capability URLs can leak in other ways, and controlling the referrer is not enough to stop all of them. Section 17.9 of RFC 9110 recommends keeping sensitive data out of URIs in the first place: use POST for the form, transform the data before building the URI, or redirect to a different, server-generated URI.
Sources
- W3C Referrer Policy (Candidate Recommendation, 2017-01-26): sections 1.2, 2, 3–3.9, 4, 4.1, 4.4, 6, 8.1–8.4, 9.1, 10.1, 10.2, 11.1
- WHATWG Fetch Standard (Living Standard, 2026-10-06 version): 2.2.5 Requests, 3.2
Originheader, 4.1 Main fetch, 4.5 HTTP-redirect fetch, 4.6 HTTP-network-or-cache fetch, 5.4 Request class - RFC 9110 HTTP Semantics: 10.1.3 Referer, 17.9 Disclosure of Sensitive Information in URIs
Links and content checked on 18 October 2026. The Fetch Standard is a living document; the points above follow the version retrieved that day.