Redirect mapping template for site migrations

The short answer

The redirect mapping template is a CSV with one row per old URL: the page it maps to, the response it must give after launch (a 301 redirect, a 410 or no change), its priority and whether a crawl has checked it. Fill it from Google Search Console, backlink and crawl data, then convert it to your server’s import format.

Fill in the template, one row per old URL

If your site is changing domain, platform or URL structure, each old URL that earns clicks, links or index entries gets one row in this file before the new templates are built. If you would rather not build it yourself, you can get the map built and tested as an SEO-only package.

The CSV opens with this header and three fictional example.com rows. Delete the examples before the file goes to your developer.

Old URL,Old status,Old title,New URL,Redirect type,Priority,Notes,Checked
https://www.example.com/services/web-design.html,200,Example: Web Design Services,https://www.example.com/services/web-design/,301,High,Example row (fictional): page kept and its address changed,No
https://www.example.com/?p=123,200,Example: Blog Post,https://www.example.com/blog/example-post/,301,Medium,Example row (fictional): query-string address mapped to its new permalink,No
https://www.example.com/old-offer/,200,Example: Retired Offer,,410,Low,Example row (fictional): page retired on purpose; it returns 410 and no redirect,No

The XLSX version holds the same columns and example rows, plus three check columns for every row whose Redirect type is a 3xx. Chain check flags a New URL that is itself an Old URL with a redirect, Loop check flags a row that redirects to itself or to a URL that redirects back to it, and Home page check flags a New URL that is the site’s home page. The formulas fill the first 1,000 rows.

Each column has one job:

Column What to enter Values
Old URL The full old address, protocol included, exactly as Search Console lists it Full URL
Old status The code the old URL returns today, from a crawl 200, 301, 404
Old title The old title tag, for choosing the mapped page and for the parity check Text
New URL The full address of the mapped page Full URL, or blank if retired
Redirect type The response the old URL must give after launch 301 moved, 410 retired, 200 kept
Priority Which rows a crawl checks first High: clicks or backlinks; Medium: impressions or internal links; Low: the rest
Notes Why the row maps this way, and where the old URL came from Text
Checked Whether a crawl has confirmed the row No, then Yes with the date in Notes

Keep the Old URL column absolute, because crawlers need it that way: in Screaming Frog’s list mode, a URL without HTTP or HTTPS “won’t be read and uploaded”8. Plugins and server files want the path alone, so the domain comes off at the import step.

Write 301 for every URL that moves: Google’s redirects guide says permanent redirects “Show the new redirect target in search results”, temporary ones “Show the source page in search results”2. A 410 marks a page retired on purpose, so an old URL that returns a 404 in the launch crawl is one nobody handled.

Where the old URLs come from, and where each source stops

Old URLs come from four sources: Google Search Console, a backlink report, the current XML sitemap and a crawl of the old site. Google’s site-move guide adds server logs and asks you to “include URLs of embedded content in your site move plans: videos, images, JavaScript, and CSS files”1. Images get rows, and so do PDFs that other sites link to.

Each source also caps how many URLs it returns at once:

  1. A Search Console report export: “Data is truncated to 1,000 rows of representative examples of your data.”4
  2. The Search Analytics API, one request: its row limit has a “Valid range is 1–25,000; Default is 1,000”5.
  3. The same API across a day: Google gives the ceiling as “50,000 rows per day per site per search type”6.
  4. Screaming Frog’s SEO Spider: “The free version is restricted to crawling up to 500 URLs in a single crawl.”7
Bar chart of the most rows or URLs one source returns: Screaming Frog SEO Spider free version 500 URLs, a Search Console report export 1,000 rows, the Search Analytics API 1,000 rows by default and 25,000 rows a request at most, and 50,000 rows a day per site and search type

A site with more than 1,000 pages that earned clicks will not fit one export: filter the Performance report by folder and export each part, or use the API with its row limit raised, over the longest date range offered.

Mistakes that break a redirect map

Each mistake below reads fine in the spreadsheet and fails on the live server, which is why the Checked column exists.

Mistake What happens Fix
Many old URLs mapped to the home page Google may treat them as soft 404s1 Map each URL to the page that holds its content
An old URL that already redirects, mapped to the page it used to redirect to A chain of two or more hops Enter the final page as New URL
An Apache Redirect line with no status Apache sends a 302, a temporary redirect15 Write Redirect 301
A short Apache Redirect path, such as /services Every URL under it redirects too, with its extra path appended15 Write each old path in full
Only one form of an address mapped The other slash or letter-case form misses Crawl both forms; add a row for each form Search Console lists

Chains cost little to prevent in the map. Google’s crawlers “follow up to 10 redirect hops”3, yet the site-move guide asks you to “keep the number of redirects in the chain low, ideally no more than 3 and fewer than 5”1. Pointing each old URL, including one that already redirects, straight at its final page keeps every chain at one hop.

Import formats for Redirection, Nginx and Apache

The import file is a conversion of three columns: Old URL, New URL and Redirect type. Below, the template’s three example rows appear in each format.

WordPress with the Redirection plugin

The Redirection plugin imports a CSV whose rows read “source URL,target URL”, optionally followed by “regex,http code,type”9. Its matching guide says a path “should always start with a /”, and query parameters are matched exactly by default11. Strip the domain from both columns:

/services/web-design.html,/services/web-design/,0,301
/?p=123,/blog/example-post/,0,301

The 410 row stays out of the file, because “Only redirect HTTP codes are supported (i.e. 301-307).”9 Add it in the plugin with the Error (404) action, whose codes include “410 – page gone”10. To have the whole move done end to end, ask for a WordPress move with this map: the move, the redirects and the launch crawls in one project.

Nginx

Nginx can hold the redirect rows in one map block keyed on $request_uri, the “full original request URI (with arguments)”14, so the query-string row matches as well. A return line13 then sends the 301 or the 410:

# in the http block
map $request_uri $mapped_page {
    /services/web-design.html  https://www.example.com/services/web-design/;
    /?p=123                    https://www.example.com/blog/example-post/;
}

# in the server block
if ($mapped_page) {
    return 301 "$mapped_page";
}
location = /old-offer/ {
    return 410;
}

Two details differ from Apache’s Redirect lines: nginx compares map strings “ignoring the case”12, and since each key holds the whole query string, a tagged link such as /services/web-design.html?utm_source=news misses an exact row that Apache would still redirect.

Apache

Apache’s mod_alias15 handles plain paths with Redirect, and its gone status returns a 410. A URL with a query string needs mod_rewrite, whose docs say “If you wish to match against the hostname, port, or query string, use a RewriteCond” with the matching variable16. In a WordPress .htaccess file, the lines go above # BEGIN WordPress, outside the basic WordPress block that runs from there to # END WordPress17:

Redirect 301 /services/web-design.html https://www.example.com/services/web-design/
RewriteEngine On
RewriteCond %{QUERY_STRING} =p=123
RewriteRule ^$ https://www.example.com/blog/example-post/? [R=301,L]
Redirect gone /old-offer/

The closing question mark drops the old query string, as the mod_rewrite docs explain: “When you want to erase an existing query string, end the substitution string with just a question mark.”16 A Redirect line matches a “case-sensitive (%-decoded) path”15 from its start, so /Services/web-design.html and /old-offer without its slash pass these lines untouched and reach WordPress. Add a row for each form Search Console lists.

Check the map with a crawler in list mode

A list-mode crawl of the Old URL column shows whether each row does what the map says, even when you are told the redirects are handled. Screaming Frog’s SEO Spider is one crawler with a list mode; its guide gives the settings below8:

  1. Before launch, switch to Mode > List, upload the Old URL column and crawl the old site. Copy each response code into Old status.
  2. Turn on Always Follow Redirects under Config > Spider > Advanced, so that redirects are “followed until they reach a non-3XX response”8.
  3. On staging, swap the domain in the upload for the staging host, add each path’s other form with or without its trailing slash, and crawl again.
  4. On launch day, crawl the same upload against the live domain and export the All Redirects report, which “will map out the full chain of redirects in a single report”8.
  5. Mark a row Yes in Checked when its old URL returns its Redirect type and reaches New URL in one hop. Send every other row to your developer, and repeat the crawl a week and a month after launch.

If every row passes and clicks still fall after launch, the cause is likely outside the redirects, and a diagnosis of the drop is the next step.

When to have the map built and tested

If organic search brings your business inquiries or sales, have the map built for you when any of these is true:

  • The site has more pages with clicks than one Search Console export holds.
  • The old platform puts fixed segments in its URLs, so rows have to become pattern rules.
  • Nobody on your side can edit the server configuration or the redirect plugin on launch day.
  • The launch date is set and nobody has crawled the old site yet.

The Migration Map, from $1,390 / £1,090, starts from the signed URL inventory, and we hand over the finished map as a file your server or plugin imports. If your developer has already written a map, the Launch Check, from $590 / £470, crawls it on staging and after launch. Both SEO-only packages are sized by URL count.

Agencies can buy client map QA under your brand, with crawl reports in the agency’s name. The map is one task in a relaunch, and the migration checklist sets out the rest.

Do it yourself

Hand it over

From $1,390 / £1,090

Frequently asked questions

What is a redirect map?

A redirect map is the plan your redirects are built from: one row for each old URL that still earns clicks, links or index entries, the page on the new site that replaces it, and the response that old URL must give once the new site launches. The launch crawls check the live server against the same rows.

Which URLs belong in a redirect map?

Every old URL that people or Google can still request: pages with Search Console clicks or impressions over the longest date range it offers, URLs with backlinks, indexed URLs and URLs in the current sitemap. Add old addresses that already redirect, plus linked PDFs and images. Each one gets a row, even when its row ends in a 410.

How do I import the map into WordPress, Nginx or Apache?

Convert the Old URL, New URL and Redirect type columns into the format your server reads. In WordPress, the Redirection plugin imports a CSV of paths and codes, though its import does not take 410 rows; Nginx takes a map block and a return line; Apache takes Redirect lines, plus mod_rewrite for URLs with a query string. Each format is set out above with the template’s example rows.

Should old URLs redirect to the homepage?

No. Point each old URL at the page that now carries its content, and let a page you retired on purpose return a 410. Google’s site-move guide says that sending many old URLs to one irrelevant page, such as the home page, “might be treated as a soft 404 error”. Several old URLs may share one mapped page only when their content was merged into it.
  1. Site Moves and Migrations Google Search Central. Accessed .
  2. Redirects and Google Search Google Search Central. Accessed .
  3. How HTTP Status Codes Affect Google's Crawlers Google for Developers. Accessed .
  4. Export data directly from a Search Console report Google Search Console Help. Accessed .
  5. Search Analytics: query (Search Console API) Google for Developers. Accessed .
  6. A deep dive into Search Console performance data filtering and limits Google Search Central Blog. Accessed .
  7. Screaming Frog SEO Spider Website Crawler Screaming Frog. Accessed .
  8. How To Use List Mode Screaming Frog. Accessed .
  9. Import and export Redirection. Accessed .
  10. Redirect Actions Redirection. Accessed .
  11. Matching a URL Redirection. Accessed .
  12. Module ngx_http_map_module nginx. Accessed .
  13. Module ngx_http_rewrite_module nginx. Accessed .
  14. Module ngx_http_core_module nginx. Accessed .
  15. mod_alias - Apache HTTP Server Version 2.4 Apache HTTP Server Project. Accessed .
  16. mod_rewrite - Apache HTTP Server Version 2.4 Apache HTTP Server Project. Accessed .
  17. Apache HTTPD / .htaccess (Advanced Administration Handbook) WordPress.org. Accessed .

Quotes and calls are free.

Get a quote