# Referer Header: What It Sends and How to Control It

> Referer tells a server which page a request came from. What browsers send under the default strict-origin-when-cross-origin policy, and how to trim it.

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

> **TL;DR:** `Referer` (yes, misspelled) is the request header that tells a server which page the request came from. Under the browser default, same-origin requests get the full URL, cross-origin HTTPS requests get only the origin (`https://blog.example.com/`), and HTTPS-to-HTTP requests get nothing. Use it for analytics and as a CSRF signal; it's easy to fake and often missing, so never use it for authentication.

## What is Referer?

Browsers attach `Referer` to navigations and resource loads to say where the request came from. The header keeps its historical misspelling; [Referrer-Policy](https://howhttpworks.com/headers/referrer-policy) is spelled correctly. The "referrer" isn't always the previous page: when a document loads an image or calls fetch, that document is the referrer. [RFC 9110 section 10.1.3 defines the field](https://www.rfc-editor.org/rfc/rfc9110.html#section-10.1.3).

## How Referer Works

Say a reader is on `https://blog.example.com/posts/caching?edition=web#examples`, and the page uses the default `strict-origin-when-cross-origin` policy. Clicking a link to `https://shop.example.com/products` sends (examples on this page are trimmed):

```http
GET /products HTTP/1.1
Host: shop.example.com
Referer: https://blog.example.com/
```

The shop only learns the origin. A link to another page on the blog itself would carry the path and query too. The fragment (`#examples`) is never sent.

## Referer Format

Here's what a same-origin request from that page carries:

```http
Referer: https://blog.example.com/posts/caching?edition=web
```

Browsers always strip the fragment and any `user:password@` part. Depending on the policy, they may also cut the value down to the origin with a trailing `/`, or drop the header entirely. [MDN lists which URL parts are allowed](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referer).

## When Browsers Send Referer

Links, form submissions, images and fetches all carry it, subject to policy. Typing a URL or opening a bookmark usually means there's no referring page, so no header. A `no-referrer` policy or a link with `rel="noreferrer"` suppresses it. Under the default policy, going from HTTPS to HTTP drops it, but a page that sets `unsafe-url` sends the full URL even then.

To change the policy for one image without touching the rest of the page, set it on the element:

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

The image server still sees the URL being requested and the client's IP address. Referrer policy only controls what the request says about the page it came from.

## Real-World Examples

A same-origin request from your cart page to checkout carries the cart path. A referral from another HTTPS site usually carries only that site's origin. That includes search engines, so plan your analytics without their full query URLs or any particular vendor's referral format.

Here's a checkout request from `https://shop.example.com/cart?coupon=SPRING` under the default policy:

```http
GET /checkout HTTP/1.1
Host: shop.example.com
Referer: https://shop.example.com/cart?coupon=SPRING
```

Source and destination share an origin, so checkout sees the cart's query string. Move checkout to `https://pay.example.com` and it gets only the origin, even though both belong to the same company. Same-site isn't same-origin.

## Server-Side Usage

Parse the value before you compare it. This helper returns an HTTP(S) origin, or null:

```javascript
function referralOrigin(value) {
  if (typeof value !== 'string') return null
  try {
    const url = new URL(value)
    return ['http:', 'https:'].includes(url.protocol) ? url.origin : null
  } catch {
    return null
  }
}
```

Compare the result against a configured public origin such as `https://app.example.com`, not against a substring of `req.headers.host`. Treat it as context; it's not a login check.

In an existing Express app, the helper can label each request's referral without keeping the full URL:

```javascript
app.use((req, res, next) => {
  const origin = referralOrigin(req.get('Referer'))
  res.locals.referral = origin === null ? 'unknown'
    : origin === 'https://shop.example.com' ? 'internal' : 'external'
  res.locals.referralOrigin = origin
  next()
})
```

Define "internal" with a configured origin; the incoming Host header is under the client's control. Use the label for reporting, and let checkouts with an unknown referral through, because plenty of legitimate ones arrive that way. Clients outside the browser can send any value they like.

## Privacy and Security

URLs often contain account IDs or password-reset tokens, and Referer can leak them to third parties. On sensitive pages, set the policy in the document before it makes any requests:

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

For a single external link:

```html
<a href="https://partner.example.com/" rel="noreferrer">Partner</a>
```

## Common Referer Policies

The default is `strict-origin-when-cross-origin`: the full (stripped) URL for same-origin requests, the origin for cross-origin requests at the same security level, and nothing when going from HTTPS to HTTP. `no-referrer` sends nothing anywhere. `origin` drops the path and query everywhere, but sends the origin even from HTTPS to HTTP. [MDN compares all directives](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referrer-Policy#directives).

## Analytics Use Cases

Log a missing or unparseable value as "unknown". Calling it "direct" lumps typed URLs together with policy suppression and privacy tools. If you only need the referring origin, store only the origin.

For attribution you control, put a campaign parameter on the destination link:

```html
<a href="https://shop.example.com/products?campaign=partner-newsletter">
  View products
</a>
```

The parameter is part of the destination URL, so it survives `no-referrer` and shows up in your logs whether or not a Referer was sent. Anyone can type it, though, so treat it as untrusted reporting data rather than evidence the visit came from the partner.

## Security Considerations

A prefix check like `referer.startsWith('https://app.example.com')` also accepts `https://app.example.com.attacker.example/`. Parse both sides and compare origins exactly. [OWASP lists Origin/Referer checks as one layer of CSRF defense](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#checking-the-origin-header), alongside an explicit decision about missing values and separate authentication.

## Testing Referer Headers

```bash
curl -i https://app.example.com/checkout \
  --referer 'https://app.example.com/cart'
```

curl sends whatever value you give it and applies no referrer policy. To see real browser behavior, navigate from a served page and inspect the destination request in the Network panel. Note that `document.referrer` tells you how the current page was reached; it isn't the Referer the page sends on its own outgoing requests.

Compare a request with a referral and one without:

```bash
curl -i https://app.example.com/checkout
curl -i https://app.example.com/checkout --referer 'https://other.example/'
```

Both should succeed; this also checks that your analytics code copes with a missing header. To test how the browser trims the value, load a source page with a query string, follow a link to a same-origin page and one to another HTTPS origin, and look at each destination request.

## Getting Referer right

Browser scripts can't set `Referer` directly. Fetch offers `referrer` and `referrerPolicy` options, within limits. To suppress the referral on one request, set the policy and then check the request that went out:

```javascript
await fetch('/api/data', { referrerPolicy: 'no-referrer' })
```

## Related Headers

- [Referrer-Policy](https://howhttpworks.com/headers/referrer-policy)
- [Origin](https://howhttpworks.com/headers/origin)
- [Sec-Fetch-Site](https://howhttpworks.com/headers/sec-fetch-site)
