- Home
- HTTP Headers
- Referrer-Policy Header
Header
Referrer-Policy Header
Learn how Referrer-Policy controls how much referrer information is sent with requests. Protect user privacy while maintaining analytics functionality.
TL;DR: Controls how much referrer information is sent with requests to protect user privacy. Use strict-origin-when-cross-origin for balanced privacy and functionality.
What is Referrer-Policy?
The Referrer-Policy header controls how much referrer information (the URL of the previous page) is included in the Referer header when navigating from your site or loading resources. It’s a privacy and security feature that lets you decide what information to share about where users came from.
Think of it like deciding how much information to share when you refer someone to another place - you can share the full address, just the street name, or nothing at all.
How Referrer-Policy Works
Without policy (default behavior):
GET https://example.com/page HTTP/1.1
Host: example.com
```text
User clicks link to `https://external.com/article`:
```http
GET /article HTTP/1.1
Host: external.com
Referer: https://example.com/page?user=123&token=secret
Full URL including sensitive parameters is sent!
With strict policy:
HTTP/1.1 200 OK
Referrer-Policy: no-referrer
Content-Type: text/html
<html>...</html>
```text
User clicks link to external site:
```http
GET /article HTTP/1.1
Host: external.com
(no Referer header)
No referrer information is sent, protecting privacy.
Syntax
Referrer-Policy: <directive>
```text
Multiple policies can be comma-separated (browser uses first supported one):
```http
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
Policy Directives
no-referrer
Never send Referer header.
Referrer-Policy: no-referrer
```text
**Example:**
```http
From: https://example.com/private/page?id=123
To: https://external.com/article
Referer: (not sent)
```text
### no-referrer-when-downgrade (default)
Send full URL for same-protocol requests. Don't send when downgrading from HTTPS to HTTP.
```http
Referrer-Policy: no-referrer-when-downgrade
Examples:
From: https://example.com/page
To: https://other.com/article
Referer: https://example.com/page
From: https://example.com/page
To: http://other.com/article (downgrade)
Referer: (not sent)
origin
Send only the origin (scheme, host, port), not the full URL.
Referrer-Policy: origin
```text
**Example:**
```http
From: https://example.com/path/to/page?query=value
To: https://other.com/article
Referer: https://example.com/
```text
### origin-when-cross-origin
Send full URL for same-origin requests, only origin for cross-origin.
```http
Referrer-Policy: origin-when-cross-origin
Examples:
From: https://example.com/page1
To: https://example.com/page2 (same-origin)
Referer: https://example.com/page1
From: https://example.com/page1
To: https://other.com/page (cross-origin)
Referer: https://example.com/
same-origin
Send full URL for same-origin requests, nothing for cross-origin.
Referrer-Policy: same-origin
```text
**Examples:**
```http
From: https://example.com/page1
To: https://example.com/page2 (same-origin)
Referer: https://example.com/page1
From: https://example.com/page1
To: https://other.com/page (cross-origin)
Referer: (not sent)
```text
### strict-origin
Send only origin when protocol is same or upgraded, nothing when downgrading.
```http
Referrer-Policy: strict-origin
Examples:
From: https://example.com/private/page
To: https://other.com/article
Referer: https://example.com/
From: https://example.com/page
To: http://other.com/article (downgrade)
Referer: (not sent)
strict-origin-when-cross-origin (recommended)
Full URL for same-origin, origin for cross-origin (if not downgrading), nothing when downgrading.
Referrer-Policy: strict-origin-when-cross-origin
```text
**Examples:**
```http
From: https://example.com/page1?user=123
To: https://example.com/page2 (same-origin)
Referer: https://example.com/page1?user=123
From: https://example.com/page?user=123
To: https://other.com/article (cross-origin)
Referer: https://example.com/
From: https://example.com/page
To: http://other.com/article (downgrade)
Referer: (not sent)
```text
### unsafe-url
Always send full URL (least privacy).
```http
Referrer-Policy: unsafe-url
Example:
From: https://example.com/private/page?token=secret
To: http://other.com/article
Referer: https://example.com/private/page?token=secret
Warning: This can leak sensitive information!
Common Examples
Privacy-Focused Site
HTTP/1.1 200 OK
Referrer-Policy: no-referrer
Content-Type: text/html
<!DOCTYPE html>
<html>
<!-- No referrer sent for any links -->
</html>
```text
### Balanced Privacy and Analytics
```http
HTTP/1.1 200 OK
Referrer-Policy: strict-origin-when-cross-origin
Content-Type: text/html
Most common and recommended policy.
Same-Origin Only
HTTP/1.1 200 OK
Referrer-Policy: same-origin
Content-Type: text/html
```text
Internal analytics work, external sites get nothing.
### Express.js Configuration
```javascript
app.use((req, res, next) => {
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
next()
})
Real-World Scenarios
E-commerce Checkout
HTTP/1.1 200 OK
Referrer-Policy: no-referrer
Content-Type: text/html
<!DOCTYPE html>
<html>
<!-- Protect order details in URL -->
<a href="https://payment.example.com/pay">
Complete Payment
</a>
</html>
```text
Prevents leaking order IDs or cart contents to payment processor.
### Social Media Platform
```javascript
// Node.js/Express
app.use((req, res, next) => {
// Protect user profiles from being leaked
if (req.path.startsWith('/user')) {
res.setHeader('Referrer-Policy', 'same-origin')
} else {
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
}
next()
})
Per-Link Policy (HTML)
<!-- Override default policy for specific links -->
<a href="https://analytics.example.com/track" referrerpolicy="no-referrer"> Track Event </a>
<a href="https://trusted-partner.com" referrerpolicy="origin"> Partner Site </a>
<!-- Image with no referrer -->
<img src="https://external.com/pixel.gif" referrerpolicy="no-referrer" />
```text
### API Endpoints
```javascript
// Different policies for different endpoints
app.get('/public/*', (req, res, next) => {
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
next()
})
app.get('/private/*', (req, res, next) => {
res.setHeader('Referrer-Policy', 'no-referrer')
next()
})
app.get('/admin/*', (req, res, next) => {
res.setHeader('Referrer-Policy', 'same-origin')
next()
})
Meta Tag Alternative
<!-- Can also be set via meta tag -->
<meta name="referrer" content="strict-origin-when-cross-origin" />
```text
**Note:** HTTP header takes precedence over meta tag.
## Best Practices
### 1. Use strict-origin-when-cross-origin as Default
```javascript
// ✅ Balanced privacy and functionality
app.use((req, res, next) => {
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
next()
})
2. Use no-referrer for Sensitive Pages
// ✅ Protect sensitive information
app.get('/account/payment', (req, res) => {
res.setHeader('Referrer-Policy', 'no-referrer')
res.render('payment')
})
app.get('/admin/users', (req, res) => {
res.setHeader('Referrer-Policy', 'no-referrer')
res.render('admin')
})
```javascript
### 3. Clean URLs Before External Links
```javascript
// ✅ Remove sensitive query parameters
function cleanURL(url) {
const cleaned = new URL(url)
// Remove sensitive params
cleaned.searchParams.delete('token')
cleaned.searchParams.delete('session')
cleaned.searchParams.delete('api_key')
return cleaned.toString()
}
4. Test Referrer Policy Impact
// ✅ Monitor analytics impact
app.use((req, res, next) => {
const referer = req.headers.referer || req.headers.referrer
// Log referrer availability for analytics
if (req.path.startsWith('/api/analytics')) {
console.log('Referer header present:', !!referer)
}
next()
})
```javascript
### 5. Helmet.js (Express)
```javascript
const helmet = require('helmet')
app.use(
helmet.referrerPolicy({
policy: 'strict-origin-when-cross-origin'
})
)
Common Patterns
Environment-Based Policy
const isDevelopment = process.env.NODE_ENV === 'development'
const referrerPolicy = isDevelopment
? 'unsafe-url' // Full URLs in dev for debugging
: 'strict-origin-when-cross-origin' // Strict in production
app.use((req, res, next) => {
res.setHeader('Referrer-Policy', referrerPolicy)
next()
})
```text
### Content-Type Specific
```javascript
app.use((req, res, next) => {
// API endpoints: no referrer
if (req.path.startsWith('/api')) {
res.setHeader('Referrer-Policy', 'no-referrer')
}
// Regular pages: balanced policy
else {
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
}
next()
})
Fallback Policy
# Multiple policies (first supported one is used)
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
```javascript
## Privacy Implications
### Protecting User Privacy
```javascript
// URLs that may contain sensitive info
const sensitivePatterns = ['/user', '/account', '/payment', '/admin', '/reset-password']
app.use((req, res, next) => {
const isSensitive = sensitivePatterns.some((pattern) => req.path.includes(pattern))
if (isSensitive) {
res.setHeader('Referrer-Policy', 'no-referrer')
} else {
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin')
}
next()
})
Query Parameter Leakage
# Bad: Sensitive data in URL
https://example.com/reset-password?token=secret123&email=user@example.com
# If referrer policy is unsafe-url:
User clicks external link → token and email leaked!
# Solution: Use no-referrer or keep tokens in POST body
Analytics Considerations
Impact on Analytics
// strict-origin-when-cross-origin allows:
// - Same-origin: full URL (good for internal analytics)
// - Cross-origin: origin only (protects privacy)
// Track referrer availability
app.get('/analytics/track', (req, res) => {
const referer = req.headers.referer
if (referer) {
// Can track traffic source
console.log('Traffic from:', referer)
} else {
// Referrer blocked by policy
console.log('No referrer (privacy protected)')
}
res.sendStatus(200)
})
```javascript
### UTM Parameters
```javascript
// Use UTM parameters for cross-origin tracking instead of relying on Referer
// ?utm_source=google&utm_medium=cpc&utm_campaign=spring_sale
app.get('/landing', (req, res) => {
const source = req.query.utm_source
const medium = req.query.utm_medium
// Track via query params, not Referer header
analytics.track({ source, medium })
res.render('landing')
})
Testing
Check Current Policy
# Using curl
curl -I https://example.com | grep -i referrer-policy
# Output:
# referrer-policy: strict-origin-when-cross-origin
```javascript
### Test Referrer Behavior
```html
<!-- Test page -->
<!DOCTYPE html>
<html>
<head>
<meta name="referrer" content="strict-origin-when-cross-origin" />
</head>
<body>
<script>
// Check what referrer is sent
fetch('https://httpbin.org/headers')
.then((r) => r.json())
.then((data) => {
console.log('Referer header:', data.headers.Referer || 'not sent')
})
</script>
</body>
</html>
Browser DevTools
1. Open DevTools → Network tab
2. Click link or load resource
3. Check request headers for "Referer"
4. Compare with current page URL
Browser Support
All modern browsers support Referrer-Policy:
- Chrome 61+
- Firefox 52+
- Safari 11.1+
- Edge 79+
Default policy (if not specified):
- Modern browsers:
strict-origin-when-cross-origin - Older browsers:
no-referrer-when-downgrade
Related Headers
- Referer - The referrer URL sent with requests
- Content-Security-Policy - General security policy
- X-Frame-Options - Clickjacking protection
- Origin - Request origin
Frequently Asked Questions
What is Referrer-Policy?
Referrer-Policy controls how much referrer information is sent with requests. It helps protect user privacy by limiting URL information shared with other sites.
What is a good default Referrer-Policy?
strict-origin-when-cross-origin is a good default. It sends full referrer to same-origin, only origin to cross-origin HTTPS, and nothing to HTTP.
What does no-referrer do?
no-referrer never sends the Referer header. Use it for maximum privacy but note it may break analytics and some functionality that depends on referrer.
Why is it Referrer-Policy but Referer header?
The Referer header has a historical misspelling from the HTTP specification. Referrer-Policy uses the correct spelling. Both refer to the same concept.