Website redirects tell browsers and search engines information about a URL and where to find the webpage.
It’s essential to use redirects correctly because they impact how websites are crawled and indexed by Google.
While most people think of redirects as an internet detour sign, there is much more going on, and it’s surprisingly enjoyable to discover.
HTTP Response Status Codes
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.
The Meaning Of A Redirect
When we talk about a redirect, what we’re talking about is a server response. It’s a response to a request for 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 redirect. 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 redirect 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.
302: Found
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 is required to 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.
For instance:
- Servers status code of redirect: “301″ vs. “permanent.”
- Action command: “RedirectMatch” vs. “rewrite”.
But the syntax of the redirect ( ^/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
Read the official documentation to learn more about the RewriteEngine.
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 |
Redirect A Single URL
The most common and widely used type of redirect is when deleting pages or changing URLs.
For instance, say you changed URL from /old-page/ to /new-page/. The redirect rule would be:
RewriteRule ^old-page(/?|/.*)$ /new-page/ [R=301,L]
Or
RedirectMatch 301 ^/old-page(/?|/.*)$ /new-page/
The only difference between the two methods is that the first one uses the Apache mod_rewrite module, and the second one 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:
/old-page/ | /new-page/ |
/old-page | /new-page/ |
/old-page/?utm_source=facebook.com | /new-page/?utm_source=facebook.com |
/old-page/child-page/ | /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 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]
Here, we want to redirect all under /category/ on the third line except if it is /category/final-subcategory/ on the fourth line. We also have the “!-f” rule on the second line, ignoring any file like images, CSS, or JavaScript files.
Otherwise, if we have some assets like “/category/image.jpg,” it will also be redirected to “/final-subcategory/” and cause an image break.
Directory Change
If you did a category restructuring and want to move everything from the old directory to the new one, you can use the rule below.
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]
Canonicalization
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 /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.
From the existing ones, I would recommend a free plugin called Redirection, which has many parameters to control redirect rules and many useful docs.
Redirect Bad Practices
1. Redirecting All 404 Broken URLs To The Homepage
This case often happens when you are lazy to investigate all of 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. Wrong Mobile Page-Specific Redirects
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 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. Using 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
According to John Mueller, search engines may not be able to recognize that type of redirect properly. The same is also true about JavaScript redirects.
4. Too Many Redirects
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.
Conclusion
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.
Featured Image: Paulo Bobita/Search Engine Journal
window.addEventListener( ‘load’, function() {
setTimeout(function(){ striggerEvent( ‘load2’ ); }, 2000);
});
window.addEventListener( ‘load2’, function() {
if( sopp != ‘yes’ && addtl_consent != ‘1~’ && !ss_u ){
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version=’2.0′;
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window,document,’script’,
‘https://connect.facebook.net/en_US/fbevents.js’);
if( typeof sopp !== “undefined” && sopp === ‘yes’ ){
fbq(‘dataProcessingOptions’, [‘LDU’], 1, 1000);
}else{
fbq(‘dataProcessingOptions’, []);
}
fbq(‘init’, ‘1321385257908563’);
fbq(‘track’, ‘PageView’);
fbq(‘trackSingle’, ‘1321385257908563’, ‘ViewContent’, {
content_name: ‘redirects-technical-guide’,
content_category: ‘technical-seo’
});
}
});