A permanent 301 redirect informs search engines and browsers (Firefox, Google Chrome, Microsoft Internet Explorer etc…) a webpage has permanently moved to a new location. A visitor to a website visiting via a link that’s been 301 redirected will click a link with one URL, but load another URL.
For example I moved some articles from another website to here, if a visitor found a link to
https://stallion-theme.co.uk/seo-tutorial/ (old location)
It automatically 301 redirects to
https://seo-gold.com/seo-tutorial/ (new location)
in a browser since there’s a 301 redirect on the old site (added to the .htaccess file) to here.
Highlighted in blue is a simple 301 redirect added to the top of a default WordPress .htaccess file.
Search engines like Google will pass any SEO benefit (PageRank for example) and traffic from the old URL to the new URL.
When Googlebot (Google search engine spider) has spidered the old URL it will stop indexing the old URL and only index the new one (give it a few weeks, don’t expect the change to be overnight): this means current Google SERPs for the old page will be associated with the new page.
SEO note: there’s a small dampening factor on the PageRank passed via 301 redirects, based on the original PageRank formula assume it’s around 15%. ~15% of your old pages PageRank will be lost because of the 301 redirect, this could have a negative impact on the SERPs the old page used to have. See the Matt Cutts video below for confirmation
What percentage of PageRank is lost through a 301 redirect?
https://www.youtube.com/watch?v=Filv4pP-1nw
WordPress 301 Redirects
WordPress includes some 301 redirect capabilities built in, for example when a site uses SEO Friendly Permalinks the dynamic version of a URL is automatically 301 redirected to the SEO friendly version.
For example this article can be accessed via it’s SEO unfriendly dynamic URL here : WordPress Automatic Permalinks 301 Redirects.
Hoverover the link above and you can see the URL is: https://seo-gold.com/?p=3955 now click the link and it reloads the webpage you are on now. That’s a built in WordPress 301 redirect in action.
The above is built into WordPress since version 3.3, so no need to worry about 301 redirects when changing WordPress permalinks from the default ?p=123 to the SEO recommended /%postname%/ on a new or even an old site that’s used the default Permalinks setting for years, WordPress 301 redirects automatically: don’t forget on an old site about the ~15% 301 redirect dampening factor.
Changing WordPress Permalinks 301 Redirects
WordPress does NOT handle automatic 301 redirects if you change permalinks from a non-default structure to another.
For example if your website is currently running with the
“Month and Name” option set – outputs URLs like: https://seo-gold.com/2020/12/sample-post/
and want to change to the SEO recommended permalinks structure
“Post Name” option set – outputs URLs like: https://seo-gold.com/sample-post/
The old URLs will NOT automatically 301 redirect to the new, to make this change you’ll either have to manually setup 301 redirects via your .htaccess file or install a 301 Redirect WordPress Plugin. I’ve used both options, really depends on the site and number of posts that require 301 redirects.
WordPress 301 Redirect .htaccess
Unless you are running a WordPress plugin or other way to edit your root .htaccess file, use an FTP program (Filezilla for example) to download your .htaccess file (the .htaccess file is normally where the wp-config.php file is).
Load the .htaccess file in a text editor (Notepad for example) and if you setup SEO Friendly Permalinks as described in an earlier WordPress SEO tutorial it should include this code: this deals with the SEO friendly permalinks:
# BEGIN WordPress
<ifmodule mod_rewrite.c="">
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</ifmodule>
# END WordPress
If you use a WordPress caching plugin like WP Super Cache or W3 Total Cache you’ll find a lot more rules in your .htaccess file.
If you are having problems creating the WordPress .htaccess file, Download the Default WordPress .htaccess File. This is only suitable for standard WordPress installs, it’s not suitable for multi-site WordPress installations.
Simple WordPress 301 Redirect Rule
All the .htaccess rules mentioned later should be added ABOVE the WordPress permalink rules and anything added by caching plugins like so (the top two lines are 2 simple 301 redirects):
RewriteEngine On
Redirect 301 /old-page.htm https://seo-gold.com/new-page/
Redirect 301 /another-old-page.htm https://seo-gold.com/new-page-2/
# BEGIN WordPress
<ifmodule mod_rewrite.c="">
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</ifmodule>
# END WordPress
After adding your 301 redirect rules upload the .htaccess file to the root of your site using an FTP program.
.htaccess Simple 301 Redirect
Below is a simple 301 redirect that would be added to the .htaccess file found in the root of your site.
RewriteEngine On
Redirect 301 /old-page.htm https://seo-gold.com/new-page/
“RewriteEngine On” probably won’t be needed, it’s already been added by WordPress when you turn SEO friendly permalinks on (see earlier). For non WordPress users the above is all you need within your .htaccess file to redirect one page to another.
If I added the above rule to this sites .htaccess file it would redirect
https://seo-gold.com/old-page.htm to https://seo-gold.com/new-page/
If I added the rule to another site for example https://example.com/ it would redirect
https://example.com/old-page.htm to https://seo-gold.com/new-page/
This 301 redirect rule type can be used to redirect entire sites one page at a time, this is not the easiest way to redirect a site you’ve moved, but it’s possible:
RewriteEngine On
Redirect 301 / https://seo-gold.com/
Redirect 301 /page-1/ https://seo-gold.com/page-1/
Redirect 301 /page-2/ https://seo-gold.com/page-2/
Redirect 301 /page-3/ https://seo-gold.com/page-3/
This would redirect the home page / of the old site to the home page / of the new domain, page-1 on the old site to page-1 on the new domain etc…
This is not the easiest way to achieve this (see next .htaccess 301 redirect rules for the easy way), but it can be useful if you split an old site over multiple domains for example where wildcard rules just won’t work or you’ve changed the URL structure.
Moving a WordPress Blog with NON-WWW to WWW Support 301 Redirect Rules
Moving a WordPress blog from one domain to another when you keep the same WordPress permalinks settings is easy, after moving domains add a .htaccess file that contains the following rules:
RewriteCond %{HTTP_HOST} ^old-domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.old-domain.com$ [NC]
RewriteRule ^(.*)$ https://www.new-domain.com/$1 [L,R=301]
The rules above 301 redirects everything under old-domain.com and www.old-domain.com to www.new-domain.com keeping the original filenames (based on the permalinks settings).
For example the URLs old-domain.com/page-1/ and www.old-domain.com/page-1/ will both 301 redirect to www.new-domain.com/page-1/ on the new domain.
Another alternative is:
RewriteRule (.*) https://www.new-domain.com/$1 [R=301,L]
Moving a WordPress Blog with WWW to NON-WWW Support 301 Redirect Rules
As above, except redirecting to the non-www version of the new domain:
RewriteCond %{HTTP_HOST} ^old-domain.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.old-domain.com$ [NC]
RewriteRule ^(.*)$ https://new-domain.com/$1 [L,R=301]
For example the URLs old-domain.com/page-1/ and www.old-domain.com/page-1/ will both 301 redirect to new-domain.com/page-1/ on the new domain.
Another alternative is:
RewriteRule (.*) https://new-domain.com/$1 [R=301,L]
WordPress SEO Tip: When moving domains don’t forget to set the preferred domain (www or non-www) under Google Search Console, so Google knows which www or non-www should be indexed and ranked.
And since it’s 2020 and a secure site is important, consider updating from http (unsecure) to https (secure) access to your website. Used to be case SSL certificates where expensive, but there are free services like Letsencrypt which offer free SSL certificates: this website runs under a free Letsencrypt SSL certificate.
If you do update from http to https don’t forget any old 301 redirect rules within your .htaccess file will need upgrading from http to https. Otherwise there will be a double redirect which is inefficient. It’s an easy update, simply change the http URLs to https URLs.
Stallion Responsive SEO Super Comments URLs 301 Redirect Rules
I moved half a dozen posts with over 100 comments between them from one site to another (to this site, it’s some of the WordPress SEO Tutorials: decided to bring all my WordPress SEO Tutorial articles under one domain) and because I use the Stallion Responsive Theme SEO Super Comments feature I had to take into account the comments that were indexed in their own right: although there’s only half a dozen articles, the 100 or so comments meant I had to deal with dozens of URLs with query strings (?cid=123) that needed 301 redirects.
Easiest way to deal with this was a small set of custom 301 redirect rules added to the .htaccess file of the site I was moving the articles from. I’ve pasted one of the custom rules below (there’s a set like this for each article moved):
RewriteCond %{QUERY_STRING} ^cid=([0-9]*)$
RewriteRule ^seo-tutorial-for-wordpress https://seo-gold.com/seo-tutorial-for-wordpress/? [R=301,L]
RewriteRule ^seo-tutorial-for-wordpress(.*)$ https://seo-gold.com/seo-tutorial-for-wordpress/ [R=301,L]
No way I could generate this rule via a WordPress 301 Redirect Plugin, it’s too specific to that sites needs.
What it does is look for URLs with a query string ?cid=123: this is what you find on the end of Stallion SEO Super Comment URLs. Looks for URLs including seo-tutorial-for-wordpress (which is the WordPress slug of an article I moved) and 301 redirects it to https://seo-gold.com/seo-tutorial-for-wordpress/: where I moved the WordPress SEO Tutorial article to.
Since the cid=number is the comment ID and when moving comments from one site to another WordPress doesn’t maintain the original comment ID (comments get a new comment ID) the above 301 redirects all URLs with format seo-tutorial-for-wordpress?cid=123 from the old site to https://seo-gold.com/seo-tutorial-for-wordpress/ on the new site.
I’ve used an even more complex set of 301 redirect rules where after moving WordPress Posts including comments, the comment IDs on the two sites didn’t match up, but I wanted the SEO Super Comments to pass ranking benefit.
RewriteCond %{QUERY_STRING} ^cid=25703$
RewriteRule ^seo-meta-tags/$ https://seo-gold.com/seo-meta-tags/?cid=275 [R=301,L]
RewriteCond %{QUERY_STRING} ^cid=25716$
RewriteRule ^seo-meta-tags/$ https://seo-gold.com/seo-meta-tags/?cid=276 [R=301,L]
RewriteRule ^seo-meta-tags/google-meta-description-tag/ https://seo-gold.com/seo-meta-tags/does-google-use-meta-keywords/? [R=301,L]
RewriteRule ^seo-meta-tags/meta-description-tag/ https://seo-gold.com/seo-meta-tags/meta-description-tag-has-no-direct-seo-value/? [R=301,L]
RewriteRule ^seo-meta-tags/html-meta-tags/ https://seo-gold.com/seo-meta-tags/html-meta-tags/? [R=301,L]
RewriteRule ^seo-meta-tags/(.*)$ https://seo-gold.com/seo-meta-tags/ [R=301,L]
The first line RewriteCond %{QUERY_STRING} ^cid=25703$ looks for a specific rewrite condition which will be used by line two. The condition is find cid=25703 which is a specific SEO Super Comment URL.
The left side of the second line RewriteRule ^seo-meta-tags/$ https://seo-gold.com/seo-meta-tags/?cid=275 [R=301,L] says find the rewrite condition from line one associated with seo-meta-tags/, so specifically looking for a URL including seo-meta-tags/?cid=25703. The right sie of the second line is where the URL should be redirected to, this URL https://seo-gold.com/seo-meta-tags/?cid=275
Lines three and four are for another comment.
Lines 5, 6 and 7 are related to WordPress Attachment Pages. Line five RewriteRule ^seo-meta-tags/google-meta-description-tag/ https://seo-gold.com/seo-meta-tags/does-google-use-meta-keywords/? [R=301,L] is looking for the URL seo-meta-tags/google-meta-description-tag/ and is 301 redirecting it to https://seo-gold.com/seo-meta-tags/does-google-use-meta-keywords/
The final line RewriteRule ^seo-meta-tags/(.*)$ https://seo-gold.com/seo-meta-tags/ [R=301,L] is a catchall for anything else left related to the WordPress Post with URL seo-meta-tags/. The (.*) is wildcard, it means find anything. So this means find seo-meta-tags/ANYTHINGHERE and 301 redirect it to https://seo-gold.com/seo-meta-tags/ where ANYTHINGHERE is dropped. This format could be used to 301 redirect thousands of webpages or just one to a single URL.
Most WordPress users will never need a 301 redirect .htaccess rule like the ones above, but it shows what you can achieve with the right 301 redirect rules.
David Law
Hi! Please help me out! I feel I’m going crazy…
I a have site built on a wordpress platform. The thing is neither 301 redirects nor canonical rel are working for redirecting from non www to www, although when I first put the site online it used to work. I’ve tried leaving just the 301 and then just the canonical thinking that they can come in conflict. I’ve tried all the code versions for .htaccess I could find including yours. I’ve also tried registering the non www to google webmasters but no matter which way I try it fails (when I verify them with www they are all ok). Non www just doesn’t work. I get the following message:
“This IP address is shared. For access to the web site which you look for, enter its address instead of its IP.
For questions or problems please contact the server administrator.”
The only change I can think of doing is updating my sitemap in google webmasters because there were a few changes but I don’t see how that can influence anything. Here’s a copy of my .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.example.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Please help me out! Thanks!
I use WordPress on around 70 domains and it works fine on my sites.
Your code looks fine, most of my WordPress sites .htaccess file looks like this:
RewriteCond %{HTTP_HOST} !^www.example.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Which is basically the same as yours.
If you load http://example.com it immediately redirects to https://www.example.com.
This assumes you are on a Linux server.
David Law
Thanks for the fast reply David! I got to the bottom of it eventually. It was actually a hosting provider configuration problem.
They hadn’t added a ServerAlias in the NameVirtualHost directive. Thanks again!
I’m using the EXACT same code as the word press example above, and all I ever get is an endless loop detected in the browser (any browser). Any suggestions?
file:
#non-www to www start
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.example.com$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
#non-www to www end
# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Hi David,
how do you hide your plugins?
Thanks
Héctor
Hiding a directory is a server side setting.
Assuming you run on an Apache server it’s having something like:
Options -Indexes +IncludesNOEXEC +SymLinksIfOwnerMatch
Into your httpd.conf file for each domain on a server, this would make no directories that lack an index.html, index.php etc… show what’s in them.
If you know how to edit the httpd.conf file you’ll be looking for instances of something like this to change:
Options Indexes IncludesNOEXEC +SymLinksIfOwnerMatch
Another way is create an index.php file and add this to it:
<?php
// Silence is golden.
?>
Upload this to any folder you want ‘hidden’, first check there isn’t a index.php file in the directory.
Users now get a blank webpage where ever you upload index.php to. I use this file in Stallion Responsive, load any of the Stallion Responsive folders in a browser like : https://stallion-theme.co.uk/wp-content/themes/stallion-responsive/widgets/
And it’s a white page, simple and effective, stops your visitors snooping inside your themes files and stops Google inadvertently easily spidering and indexing anything in the Stallion Responsive directories that shouldn’t be indexed. I don’t understand why WordPress by default doesn’t do this, doesn’t make any sense to allow users and search engines to see what’s inside /wp-includes/!
I’m not sure if every time you auto update WordPress /wp-admin/ and /wp-includes/ are deleted, if so if you want these hidden you’d have to upload the .htaccess file or the index.php file again after each update.
Best solution is the server side one, but can be beyond a lot of webmasters to edit the httpd.conf file. You might have a setting under your control panel, I use the control panel Virtualmin and I couldn’t find an option so added the code manually which on my servers is under “/etc/httpd/conf/httpd.conf“.
David
Hi David,
I use bluehost, it shows this way on my FTP session
public_html/vivirencanada/wp-content/plugins
I tried adding this .htaccess inside of plugins, but it didn’t work
# BEGIN WordPress
RewriteEngine On
RewriteRule ^(.*)$ /public_html/vivirencanada/index.php
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
I wonder if it’s because already exists a index.php within the directory?
Regards,
Héctor
Hmm, after rereading what I suggested the .htaccess option isn’t suitable for all directories like /wp-content/plugins/ it would 301 redirect everything under the folder to home rather than just stop users seeing the contents!
I’ve deleted that part of my earlier comment and pasted below with a better modification to explain what it actually does.
How to 301 redirect an entire directory to home.
You have two directories you no longer use and want to 301 redirect everything that used to be in them to home, this could be thousands of images or webpages.
/wp-content/hidden/
and
/oldstuff/
Add this to your root .htaccess file
Note if “RewriteEngine On” is already within the file it’s not needed again.
RewriteEngine On
RewriteRule ^wp-content/hidden/(.*)$ https://seo-gold.com/ [R=301,L]
RewriteRule ^oldstuff/(.*)$ https://seo-gold.com/ [R=301,L]
This would 301 redirect everything under the folders “/wp-content/hidden/” and “/oldstuff/” to my home page.
This can be useful where you’ve deleted hundreds of tags, tags are rubbish SEO wise and should be avoided, if you deleted all your sites tags you could build a set of 301 redirects to conserve the link benefit.
You’ve delete all tags and want them all 301 redirecting:
RewriteEngine On
RewriteRule ^tag/(.*)$ https://seo-gold.com/ [R=301,L]
You’ve deleted some tags called tag 1, tag 2 and tag 3, but kept tag 5 and tag 5
RewriteEngine On
RewriteRule ^tag/tag-1/(.*)$ https://seo-gold.com/ [R=301,L]
RewriteRule ^tag/tag-2/(.*)$ https://seo-gold.com/ [R=301,L]
RewriteRule ^tag/tag-3/(.*)$ https://seo-gold.com/ [R=301,L]
Tag 1 to 3 will 301, the rest won’t be.
Best to try to find a page that’s similar to redirect to rather than just back to home
RewriteEngine On
RewriteRule ^tag/tag-1/(.*)$ https://seo-gold.com/ [R=301,L]
RewriteRule ^tag/tag-2/(.*)$ https://seo-gold.com/post-about-tag-2/ [R=301,L]
RewriteRule ^tag/tag-3/(.*)$ https://seo-gold.com/responsive/category-3/ [R=301,L]
Above I don’t have a relevant page to tag-1 so 301 to home, but do to tag-2 have a post about tag 2 and have a category similar to tag 3.
I have sites with dozens of 301 redirect rule sets like these.
David