WhoDNS
All articles

Meta Refresh vs JavaScript vs 301: Choosing the Right Redirect

“Make this URL go to that one” hides three genuinely different mechanisms. Choosing between a server redirect, a meta refresh and a JavaScript redirect is not a style preference — the options differ in speed, crawlability, and how much ranking the destination keeps.

Server-side redirects: the default choice

An HTTP redirect happens before any content is sent: the server replies 301 Moved Permanently or 302 Found (or 307/308 preserving method) with a Location header, and the browser immediately requests the target. This is the fastest path and the only one search engines treat as a full signal transfer. Status code semantics matter:

  • 301: permanent. Search engines consolidate signals into the target. Use for domain moves, path migrations, HTTP-to-HTTPS.
  • 302/307: temporary. Use when the move may be undone — maintenance, A/B tests, seasonal pages. Do not use for migrations “just in case”; months of 302 leave ranking split between URLs.
  • 308: permanent with method preservation — right for API endpoints where PUT must stay PUT.

Typical nginx rule and Apache rule for a path migration:

rewrite ^/old-section/(.*) /new-section/ permanent;
RedirectMatch 301 ^/old-section/ /new-section/

Meta refresh: the legacy tool

<meta http-equiv="refresh" content="5; url=/new-page"> is honoured by browsers without JS, and Google mostly treats a short-delay meta refresh like a 301 — but other engines may not, and the delay means users stare at a page that says nothing. Legitimate uses are rare: interstitial “you are being moved” pages and environments where you cannot touch server config. Never use it for site migrations.

JavaScript redirects: last resort

window.location.href = "/new-page"; runs only after HTML and JS load, so it is the slowest option and the least legible to crawlers. It is appropriate inside single-page apps routing between views, or where the redirect decision depends on client-side state (locale detection, A/B assignment). For anything search-visible, pair it with a server-side redirect or canonical tag.

Migration checklist

  1. Map every old URL to a new destination — bulk, not per-page guesses.
  2. Use 301 for one-to-one moves; keep redirect chains at one hop (old → final, never old → middle → final).
  3. Update internal links to point directly at the new URLs; internal 301s waste crawl budget.
  4. Watch the search console and server logs for 404 spikes after launch.

Hand-writing rewrite rules across dozens of paths is where syntax errors slip in. The redirect rule generator takes your old/new URL pairs and emits ready-to-paste nginx, Apache and meta-refresh variants with the right status codes, so the server-side rule is correct the first time.

Testing before shipping

Verify redirects with curl rather than a browser, because a browser follows the chain silently and hides how many hops it took:

curl -sI http://example.com/old-page
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page

Check three things on every rule: the status code matches intent (301 for permanent, 302 for temporary), the Location is absolute and correct, and there is exactly one hop — follow the chain with curl -IL and count the responses. A redirect loop or a chain from http to https to www to final URL costs a full extra round-trip set per hop, which users notice on mobile connections even when nothing is technically broken.

meta refreshjavascript redirect301 redirect302seo redirectsnginx rewritehtaccess redirect