Q&A
How to redirect to a web page using HTML
Overview
A true web redirect should happen at the server level (via a Location header), but HTML's <meta http-equiv="refresh"> provides a client-side alternative when you only have access to the HTML - for static hosting, offline pages, or legacy systems. For JavaScript-capable environments, window.location is cleaner and instant.
graph TD
A[User hits the page] --> B["<meta> refresh timer starts"]
B --> C{delay == 0?}
C -->|yes| D["Immediate redirect to URL"]
C -->|no| E["Show current page, then redirect after N seconds"]
style D fill:#1e1b4b,color:#fff
Immediate Redirect with meta refresh
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=https://www.example.com">
<title>Redirecting…</title>
</head>
<body>
<p>If you are not redirected automatically,
<a href="https://www.example.com">click here</a>.</p>
</body>
</html>
content="0; url=..."-0seconds delay, then go to the URL.- The fallback
<a>link is important accessibility practice - some browsers or screen readers may not auto-follow the redirect.
Delayed Redirect (countdown)
<meta http-equiv="refresh" content="5; url=https://www.new-site.com">
<p>This page has moved. You will be redirected in 5 seconds.</p>
Useful for "page has moved" notices - show a message, then redirect automatically.
JavaScript Redirect (preferred when JS is available)
<script>
window.location.href = "https://www.example.com";
// or:
window.location.replace("https://www.example.com"); // no back-button history entry
</script>
location.href- adds an entry to browser history (user can press Back).location.replace()- replaces the current entry (no Back button to the old page).
For React/single-page apps, use the router's navigate() / <Navigate> component instead of touching window.location directly.
Server-Side Redirect (best practice)
For permanent or important redirects, configure at the server level - browsers, crawlers, and CDN caches handle these most efficiently:
Apache .htaccess:
Redirect 301 /old-page https://example.com/new-page
Nginx:
return 301 https://example.com/new-page;
Node/Express:
res.redirect(301, "https://example.com/new-page");
A 301 means "Moved Permanently" (crawlers update their index); 302 means "Moved Temporarily" (crawlers keep the old URL).
Comparing the Methods
| Method | Requires | SEO / Crawlers | Back button |
|---|---|---|---|
<meta refresh> |
Only HTML | Not ideal (some crawlers ignore it) | Yes |
window.location.href |
JavaScript | Not ideal | Yes |
window.location.replace() |
JavaScript | Not ideal | No |
| Server 301/302 | Server control | Best (301 = canonical) | 302 = yes, 301 = no |
Why This Matters in Interviews
HTML/web-fundamentals interviews use this to check whether you know the right tool for the context. Key points: <meta http-equiv="refresh"> is HTML-only but suboptimal for SEO and accessibility (always add a fallback link); window.location is clean for JS-capable environments; and server-level 301/302 redirects are the correct answer for production - they're faster, better for SEO, and don't require the page to load first. Explaining 301 vs 302 semantics shows HTTP maturity.
Common Pitfalls
- Omitting the fallback
<a>link - users without auto-redirect support are stuck. - Using meta-refresh for a permanent redirect that crawlers should track (use a server 301 instead).
- Using
location.hrefwhen you want to prevent the user going back to the redirect page (usereplace). - Putting a non-zero delay on a redirect in the
contentattribute by accident and confusing users.
References
- MDN
<meta http-equiv="refresh">: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections - HTTP redirects overview: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections