How to Set Up 301 Redirects Without Losing Rankings

how to set up 301 redirects

Learning how to set up 301 redirects takes about ten minutes. Learning how to set them up without dropping a third of your organic traffic takes a bit longer, because the syntax is the easy part — the mapping, the testing, and the order of operations are where migrations go wrong.

A 301 tells browsers and crawlers that a URL has moved permanently. Google consolidates ranking signals onto the destination, and over subsequent recrawls the new URL replaces the old one in the index. Done properly, a migration costs you a few weeks of jitter. Done badly, it costs a quarter.

Build the redirect map before you touch a config file

Every successful migration I have run started with a spreadsheet, not a server. Two columns: old URL, new URL. Every row filled in deliberately.

Source your list of old URLs from three places, because no single source is complete. Export every URL from a full crawl of the existing site. Pull the top-performing URLs from Search Console’s Performance report, sorted by clicks over twelve months. And pull the URLs with external backlinks, since those carry equity you cannot afford to strand.

Then map each one to its closest genuine equivalent. The rule that matters: redirect to a page that answers the same question. Sending 400 retired product URLs to the homepage does not preserve anything — Google treats a redirect to an irrelevant destination as a soft 404 and passes no signal at all. If there is no equivalent, return 410 Gone and accept the loss cleanly.

Two habits make the map far more useful. Add a column for the reason behind each mapping, so the person auditing it in six months understands why a discontinued SKU points where it does. And sort the whole sheet by organic clicks descending, then hand-check the top 200 rows individually. Pattern rules are fine for the long tail; your best pages deserve a human decision each.

Apache: .htaccess and RewriteRule

On Apache, redirects live in .htaccess or the virtual host config. For a handful of one-to-one moves, Redirect is the simplest directive:

Redirect 301 /old-page/ https://example.com/new-page/

For pattern-based rules, use mod_rewrite. Two of the most common site-wide rules:

RewriteEngine On

# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# Force non-www to www
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

Order matters more than people expect. Put specific one-to-one rules above broad pattern rules, and combine your protocol and hostname rules into a single hop where you can — otherwise a visitor on http://example.com takes two redirects to arrive.

Be aware of the performance cost too. Apache reads .htaccess on every single request, and it re-evaluates every rule in the file. A few hundred rules is unnoticeable; twenty thousand hand-written lines will show up in your response times. Past a few thousand rules, move them into the virtual host config, use a RewriteMap backed by a flat file, or push the whole map to your CDN.

One more Apache-specific gotcha: if a rule appears not to fire at all, check that AllowOverride permits .htaccess in that directory and that mod_rewrite is enabled. Silent failure is the default behavior when either is missing.

nginx, Shopify, and CDN-level rules

On nginx, redirects go in the server block and the config must be reloaded to take effect:

server {
    listen 443 ssl;
    server_name example.com;
    return 301 https://www.example.com$request_uri;
}

location = /old-page/ {
    return 301 https://www.example.com/new-page/;
}

Shopify handles this through Online Store → Navigation → URL Redirects, with a bulk CSV import for large batches. You cannot edit server config, and Shopify’s own /collections/ and /products/ URL structure limits what you can restructure — plan around it rather than fighting it.

If you sit behind Cloudflare or another CDN, you have a third option: Bulk Redirects or a redirect rule at the edge. These are fast and survive origin changes, but they add a layer someone will forget exists in two years. Document wherever you put them, and never split one migration’s rules across two layers.

The edge option has one real advantage worth weighing: it works no matter what happens to the origin. If you are retiring a platform entirely and pointing DNS at something new, CDN-level rules keep the old URL map alive after the old server is switched off. That is often the only way to preserve equity from a site you no longer host.

WordPress: plugin or server?

WordPress gives you both routes. A redirect plugin stores rules in the database and applies them in PHP, which means every redirect costs a full WordPress bootstrap. That is fine for a few hundred rules and noticeably slow at several thousand.

For large-scale migrations, put the rules in .htaccess or nginx and keep the plugin for the ad-hoc ones editors create when they rename a post. Whichever you choose, avoid running two redirect systems that both think they own the same URL — that is the fastest way to build an accidental loop.

Test before, during, and after

Testing is not optional and it is not a spot check. Verify with a real HTTP request rather than a browser, because browsers cache 301s hard and will happily show you yesterday’s behavior:

curl -sIL https://example.com/old-page/ | grep -E "HTTP/|location"

You want to see exactly one 301 followed by one 200. Two 301s means a chain. A 302 means someone used the wrong code. A 200 on the old URL means the rule never fired.

Test in three passes rather than one. On staging before deploy, against the same server software and module set the production host runs. Immediately after go-live, on the URLs that carry the most organic clicks and the most referring domains. Then a full crawl a week later, because chains only surface once several rules have had a chance to interact with real traffic patterns.

Check four things across the whole map. Every old URL returns 301, not 302 or 200. Every destination returns 200, not another redirect or a 404. No rule produces a loop. And your internal links now point at the new URLs directly, not through the redirect — your own navigation should never rely on redirects it can simply avoid.

Doing this across thousands of rows needs a crawler that follows and reports every hop. SEO Rocket’s technical audit crawls full sites — verified past 900 pages — and reports evidence per issue rather than a count: the specific URLs, their redirect targets, and the titles and tags on both ends, which is the list you hand a developer. It does not deploy redirects or edit your server config for you; that stays in your .htaccess, nginx block, or CDN dashboard.

Launch sequence and what happens next

A workable order of operations for a full migration:

  1. Freeze content changes on the old site so your crawl stays accurate.
  2. Deploy redirects on a staging environment and test the full map.
  3. Go live, then immediately re-test the top 100 URLs by traffic and by backlinks.
  4. Submit a new XML sitemap containing only new URLs. Keep the old sitemap available for a few weeks so Google rediscovers the old URLs and processes their redirects.
  5. Watch Search Console’s Pages report for “Redirect error” and any spike in 404s.
  6. Monitor server logs or Crawl Stats for 5xx errors caused by redirect processing load.

Then be patient. Expect a dip. Traffic commonly falls for two to four weeks while Google recrawls and reassigns signals, and daily rank movement of two or three positions during that window is normal noise, not evidence of failure. Judge the migration on the trend across a month, and keep the redirects in place permanently — external links and old bookmarks keep sending real people for years after Google has stopped checking.