Redirects for SEO should be used correctly because they impact how websites are crawled and indexed by Google.
While most people think of redirects as an internet detour sign, much more is happening, and it’s surprisingly enjoyable to discover.
Keep reading for a comprehensive overview of redirects and the proper application for technical SEO.
What Is A Redirect?
Website redirects tell browsers and search engines information about a URL and where to find the webpage.
A URL redirect involves code implemented to a specific URL, or a group of URLs so that the user (or search engine) is sent to a different page to the actual URL that was input or clicked.
A redirect can be set as a:
- Temporary redirect: 302, 303, 307, 308.
- Permanent redirect: 301.
When To Use Redirects
The main reasons to use redirects are:
- An individual page or entire domain has been moved (URL changed).
- To allow the use of URL shorteners or ‘pretty URLs.’
- Site migration (e.g., HTTP to HTTPS).
For SEO purposes, URL redirects are important because they:
- Forward authority of any links pointing to a page that has moved or been deleted.
- Avoid 404 page not found errors (although sometimes it is better to leave a 404).
Redirects can be implemented on a group or domain-wide basis but often need to be set on an individual basis to avoid issues.
When using RegEX for group redirects, it can have unexpected results if your logic isn’t flawless!
Types Of Redirects
There are three main types of redirects:
- Meta Refresh redirects are set at the page level but are generally not recommended for SEO purposes. There are two types of meta redirect: delayed which is seen as a temporary redirect, and instant, which is seen as a permanent redirect.
- HTTP redirects are set server-side and the best approach for SEO purposes – we covered in-depth below.
What Is A HTTP Response Status Code?
Browsers and search engine crawlers like GoogleBot are called user agents.
When a user agent tries to access a webpage, what happens is that the user agent makes a request, and the website server issues a response.
The response is called an HTTP response status code. It provides a status for the request for a URL.
In the situation where a user agent like GoogleBot requests a URL, the server gives a response.
For example, if the request for a URL is successful, the server will provide a response code of 200, which means the request for a URL was successful.
So, when you think of a GoogleBot reaching a website and trying to crawl it, what’s happening is a series of requests and responses.
An HTTP redirect is a server response to request a URL.
If the URL exists at a different URL (because it was moved), the server tells the user agent that the URL request is being redirected to a different URL.
The response code for a changed URL is usually in the form of a 301 or 302 response status code.
The entire 3xx series of response codes communicate much information that can optionally be acted upon by the user agent.
An example of an action that the user agent can take is to save a cache of the new URL so that the next time the old URL is requested, it will ask for the new URL instead.
So, a 301 and a 302 redirect is more than an internet road sign that says, “Go here, not there.”
3XX Series Of Status Codes
Redirects are more than just the two status codes everyone is familiar with, the 301 and 302 response codes.
There are a total of seven official 3xx response status codes.
These are the different kinds of redirects available for use:
- 300 Multiple Choices.
- 301 Moved Permanently.
- 302 Found.
- 303 See Other.
- 304 Not Modified.
- 305 Use Proxy.
- 306 (Unused).
- 307 Temporary Redirect.
- 308 Permanent Redirect.
Some of the above status codes have not been around as long and might not be used. So, before using any redirect code other than 301 or 302, be sure that the intended user agent can interpret it.
Because GoogleBot uses the latest version of Chrome (called a headless browser), it’s easy to check if a status code is compatible by checking if Chrome recognizes the status code with a browser compatibility list.
For SEO, one should stick to using the 301 and 302 response codes unless there is a specific reason to use one of the other codes.
301: Moved Permanently
The 301 status code is routinely referenced as the 301 redirects. But the official name is 301 Moved Permanently.
The 301 redirect indicates to a user agent that the URL (sometimes referred to as a target resource or simply resource) was changed to another location and that it should use the new URL for future requests.
As mentioned earlier, there is more information as well.
The 301 status code also suggests to the user agent:
- Future requests for the URL should be made with the new URL.
- Whoever is making the request should update their links to the new URL.
- Subsequent requests can be changed from GET to POST.
That last point is a technical issue. According to the official standards for the 301 status code:
“Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 308 (Permanent Redirect) status code can be used instead.”
For SEO, when search engines see a 301 redirect, they pass the old page’s ranking to the new one.
Before making a change, you must be careful when using a 301 redirect. The 301 redirects must only be used when the change to a new URL is permanent.
The 301 status code must not be used when the change is temporary.
Additionally, if you change your mind later and return to the old URL, the old URL may not rank anymore and may take time to regain the rankings.
So, the main thing to remember is that a 301 status code will be used when the change is permanent.
The main thing to understand about the 302 status code is that it’s useful for situations where a URL is temporarily changed.
The meaning of this response code is that the URL is temporarily at a different URL, and it is suggested to use the old URL for future requests.
The 302 redirect status code also comes with a technical caveat related to GET and Post:
“Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead.”
The reference to “historical reasons” may refer to old or buggy user agents that may change the request method.
307: Temporary Redirect
A 307 redirect means the requested URL is temporarily moved, and the user agent should use the original URL for future requests.
The only difference between a 302 and a 307 status code is that a user agent must request the new URL with the same HTTP request used to request the original URL.
That means if the user agent requests the page with a GET request, then the user agent must use a GET request for the new temporary URL and cannot use the POST request.
The Mozilla documentation of the 307 status code explains it more clearly than the official documentation.
“The server sends this response to direct the client to get the requested resource at another URI with same method that was used in the prior request.
This has the same semantics as the 302 Found HTTP response code, with the exception that the user agent must not change the HTTP method used: if a POST was used in the first request, a POST must be used in the second request.”
Other than the 307 status code requiring subsequent requests to be of the same kind (POST or GET) and that the 302 can go either way, everything else is the same between the 302 and the 307 status codes.
302 Vs. 307
You may handle a redirect via server config files .htaccess on Apache, example.conf file on Nginx or via plugins if you are using WordPress.
In all instances, they have the same syntax for writing redirect rules. They differ only with commands used in configuration files. For example, a redirect on Apache will look like this:
Options +FollowSymlinks RewriteEngine on RedirectMatch 301 ^/oldfolder/ /newfolder/
(You can read about symlinks here.)
On Nginx servers, it will look like this:
rewrite ^/oldfolder/ /newfolder/ permanent;
The commands used to tell the server’s status code of redirect and the action command differ.
- Servers status code of redirect: “301″ vs. “permanent.”
- Action command: “RedirectMatch” vs. “rewrite.”
But the redirect syntax ( ^/oldfolder/ /newfolder/ ) is the same for both.
On Apache, ensure that mod_rewrite and mod_alias modules (responsible for handling redirects) are enabled on your server.
Since the most widely spread server type is Apache, here are examples for .htaccess apache files.
Make sure that the .htaccess file has these two lines above the redirect rules and put the rules below them:
Options +FollowSymlinks RewriteEngine on
To understand the examples below, you may refer to the table below on RegExp basics.
|*||zero or more times|
|+||One or more times|
|.||any single character|
|?||Zero or one time|
|^||Start of the string|
|$||End of the string|
|a|b||OR operadn “|” a or b|
|(z)||remembers the match to be used when calling $1|
How To Create Redirects
How To Create A Redirect For A Single URL
The most common and widely used type of redirect is when deleting pages or changing URLs.
For instance, say you changed the URL from /old-page/ to /new-page/. The redirect rule would be:
RewriteRule ^old-page(/?|/.*)$ /new-page/ [R=301,L]
RedirectMatch 301 ^/old-page(/?|/.*)$ /new-page/
The only difference between the two methods is that the first uses the Apache mod_rewrite module, and the second uses mod_alias. It can be done using both methods.
The regular expression “^” means the URL must start with “/old-page” while (/?|/.*)$ indicates that anything that follows “/old-page/” with a slash “/” or without an exact match must be redirected to /new-page/.
We could also use (.*), i.e., ^/old-page(.*), but the problem is, if you have another page with a similar URL like /old-page-other/, it will also be redirected when we only want to redirect /old-page/.
The following URLs will match and be directed to a new page:
It will redirect any variation of the page URL to a new one. If we use redirect in the following form:
Redirect 301 /old-page/ /new-page/
Without regular expressions, all URLs with UTM query string, e.g., /old-page?utm_source=facebook.com (which is common since URLs are used to be shared over a social network), would end up as 404s.
Even /old-page without a trailing slash “/” would end up as a 404.
Redirect All Except
Let’s say we have a bunch of URLs like /category/old-subcategory-1/, /category/old-subcategory-2/, /category/final-subcategory/ and want to merge all subcategories into /category/final-subcategory/. We need the “all except” rule here.
RewriteCond %REQUEST_URI !/category/final-subcategory/ RewriteCond %REQUEST_FILENAME !-f RewriteRule ^(category/). /category/final-subcategory/ [R=301,L]
Otherwise, if we have some assets like “/category/image.jpg,” it will also be redirected to “/final-subcategory/” and cause an image break.
You can use the rule below if you did a category restructuring and want to move everything from the old directory to the new one.
RewriteRule ^old-directory$ /new-directory/ [R=301,NC,L] RewriteRule ^old-directory/(.*)$ /new-directory/$1 [R=301,NC,L]
I used $1 in the target to tell the server that it should remember everything in the URL that follows /old-directory/ (i.e., /old-directory/subdirectory/) and pass it (i.e., “/subdirectory/”) onto the destination. As a result, it will be redirected to /new-directory/subdirectory/.
I used two rules: one case with no trailing slash at the end and the other one with a trailing slash.
I could combine them into one rule using (/?|.*)$ RegExp at the end, but it would cause problems and add a “//” slash to the end of the URL when the requested URL with no trailing slash has a query string (i.e., “/old-directory?utm_source=facebook” would be redirected to “/new-directory//?utm_source=facebook”).
Remove A Word From URL
Let’s say you have 100 URLs on your website with the city name “Chicago” and want to remove them.
For the URL http://yourwebiste.com/example-chicago-event/, the redirect rule would be:
RewriteRule ^(.*)-chicago-(.*) http://%SERVER_NAME/$1-$2 [NC,R=301,L]
If the example URL is in the form http://yourwebiste.com/example/chicago/event/, then the redirect would be:
RewriteRule ^(.*)/chicago/(.*) http://%SERVER_NAME/$1/$2 [NC,R=301,L]
Set A Canonical URL
Having canonical URLs is the most important part of SEO.
If missing, you might endanger your website with duplicate content issues because search engines treat URLs with “www” and “non-www” versions as different pages with the same content.
Therefore, you must ensure you run the website only with one version you choose.
If you want to run your website with the “www” version, use this rule:
RewriteCond %HTTP_HOST ^yourwebsite.com [NC] RewriteRule ^(.*)$ http://www.yourwebsite.com/$1 [L,R=301]
For a “non-www” version:
RewriteCond %HTTP_HOST ^www.yourwebsite.com [NC] RewriteRule ^(.*)$ http://yourwebsite.com/$1 [L,R=301]
Trailing slash is also part of canonicalization since URLs with a slash at the end or without are also treated differently.
RewriteCond %REQUEST_FILENAME !-f RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
This will make sure the /example-page is redirected to /example-page/. You may choose to remove the slash instead of adding then you will need the other rule below:
RewriteCond %REQUEST_FILENAME !-d RewriteRule ^(.*)/$ /$1 [L,R=301]
HTTP To HTTPS Redirect
After Google’s initiative to encourage website owners to use SSL, migrating to HTTPS is one of the commonly used redirects that almost every website has.
The rewrite rule below can be used to force HTTPS on every website.
RewriteCond %HTTP_HOST ^yourwebsite.com [NC,OR] RewriteCond %HTTP_HOST ^www.yourwebsite.com [NC] RewriteRule ^(.*)$ https://www.yourwebsite.com/$1 [L,R=301,NC]
Using this, you can combine a www or non-www version redirect into one HTTPS redirect rule.
Redirect From Old Domain To New
This is also one of the most used redirects when you decide to rebrand and need to change your domain. The rule below redirects old-domain.com to new-domain.com.
RewriteCond %HTTP_HOST ^old-domain.com$ [OR] RewriteCond %HTTP_HOST ^www.old-domain.com$ RewriteRule (.*)$ http://www.new-domain.com/$1 [R=301,L]
It uses two cases: one with the “www” version of URLs and another “non-www” because any page for historical reasons may have incoming links to both versions.
Most site owners use WordPress and may not need a .htaccess file for redirects but use a plugin instead.
Handling redirects using plugins may be slightly different from what we discussed above. You may need to read their documentation to handle RegExp correctly for the specific plugin.
Redirect Best Practices
1. Don’t Redirect All 404 Broken URLs To The Homepage
This case often happens when you are too lazy to investigate your 404 URLs and map them to the appropriate landing page.
According to Google, they are still all treated as 404s.
Yeah, it’s not a great practice (confuses users), and we mostly treat them as 404s anyway (they’re soft-404s), so there’s no upside. It’s not critically broken/bad, but additional complexity for no good reason – make a better 404 page instead.
— 🍌 John 🍌 (@JohnMu) January 8, 2019
If you have too many pages like this, you should consider creating beautiful 404 pages and engaging users to browse further or find something other than what they were looking for by displaying a search option.
It is strongly recommended by Google that redirected page content should be equivalent to the old page. Otherwise, such a redirect may be considered a soft 404, and you will lose the rank of that page.
2. Get Mobile Page-Specific Redirects Right
If you have different URLs for desktop and mobile websites (i.e., “example.com” for desktop and “m.example.com” for mobile), you should make sure to redirect users to the appropriate page of the mobile version.
Correct: “example.com/sport/” to “m.example.com/sport/”
Wrong: “example.com/sport/” to “m.example.com”
Also, you have to ensure that if one page is 404 on the desktop, it should also be 404 on mobile.
If you have no mobile version for a page, you can avoid redirecting to the mobile version and keep them on the desktop page.
3. How To Use Meta Refresh
It is possible to do a redirect using a meta refresh tag like the example below:
<meta http-equiv=”refresh” content=”0;url=http://example.com/new-page/” />
If you insert this tag in /old-page/, it will redirect the user immediately to /new-page/.
Google does not prohibit this redirect, but it doesn’t recommend using it.
A meta refresh type redirect should just work. We don’t recommend it for 2 reasons: UX (it keeps the page in browser history, afaik) & processing time (we need to parse the page to see it). Once processed, it’s just like a redirect.
— 🍌 John 🍌 (@JohnMu) March 2, 2018
4. Avoid Redirect Chains
This message displays when you have a wrong regular expression setup and ends up in an infinite loop.
Usually, this happens when you have a redirect chain.
Let’s say you redirected page 1 to page 2 a long time ago. You might have forgotten that page 1 is redirected and decided to redirect page 2 to page 1 again.
As a result, you will end up with a rule like this:
RewriteRule ^page1 /page2 [R=301,NC,L] RewriteRule ^page2 /page1 [R=301,NC,L]
This will create an infinite loop and produce the error shown above.
Knowing what redirects are and which situation requires a specific status code is fundamental to optimizing webpages properly. It’s a core part of understanding SEO.
Many situations require precise knowledge of redirects, such as migrating a website to a new domain or creating a temporary holding page URL for a webpage that will return under its normal URL.
While so much is possible with a plugin, plugins can be misused without properly understanding when and why to use a particular kind of redirect.