- Home
- HTTP Headers
- Refresh Header
Header
Refresh Header
Learn how the Refresh header instructs browsers to reload or redirect after a delay. Understand its use cases, limitations, and better alternatives.
TL;DR: Instructs browsers to automatically reload or redirect after a delay. Use proper HTTP redirects (301/302) instead for better UX and SEO.
What is Refresh?
The Refresh header instructs the browser to automatically reload the current page or redirect to a different URL after a specified number of seconds. It’s like setting a timer that says “in 5 seconds, go to this page” or “reload this page every 30 seconds.”
This header is non-standard but widely supported across browsers. It’s commonly used for page redirects, auto-refreshing dashboards, and “you will be redirected” pages.
How Refresh Works
Server sends Refresh header:
HTTP/1.1 200 OK
Refresh: 5; url=https://example.com/home
Content-Type: text/html
<html>
<body>
<p>You will be redirected in 5 seconds...</p>
</body>
</html>
```text
The browser waits 5 seconds, then automatically redirects to the specified URL.
## Syntax
```http
Refresh: <seconds>
Refresh: <seconds>; url=<url>
Values
- seconds - Delay in seconds before refresh/redirect
- url - Optional URL to redirect to (if omitted, reloads current page)
Common Examples
Auto Reload Current Page
Refresh: 30
```text
Reload the page every 30 seconds.
### Redirect After Delay
```http
Refresh: 3; url=https://example.com/home
Redirect to home page after 3 seconds.
Immediate Redirect
Refresh: 0; url=https://example.com/new-location
```text
Redirect immediately (0 second delay).
### Relative URL Redirect
```http
Refresh: 5; url=/dashboard
Redirect to relative URL after 5 seconds.
Real-World Scenarios
Post-Login Redirect
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=user&password=pass
HTTP/1.1 200 OK
Refresh: 2; url=/dashboard
Content-Type: text/html
<html>
<body>
<h1>Login Successful!</h1>
<p>Redirecting to dashboard in 2 seconds...</p>
</body>
</html>
```text
### Auto-Refreshing Dashboard
```http
GET /monitoring/dashboard HTTP/1.1
HTTP/1.1 200 OK
Refresh: 10
Content-Type: text/html
<html>
<body>
<h1>Server Status Dashboard</h1>
<p>Auto-refreshing every 10 seconds...</p>
<div id="metrics">
CPU: 45%, Memory: 60%, Disk: 75%
</div>
</body>
</html>
Payment Processing Page
POST /checkout/process HTTP/1.1
HTTP/1.1 200 OK
Refresh: 5; url=/checkout/confirmation
Content-Type: text/html
<html>
<body>
<h1>Processing your payment...</h1>
<p>Please wait. You will be redirected shortly.</p>
</body>
</html>
```text
### Session Expired Redirect
```http
GET /account HTTP/1.1
HTTP/1.1 200 OK
Refresh: 3; url=/login?expired=true
Content-Type: text/html
<html>
<body>
<h1>Session Expired</h1>
<p>Redirecting to login page in 3 seconds...</p>
</body>
</html>
Server Implementation
Express.js (Node.js)
const express = require('express')
const app = express()
// Auto-reload page
app.get('/dashboard', (req, res) => {
res.setHeader('Refresh', '30')
res.send(`
<html>
<body>
<h1>Dashboard</h1>
<p>Auto-refreshing every 30 seconds...</p>
<p>Current time: ${new Date().toLocaleTimeString()}</p>
</body>
</html>
`)
})
// Redirect after delay
app.post('/login', (req, res) => {
// Validate credentials...
res.setHeader('Refresh', '2; url=/dashboard')
res.send(`
<html>
<body>
<h1>Login Successful!</h1>
<p>Redirecting to dashboard in 2 seconds...</p>
</body>
</html>
`)
})
// Immediate redirect (alternative to 302)
app.get('/old-url', (req, res) => {
res.setHeader('Refresh', '0; url=/new-url')
res.send(`
<html>
<body>
<p>This page has moved. Redirecting...</p>
</body>
</html>
`)
})
// Processing page with countdown
app.post('/process', (req, res) => {
const delay = 5
res.setHeader('Refresh', `${delay}; url=/result`)
res.send(`
<html>
<head>
<script>
let seconds = ${delay};
setInterval(() => {
seconds--;
if (seconds >= 0) {
document.getElementById('countdown').textContent = seconds;
}
}, 1000);
</script>
</head>
<body>
<h1>Processing...</h1>
<p>Redirecting in <span id="countdown">${delay}</span> seconds...</p>
</body>
</html>
`)
})
```javascript
### FastAPI (Python)
```python
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from datetime import datetime
app = FastAPI()
@app.get("/dashboard", response_class=HTMLResponse)
async def dashboard():
current_time = datetime.now().strftime("%H:%M:%S")
return HTMLResponse(
content=f"""
<html>
<body>
<h1>Dashboard</h1>
<p>Auto-refreshing every 30 seconds...</p>
<p>Current time: {current_time}</p>
</body>
</html>
""",
headers={"Refresh": "30"}
)
@app.post("/login", response_class=HTMLResponse)
async def login():
# Validate credentials...
return HTMLResponse(
content="""
<html>
<body>
<h1>Login Successful!</h1>
<p>Redirecting to dashboard in 2 seconds...</p>
</body>
</html>
""",
headers={"Refresh": "2; url=/dashboard"}
)
@app.get("/old-url", response_class=HTMLResponse)
async def old_url():
return HTMLResponse(
content="""
<html>
<body>
<p>This page has moved. Redirecting...</p>
</body>
</html>
""",
headers={"Refresh": "0; url=/new-url"}
)
Django
from django.http import HttpResponse
from datetime import datetime
def dashboard(request):
current_time = datetime.now().strftime("%H:%M:%S")
response = HttpResponse(f"""
<html>
<body>
<h1>Dashboard</h1>
<p>Auto-refreshing every 30 seconds...</p>
<p>Current time: {current_time}</p>
</body>
</html>
""")
response['Refresh'] = '30'
return response
def login_success(request):
response = HttpResponse("""
<html>
<body>
<h1>Login Successful!</h1>
<p>Redirecting to dashboard in 2 seconds...</p>
</body>
</html>
""")
response['Refresh'] = '2; url=/dashboard'
return response
```nginx
### Nginx
```nginx
server {
listen 80;
server_name example.com;
# Auto-refresh monitoring page
location /monitoring {
add_header Refresh "10";
root /var/www/html;
}
# Redirect with delay
location /old-page {
add_header Refresh "3; url=/new-page";
return 200 "This page has moved. Redirecting...";
}
}
Best Practices
For Servers
1. Use proper redirects for permanent moves
# ❌ Don't use Refresh for permanent redirects
Refresh: 0; url=/new-location
# ✅ Use proper 301/308 redirect
HTTP/1.1 301 Moved Permanently
Location: /new-location
```javascript
**2. Provide visual feedback for delays**
```html
<!-- ✅ Show countdown for user experience -->
<h1>Processing...</h1>
<p>Redirecting in <span id="countdown">5</span> seconds...</p>
<script>
let seconds = 5
setInterval(() => {
seconds--
document.getElementById('countdown').textContent = seconds
}, 1000)
</script>
3. Use reasonable refresh intervals
# ✅ Reasonable for real-time data
Refresh: 10
# ❌ Too frequent, wastes resources
Refresh: 1
# ❌ Too long for meaningful updates
Refresh: 300
```text
**4. Include a manual link**
```html
<!-- ✅ Provide manual option -->
<p>You will be redirected in 3 seconds...</p>
<p>Or <a href="/dashboard">click here</a> to continue immediately.</p>
5. Consider using JavaScript alternatives
// ✅ More control with JavaScript
setTimeout(() => {
window.location.href = '/dashboard'
}, 3000)
// Or meta tag
<meta http-equiv="refresh" content="3; url=/dashboard">
```javascript
### For Clients
**1. Handle Refresh header**
```javascript
// Most browsers handle this automatically
// But you can detect it:
fetch('/page').then((response) => {
const refresh = response.headers.get('Refresh')
if (refresh) {
console.log('Page will refresh:', refresh)
}
})
2. Provide cancellation option
<!-- Allow users to cancel auto-redirect -->
<p>Redirecting in <span id="countdown">5</span> seconds...</p>
<button onclick="clearTimeout(redirectTimer)">Cancel</button>
<script>
const redirectTimer = setTimeout(() => {
window.location.href = '/dashboard'
}, 5000)
</script>
```text
## Refresh vs Other Redirect Methods
### Refresh Header
```http
HTTP/1.1 200 OK
Refresh: 3; url=/new-page
<html>Redirecting...</html>
Pros: Shows content while waiting Cons: Non-standard, can’t be cached by proxies
Location Header (301/302)
HTTP/1.1 302 Found
Location: /new-page
```text
Pros: Standard, immediate, cacheable
Cons: No delay option, no intermediate content
### HTML Meta Tag
```html
<meta http-equiv="refresh" content="3; url=/new-page" />
Pros: Works without server-side changes Cons: Only in HTML, not flexible
JavaScript
setTimeout(() => {
window.location.href = '/new-page'
}, 3000)
```http
Pros: Most flexible, can cancel, update UI
Cons: Requires JavaScript enabled
## Common Use Cases
### Auto-Refreshing Dashboards
```http
Refresh: 15
Keep monitoring dashboards up-to-date.
”Please Wait” Pages
Refresh: 5; url=/result
```text
Payment processing, job submission confirmation.
### Session Timeout Redirect
```http
Refresh: 3; url=/login?timeout=true
Redirect after session expires.
Temporary Maintenance Page
Refresh: 60
```text
Auto-refresh to check if site is back online.
### Post-Action Confirmation
```http
Refresh: 2; url=/home
After form submission, show success then redirect.
Accessibility Considerations
1. Provide sufficient time
# ✅ Give users time to read
Refresh: 5; url=/next-page
# ❌ Too fast for many users
Refresh: 1; url=/next-page
```text
**2. Announce to screen readers**
```html
<div role="status" aria-live="polite">You will be redirected in 5 seconds</div>
3. Avoid auto-refresh for content pages
# ❌ Bad for reading content
Refresh: 30 (on article page)
# ✅ Only for real-time data
Refresh: 30 (on dashboard/monitoring)
```text
## Testing Refresh Header
### Using curl
```bash
# Check for Refresh header
curl -I https://example.com/page
# View full response
curl -v https://example.com/page
# Extract Refresh header
curl -sI https://example.com/page | grep -i "^Refresh:"
Using JavaScript
// Check for Refresh header
fetch('/page').then((response) => {
const refresh = response.headers.get('Refresh')
if (refresh) {
const match = refresh.match(/(\d+)(?:;\s*url=(.+))?/)
if (match) {
const delay = parseInt(match[1])
const url = match[2]
console.log(`Refresh in ${delay} seconds`)
if (url) {
console.log(`Redirect to: ${url}`)
} else {
console.log('Reload current page')
}
}
}
})
```javascript
### Browser Testing
```javascript
// Monitor Refresh in DevTools
// Network tab -> Click request -> Headers -> Look for Refresh
// Or use console
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log('Refresh detected:', entry)
}
})
observer.observe({ entryTypes: ['navigation'] })
Related Headers
- Location - Standard redirect header
- Retry-After - Tell clients when to retry
- Content-Type - Type of content being served
- Cache-Control - Caching directives
Frequently Asked Questions
What is the Refresh header?
Refresh tells browsers to reload the page or redirect after a delay. Equivalent to meta http-equiv refresh. Example: Refresh: 5; url=https://example.com
Should I use Refresh for redirects?
No, use proper HTTP redirects (301, 302, 303, 307, 308) instead. Refresh is not a standard HTTP header and has accessibility and SEO issues.
What are the problems with Refresh?
It breaks the back button, confuses screen readers, is not a proper HTTP standard, and search engines may not follow it correctly. Use HTTP redirects instead.
When might Refresh be acceptable?
Only for auto-refreshing dashboards or status pages where users expect periodic updates. Even then, JavaScript or Server-Sent Events are better alternatives.