.htaccess URL Rewrite Simplified

URL rewrite

Summary: If you are hosting your websites on Apache servers, it is just a matter of time you will get in touch will .htaccess and URL Rewrite rules and the fearful 500 Server Error code. This article will try to ease your headache by explaining these in simple terms.

Locate and back up .htaccess file

You may access the .htaccess file on your web root (the directory where your home page is located) using your c-panel (if your website is hosted by a hosting company).

Or, if you prefer to use a FTP/SFTP client, you will need to turn on the option “show hidden files”. Since .htaccess file is such a powerful tool that can make changes to your server configurations, it is hidden by default to avoid accidental changes.

If you cannot find the .htaccess file, try to create one yourself. The filename should  begin with a dot (.).

However, not all servers are created equal. In case you cannot successfully locate the .htaccess file, ask your technical colleagues or hosting company for support. Make sure your server allows mod_rewrite.

The fearful 500 Server Error

Stay calm and keep on. Just open your .htaccess and comment the newly added rule out by adding a # in front of the rule and your website will work again.

#RewriteEngine on
#RewriteRule URL1 /URL2 [R=301,L]

For most of time, this happens because you have added several rules which may be conflicting or may loop infinitely. The flag L just stops matching the rules below. But for each redirect, the new URL2 is to be processed by the rewrite rules from the beginning again, and this is where things will run into trouble.

Case 1: A web page has been moved permanently

The simplest form of URL rewrite is to redirect a visitor from an old URL1 (the URL the visitor enters on the address bar of the browser) to a new URL2 (the URL we want them to go):

RewriteEngine on
RewriteRule URL1 /URL2 [R=301,L]

The R=301 in the brackets  (called a flag) adds the HTTP response code 301, which means the page is moved permanently. This is very important for SEO. In case you just want to show the contents from another file without changing the old URL, then you should not add R=301 flag.

The code L (Last) asks the server to ignore the rewrite rules to follow if this one matches.

There are way more flags but these two are the most commonly used. Also, note that the root level / is not needed in URL1 but is required in URL2

Case 2: A group of web pages have been moved permanently

In this case, you can hard code the redirect rules one by one or use patterns (called a Perl Compatible Regular Expression (PCRE) / regex / regexp).

As an example, you have moved your files from a directory named oldDirectory to a newDirectory.

RewriteEngine on
RewriteRule ^oldDirectory/([a-zA-Z0-9-_.]+)$ /newDirectory/$1 [R=301,L]

The language of Regex

Firstly, you will need to learn a bit symbols:

The language of Regex
^Matches the beginning of a string^index (the URL should begin with index)
$Matches the end of a stringphp$ (the URL should end with php)
\Escape a symbol \.php$ (the URL should end with .php)
[0-9]Matches a number^index[0-9] (the URL should begin with index0, index1, … index9)
[A-Za-z]Matches a letter A-Z irrespective of the case[A-Za-z] (the letter C would match this pattern)
{0,4}Matches the previous group 0 – 4 times[A-Za-z]{0,4} (the word CarD would match this pattern)
?Matches the previous group 0 – 1 times[A-Za-z]? (the word E would match this pattern)
+Matches the previous group 1 or more times[A-Za-z]+ (the word CarD would match this pattern)
()Back references (extracting parts of the old URL to be used for the new URL)[see Pretty URLs section below]

Case 3: Pretty URLs (to convert URL Get parameters into directories)

This is useful for visitors to remember your URL as well as technical SEO. Many CMS like WordPress will automatically do this for you. If you write your own PHP pages, you can create pretty URLs with the following:

RewriteEngine on
# check that the request url is neither a file nor a directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?section=$1&title=$2 [NC,L]

In this case, if the URL is /about/edward/ or /about/edward the content of /index.php?section=about&title=edward will be shown. The infamous “.php?” is now got rid of. We need to check for whether the original URL actually points to an existent file or directory before performing the redirection.

In case you would like to hide the “ugly” URLs for good (i.e. even when people type in /index.php?section=about&title=edward, the pretty URL /about/edward/ will always be shown), you will need the following piece of code instead

RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+index\.php\?section=([a-z0-9]+)&title=([a-z0-9]+) [NC]
RewriteRule ^ %1/%2/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?section=$1&title=$2 [L,NC]

Note that the order and spacing of the code is very important. The flag R=301 will change the URL in the address bar to the pretty URL for you.

Case 4: Ignore a directory

There are cases you just would not need redirect on certain directories, e.g. images, you can use hyphen (-) to indicate this:

RewriteEngine on
RewriteRule ^images/ - [L]
RewriteRule ^([a-z0-9]+)/([a-z0-9]+)/?$ /index.php?section=$1&title=$2 [NC,L]

Case 5: Redirect to readthis.php if the request is not a file/directory

Although the web server will server a 404 page automatically in this case. Sometimes you may want to collect all ‘page not found’ requests and redirect to a specific page to give more related information to the visitors:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f // not a file
RewriteCond %{REQUEST_FILENAME} !-d // not a directory
RewriteRule ^([a-z0-9]+)/([a-z0-9]+)/?$ /readthis.php?section=$1&title=$2 [NC,L] 

Case 6: Use no www domain for SEO

If both the www.domain.com and domain.com points to the same content, some search engines may mistakenly make penalty for “duplicated” contents and demote your ranking. An easy way to avoid this is to designate a version of the domain as default and redirect the rest to this version. Assuming the no www domain is the preferred version:

RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
RewriteRule ^(.*)$ http://domain.com/$1 [R=301,L]

If the with www domain is your choice:

RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]

Further Help

Support website running for FREE, thanks!

If you find this post helpful and if you are thinking of buying from Amazon, please support the running cost of this website at no extra cost to you by searching and buying through the search box below. Thank you very much for your help!

Edward Chung

Edward Chung aspires to become a full-stack web developer and project manager. In the quest to become a more competent professional, Edward studied for and passed the PMP Certification, ITIL v3 Foundation Certification, PMI-ACP Certification and Zend PHP Certification. Edward shares his certification experience and resources here in the hope of helping others who are pursuing these certification exams to achieve exam success.

You may also like...

Leave a Reply

Your email address will not be published.

10 Responses

  1. Hello, how can I redirect like this having two pages example.com/abc.html and example.com/xyz.html how to redirect the first page as example.com/abc/ and the second page as example.com/abc/xyz/

    I have search a lot of websites but not found a solution yet.

  2. Nelson says:

    How to move to .htaccess?

  3. Nik says:

    I think this should work:

    Step – 1: Rewrite:

    RewriteRule abc1.htm abc.htm

    Step -2 : Redirect

    redirect 301 /abc.htm http://www.mysite.com/abc1.htm

    Let me know your thoughts.

  4. Nik says:

    Hi Edward, Thank you very much for the reply. And sorry if I’d created any confusion.

    Actually I want to display the new url i.e. (abc1.htm) similar to my old url i.e. (abc.htm). Because abc.htm has a very good PR (4). So to preserve the page rank, the REWRITE+REDIRECT (old to new) will be:

    Rewrite abc1.htm /abc.htm [R=301,L]

    Am I right?

    Since the design of new page (abc1.htm) is good, I want to preserve the URL naming structure along with the page rank as well.

  5. Nik says:

    Hi, I have two pages old (abc.htm) and new (abc1.htm) (content is nearly the same on both the page only design is different). I want to rewrite abc1.htm to abc.htm i.e. whenever someone clicks on the link abc1.htm, browser should display abc.htm. I’ll then redirect the old abc.htm to the new rewritten abc.htm. How can I do this i.e. rewriting? Will this code work for both rewrite and redirect:
    #RewriteEngine on
    #RewriteRule abc.htm /abc1.htm [R=301,L]
    Also I already have [#RewriteEngine on] in my htaccess file. Do I need to again add this line of code?

    • Hi Nik,

      Do you mean you want to redirect abc1.htm to abc.htm? In that case the code should be:

      Rewrite abc1.htm /abc.htm [R=301,L]

      If you already have RewriteEngine on in you htaccess, there is no need to add it again.

      However, be reminded that the “#” before the lines indicate it is a comment (i.e. inactive).

  6. simran says:


    I want to convert below url


    Please give me .htaccess code

    Thanks in adv

  7. simran says:

    I need help to rectify the code.
    .htaccess [file]

    RewriteEngine on
    RewriteRule ^user/([0-9a-zA-Z]+)$ user.php?u=$1 [NC,L]

    user.php [file]

    I am using Linux server . And using code as mentioned above. I am getting static contents are written in user.php . But I am not getting parameters(dynamic contents).

    Please help me to rectify the problem.