I’m happy to say that after a lot of research, trial and error, and pulling out of my hair, I found some good mod_rewrite (.htaccess) examples that work well. I created this page so I can refer to them when I need them, so I’m using them myself and this page is updated from time to time.
Here goes, but first some prerequisites / important notes:
- Your Apache server needs mod_rewrite enabled – most of them do. Check with your host or server admin.
- My examples here are in .htaccess files. What’s in the type code below is all you need in that file – unless you already have something in that file, then you might want to keep that stuff there – up to you.
- Since https is the preferred method now (SSL), all of these examples use that protocol (versus just http).
- I got these examples from the sources mentioned below and some I’ve created or modified.
- Of course, replace things like “yourdomain.com”, “yourolddomain.com”, and “yournewdomain.com” with your actual domain name.
- I like to make it a habit of going to a website in my browser and then I copy the full URL or domain from there instead of just typing it in. I do this to make sure the URLs I use are accurate because typos can be a pain in the butt to debug. Just take that out of the equation and copy and paste as much as possible when doing this.
Force the WWW Version of a Domain Name
Require the “www” in a domain (you want to do this so that Google or other search engines don’t think there are 2 versions of your site out there – the www version (like “www.yourdomain.com”) and the non-www version. This is done for SEO reasons:
RewriteEngine On RewriteCond %{HTTP_HOST} !^www..* RewriteCond %{HTTP_HOST} !^$ RewriteCond %{HTTP_HOST} ^([^.]*).(com|com/) RewriteRule ^.*$ https://www.%1.%2%{REQUEST_URI} [R=301,L]
Force the non-WWW Version of a Domain Name
This one is useful since some websites want to have a shorter URL (better for SEO). This will redirect the www subdomain to domain root (non-www). This is for when you want the non-www version of their domain to be the main domain name. People might try going to the www version, so this code redirects them to the non-www version.
Note: Adding “www.” to the front of a domain name actually makes it a sub-domain of the main domain name – just like if you had something like blog.yourdomain.com.
RewriteCond %{HTTPS} on RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
I find this code useful when trying to verify an SSL certificate (via the .well-known method). GoDaddy says that they check for both the www and non-www version but no, they just check for the non-www version and when your website is forcing www, this can be a problem – your site switches to the www version and you can’t get it verified.
In that case, put this code in a separate .htaccess file in the /.well-known/pki-validation folder and it should then verify just fine. If it doesn’t, then you have some server settings that are forcing a certain version of the domain name.
Learn more about how to install an SSL certificate on a WordPress website.
Force HTTPS Using .htaccess
Use this code in your .htaccess file to force every page on your website to use SSL (HTTPS). This is good for SEO and it’s how Google wants every website to load now.
RewriteEngine On RewriteCond %{HTTPS} !=on RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
This code also works but you need to put your domain name in the third line (in place of “www.yourdomain.com” – I prefer what’s above, actually):
RewriteEngine On RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R=301,L]
Force HTTPS for WordPress Multi-Site – Per Domain
Use this code for forcing HTTPS (SSL) on multi-site setups where you’re using multiple domain names. This is used if you only want SSL on some of those websites – versus all of them (but since HTTPS is good for all sites, I don’t know why you’d need this anymore but here goes):
RewriteCond %{HTTP_HOST} ^www\.yourdomain\.com RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R=301,L]
And then this code goes into the wp-conf.php file:
if ( $_SERVER["HTTP_HOST"] == "yourdomain.com" ) { define('FORCE_SSL_ADMIN', true); define('FORCE_SSL_LOGIN', true); }
No Image Linking Using .htaccess
Another good one is how to make sure other sites don’t link to your images from their site (I’ve had reports of this not working perfectly):
RewriteEngine On RewriteBase / RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^https://(www.)?yourdomain.com/.*$ [NC] RewriteRule .(gif|jpg|swf|flv|png)$ /feed/ [R=302,L]
You need to hard-code your domain name into this one. This .htaccess file may need to be in your images directory to work. I’ve used a 302 (temporary) code above instead of a 301 (permanent).
Redirect One Domain Name to Another Domain
And here’s one I’m adding since it’s so useful… redirecting everything from an old domain to a new domain (not just the home page) so that you don’t lose traffic from bookmarks, links and search engine results. This one’s important to have on hand. You’ll use this if you change domain names or more content from an old domain name to a new one.
RewriteEngine on RewriteRule ^(.*)$ https://www.yournewdomain.com/$1 [R=301,L]
Just put that in your .htaccess file (or create one if you need to) and I suggest right at the top of the file to speed things up and everything coming to the domain name the .htaccess file sits on will be directed to the website (URL) you list above.
The example shown below is for both the www version of your domain and the non-www version of your domain.
Options +FollowSymLinks RewriteEngine On RewriteBase / RewriteCond %{HTTP_HOST} ^www.yourolddomain.com [nc] RewriteRule (.*) https://www.yournewdomain.com/ [R=301,L] RewriteCond %{HTTP_HOST} ^yourolddomain.com [nc] RewriteRule (.*) https://www.yournewdomain.com/ [R=301,L]
Redirect All Pages to a New Domain (Catch-All)
Here’s one I call a “catch all” where it redirects all pages from an old domain to a new domain (single page).
This is very powerful. Most people just redirect the home page but no, that’s just a tiny portion of the value of a domain. Instead, redirect ALL pages to a domain.
Options +FollowSymLinks RewriteEngine On RewriteBase / RewriteCond %{HTTP_HOST} ^yourolddomain\.com$ [NC] RewriteRule ^(.*)$ https://yournewdomain.com [R=301,L]
And here it is with the “www” subdomain included:
Options +FollowSymLinks RewriteEngine On RewriteBase / RewriteCond %{HTTP_HOST} ^www\.yourolddomain\.com$ [NC] RewriteRule ^(.*)$ https://www.yournewdomain.com [R=301,L]
WordPress: Don’t Show “index.php” in the URL
This is a .htaccess rule to use to make sure that “index.php” doesn’t show up in URLs (for SEO reasons). You want to do this so that you have just one URL pointing to a page instead of two URLs (one with index.php and one without) so that your website doesn’t have 2 pages with the same content. You may get a duplicate content penalty by Google if you don’t do this.
Here’s that one:
Options +FollowSymLinks DirectoryIndex index.php RewriteEngine On RewriteBase / RewriteCond %{THE_REQUEST} ^[A-Z]{3,9} /index.php HTTP/ RewriteRule ^index.php$ https://www.yourdomain.com/ [R=301,L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]
Redirect 404 Pages to the Home Page
This one is useful for SEO purposes – I found it when searching for “htaccess 404 redirect to homepage” and it works great.
This is another, great redirect with high value. You can redirect all 404 pages to your home page and it’s a 301 redirect, which passes on the link juice. Doing this can often result in a big boost in rankings if your webmaster has been a little careless or if you bought a domain just for the link juice and you want to pass all the juice on – not just the home page. Or you could say you’re passing on all the URL authority instead of just the domain authority. (Source)
ErrorDocument 404 https://www.yourdomain.com/
And then if you’re using WordPress and want to redirect all 404 pages to the home page, the code above might not work since WordPress might use a 404 page already in your theme.
In that case, open up the 404.php file in your theme and use this code instead of what’s there now (create a child theme to prevent this being overwritten).
<?php header("HTTP/1.1 301 Moved Permanently"); header("Location: ".get_bloginfo('url')); exit(); ?>
Redirect Off-Site Image References to a Different Image
Ha! I like this one. In fact, I just saw some guys charging like $10 for a plugin that does what this code does.
You can use it to block people from linking to images on your website but if they do, you can instead show an image that says your website name on it and encourage people to go to your website – giving you some extra website traffic… nice!
RewriteEngine On RewriteCond %{HTTP_REFERER} !^https://(.+\.)?yourdomain\.com/ [NC] RewriteCond %{HTTP_REFERER} !^$ RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/some-image-name.jpg [L]
More Resources
And there’s even more here (some of my sources and good resources for htaccess stuff):
- htaccess Cheat Sheet
- Stupid htaccess tricks (VERY good resource)
- .htaccess Tutorials, htaccess Examples, Sample .htaccess Files
- Redirecting WordPress index.php to root
- WordPress Htaccess Tips And Tricks (elegantthemes.com)
- Ultimate .htaccess Guide (whoishostingthis.com)
- RewriteRule Flags
Great to see you’re cleaning up the Rewrite Rules. I have a bunch of reeirdcts on my site (having moved or removed various things), but WordPress keeps eating the things I add to the .htaccess. One possibility is to deny it access through CHMOD, and just update it myself, but this is work I’d really rather avoid.The question: does WordPress simply generate a new .htaccess when it changes a rule, and copy it over the old one? Is there some way to add stuff to the .htaccess file that WordPress won’t remove? One possibility, I suppose, would be to have a custom .htaccess rules section on the Dashboard; are there any plugins to help with this?
I believe WordPress appends onto .htaccess files and doesn’t write them from scratch – unless it doesn’t exist… in that case, it would create one.
I had an interesting thing happen today. We have a client that pointed their domain to our server and the IP address would come up instead of the domain name.
I checked all the server settings on our side and everything looked fine. I thought it was the .htaccess file but that wasn’t it. I then did a “wget” command on my Mac (in Terminal) and saw that our client redirected the domain name to the IP address. So they did a forward to an IP instead of changing the IP address in their DNS. Problem solved but it had me wondering what was going on for a few minutes.