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:
- A Search Console report export: “Data is truncated to 1,000 rows of representative examples of your data.”4
- The Search Analytics API, one request: its row limit has a “Valid range is 1–25,000; Default is 1,000”5.
- The same API across a day: Google gives the ceiling as “50,000 rows per day per site per search type”6.
- Screaming Frog’s SEO Spider: “The free version is restricted to crawling up to 500 URLs in a single crawl.”7

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:
- Before launch, switch to Mode > List, upload the Old URL column and crawl the old site. Copy each response code into Old status.
- Turn on Always Follow Redirects under Config > Spider > Advanced, so that redirects are “followed until they reach a non-3XX response”8.
- 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.
- 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.
- 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.
Frequently asked questions
What is a redirect map?
Which URLs belong in a redirect map?
How do I import the map into WordPress, Nginx or Apache?
Should old URLs redirect to the homepage?
Sources
- Site Moves and Migrations
- Redirects and Google Search
- How HTTP Status Codes Affect Google's Crawlers
- Export data directly from a Search Console report
- Search Analytics: query (Search Console API)
- A deep dive into Search Console performance data filtering and limits
- Screaming Frog SEO Spider Website Crawler
- How To Use List Mode
- Import and export
- Redirect Actions
- Matching a URL
- Module ngx_http_map_module
- Module ngx_http_rewrite_module
- Module ngx_http_core_module
- mod_alias - Apache HTTP Server Version 2.4
- mod_rewrite - Apache HTTP Server Version 2.4
- Apache HTTPD / .htaccess (Advanced Administration Handbook)
Related