# Referrer-Policy Header

> Learn how Referrer-Policy controls how much referrer information is sent with requests. Protect user privacy while maintaining analytics functionality.

Source: https://howhttpworks.com/headers/referrer-policy
Last reviewed: 2026-10-05

> **TL;DR:** `Referrer-Policy: strict-origin-when-cross-origin` is the current default: send the stripped source URL to the same origin, only its origin to other HTTPS origins, and nothing on a normal HTTPS-to-HTTP downgrade. Use `no-referrer` to suppress the header everywhere.

## What is Referrer-Policy?

This response header governs referral information sent *from* a document on later navigations and resource requests. It does not erase a Referer already received by your server. The outgoing request field is spelled [Referer](https://howhttpworks.com/headers/referer).

## How Referrer-Policy Works

For a source at `https://app.example.com/account?view=full#profile`, the default permits this illustrative same-origin request header:

```http
Referer: https://app.example.com/account?view=full
```

For a request to `https://partner.example.com`, it permits only:

```http
Referer: https://app.example.com/
```

The fragment is excluded in both cases. A normal cross-origin HTTP destination receives no Referer under this policy. The [current Referrer Policy draft defines the default](https://w3c.github.io/webappsec-referrer-policy/#referrer-policies).

## Syntax

```http
Referrer-Policy: strict-origin-when-cross-origin
```

A comma-separated header list uses the **last recognized policy**, not the first. This lets an older fallback precede the preferred policy:

```http
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
```

The fallback list belongs in the HTTP header, not an HTML `referrerpolicy` attribute. [The parsing algorithm processes each recognized token in order](https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header).

## Policy Directives

For a source on HTTPS, the following compares a same-origin target, another HTTPS origin, and a normal non-trustworthy cross-origin HTTP target. “URL” means the source URL without user information or fragment.

| Policy | Same origin | Other HTTPS origin | Other HTTP origin |
| --- | --- | --- | --- |
| `no-referrer` | Omitted | Omitted | Omitted |
| `no-referrer-when-downgrade` | URL | URL | Omitted |
| `same-origin` | URL | Omitted | Omitted |
| `origin` | Origin | Origin | Origin |
| `strict-origin` | Origin | Origin | Omitted |
| `origin-when-cross-origin` | URL | Origin | Origin |
| `strict-origin-when-cross-origin` | URL | Origin | Omitted |
| `unsafe-url` | URL | URL | URL |

`no-referrer-when-downgrade` is an older default, not the current one. [MDN defines each directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy#directives).

## Common Examples

Inside an nginx server or location serving HTML:

```nginx
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
```

For Apache with `mod_headers`:

```apache
Header always set Referrer-Policy "strict-origin-when-cross-origin"
```

Use the documented [nginx](https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header) or [Apache](https://httpd.apache.org/docs/2.4/mod/mod_headers.html#header) directive and verify the final document response.

In an existing Express app, set a document default and override it for a sensitive route:

```javascript
app.use((_req, res, next) => {
  res.set('Referrer-Policy', 'strict-origin-when-cross-origin')
  next()
})
app.get('/reset-password', (_req, res) => {
  res.set('Referrer-Policy', 'no-referrer')
  res.sendFile('reset-password.html', { root: '/srv/app/public' })
})
```

Create that HTML file under the fixed root. Returning the override from the document route governs its later requests; setting it on `/api/reset-password` alone would not change the calling document.

With Helmet installed, its standalone middleware can set the default:

```javascript
const helmet = require('helmet')
app.use(helmet.referrerPolicy({ policy: 'strict-origin-when-cross-origin' }))
```

[Helmet documents this option](https://helmet.js.org/#referrer-policy). Register a sensitive route's override after it, and inspect the delivered HTML response to catch any later proxy setter.

For Caddy, this complete site block applies a default and then a path-specific override:

```caddyfile
app.example.com {
    route {
        header Referrer-Policy strict-origin-when-cross-origin
        header /reset-password Referrer-Policy no-referrer
        reverse_proxy localhost:3000
    }
}
```

[Caddy's header directive](https://caddyserver.com/docs/caddyfile/directives/header) accepts a matcher before the field name. The [route block preserves the written order](https://caddyserver.com/docs/caddyfile/directives/route), so the path override runs after the default. If the backend also sets Referrer-Policy, choose which layer owns the final value rather than depending on conflicting settings.

## Real-World Scenarios

A reset-password document containing a token in its URL can use `no-referrer` to avoid sending it to either same-origin or external subresources. The default still sends a path and query to same-origin destinations; origin-only cross-origin handling does not protect those internal requests.

A token placed in `#fragment` is excluded from Referer, but the default does not remove tokens in `?query` for same-origin requests. Do not test only an external analytics request and conclude the page is protected: an internal image, stylesheet, or API request can receive the source path and query.

Removing a query parameter from a destination link also does not remove it from the source page's URL. Policy is applied to the source URL when constructing the outgoing Referer.

## Meta Tag Alternative

```html
<meta name="referrer" content="no-referrer">
```

Place it early in the head, before resource loads. Processing this meta element updates the document's policy for subsequent requests, including when the response supplied a different policy. [HTML defines the update](https://html.spec.whatwg.org/multipage/semantics.html#meta-referrer).

## Getting Referrer-Policy right

Set the policy on the initiating document. Returning `no-referrer` on a JSON fetch response does not retroactively hide the incoming Referer or update the calling page's document policy.

## Common Patterns

For one link or image, use a single policy value:

```html
<a href="https://partner.example.com/" referrerpolicy="no-referrer">Partner</a>
<img src="https://images.example.com/logo.png" referrerpolicy="no-referrer" alt="Logo">
```

External stylesheets can carry their own referrer policy for resources they load, which is useful when diagnosing a CSS-initiated request that differs from a document-initiated one.

## Privacy Implications

Even `unsafe-url` excludes fragments and user information; it can still leak paths and queries. Policy is one control over referral disclosure, not a way to keep a sensitive URL out of history, logs, or other application code.

## Analytics Considerations

Origin-only referrals preserve a source origin but remove the referring page path. Missing Referer can result from policy or direct navigation; do not assign a definite cause from absence alone. Query parameters placed on the destination URL are separate from referral information.

For example, an incoming `https://blog.example.com/` identifies an origin but cannot tell you which article linked to the shop. A destination parameter such as `?campaign=launch` can provide an application-defined label, although visitors can edit it. Do not interpret the missing source path as a broken tracking implementation when the chosen policy deliberately removes it.

## Testing

```bash
curl -sS -D - -o /dev/null https://app.example.com/account
```

This checks what policy the server delivers. Test browser behavior by making same-origin and cross-origin requests from that document and inspecting their request headers in Network. Keep the test source URL non-sensitive.

A small same-origin probe makes this visible. Add this route to an existing Express app in a local test environment:

```javascript
app.get('/referrer-probe', (req, res) => {
  res.json({ referer: req.get('Referer') ?? null })
})
```

From a served page at `/test?marker=referrer-test`, run:

```javascript
for (const referrerPolicy of ['strict-origin-when-cross-origin', 'no-referrer']) {
  const response = await fetch('/referrer-probe', { referrerPolicy })
  console.log(referrerPolicy, await response.json())
}
```

The first same-origin request can include the source path and query; the second omits Referer. For a cross-origin comparison, navigate to a probe on another HTTPS origin you control, or inspect a subresource request there in Network. A cross-origin fetch probe would need CORS permission before JavaScript could read its JSON; CORS and referrer policy are separate checks.

Check the [compatibility data](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy#browser_compatibility) when supporting older clients. Browser privacy settings may restrict disclosure beyond a site's selected policy; a policy describes what may be sent, not a guarantee that every request includes it.

## Related Headers

- [Referer](https://howhttpworks.com/headers/referer)
- [Origin](https://howhttpworks.com/headers/origin)
- [Content-Security-Policy](https://howhttpworks.com/headers/content-security-policy)
