Click to find out more about our Work
August 7th, 2008

Tutorial : Creating “Pretty SEO URLS” using Apache’s mod_rewrite

16 Comments

Imagine this, You have a dynamic site powered by PHP/MySQL, its doing ok, you have submitted your website URL to all the known search engines, but still your site doesn’t seem to get much traffic from the search engines…ever wondered why ?

Well firstly, search engines have billions of pages to search. Imagine your link to be something like www.yourdomain.com/index.php?page=aboutme, its tough for any search engine to comprehend any keywords from the link.
But how about www.yourdomain.com/page/about-me.html ? These links are static Links, SEO Friendly Links, “Pretty Links”.

So today we are going to learn how to convert your ugly links into pretty links.

Index

  1. Step 1 : Enable mod_rewrite in httpd.conf
  2. Step 2 : Create A Simple PHP file
  3. Step 3 : .htaccess file
    Method 1 – For only a single Variable
    Method 2 – For 1 and more than 1 Variable(s)
  4. Conclusion

Ugly URLs
http://www.visionmasterdesigns.com/demo/seo/test.php?page=page1
http://www.visionmasterdesigns.com/demo/seo/test.php?page=page1&var=foo

Pretty URLs
http://www.visionmasterdesigns.com/demo/seo/page1.html
http://www.visionmasterdesigns.com/demo/seo/page1/foo.html

Click Here to download the script files.

Step 1 : Enable mod_rewrite in httpd.conf

Normally webservers already have mod_rewrite enabled. If it is not enabled, then you can request your host to enable it.

If you are going to try this tutorial in your local machine. Do check whether mod_rewrite module has been enabled in Apache. Do the following.

  1. Navigate to your apache folder and open httpd.conf
  2. Search for
    #LoadModule rewrite_module modules/mod_rewrite.so
  3. Remove the commenting character i.e #, then save the file.
  4. Restart the Server

About the .htaccess file

You must have seen or heard about .htaccess file somewhere.

Quote from wikipedia :
In the Apache web server, .htaccess (hypertext access) is the default name of directory-level configuration files. A .htaccess file is placed in a particular directory, and the directives in the .htaccess file apply to that directory, and all subdirectories thereof. It provides the ability to customize configuration for requests to the particular directory.

Normally the .htaccess file must be present in the directory where your script is stored.
For Example : If my script is
myserver.dev/prettyurl/test.php
then my .htaccess file will be saved in
C:\server\www\myserver.dev\public_html\prettyurl\.htaccess *

*This is applicable if you have followed –
Tutorial : Installing Apache, PHP 5, MySQL 5 & PhpMyAdmin 2.11 in Windows Vista/XP

Step 2 : Create A Simple PHP file

Lets create a simple PHP file. PHP allows us to retrieve values from the URL iself using $_GET function.

For Example :
http://myserver.dev/prettyurl/test.php?page=mypagename.
$_GET['page'] would give the value of page in the above url.

http://myserver.dev/prettyurl/test.php?page=mypagename&var=secondvar.
We can have retrieve quite a lot of data from the URLs by using multiple $_GET functions. In the above URL we can have $_GET['page'] and $_GET['var']

<?php

//test.php
//storing the retrieved val from URL into a variable
$p = $_GET['page'];
$q = $_GET['var'];

switch($p) {
    case 'page1':
    // if $p = page1 i.e url was something like test.php?page=page1
  		switch($q) {
		case 'boo':
		//if $p=boo then url is somehting like test.php?page=page1&amp;amp;var=boo
		echo "<h2>This is page1 And BOO</h2><br />";
		break;
		case 'foo':
		echo "<h2>This is page1 And FOO</h2><br />";
		break;
		default:
		// if $p = page1 i.e url was something like test.php?page=page1
		echo "<h2>This is page1</h2>";
		break;
		}
    break;
    case 'page2':
    // if $p = page2 i.e url was something like test.php?page=page2
    echo "<h2>This is page2</h2>";
    break;
    case 'page3':
    // if $p = page3 i.e url was something like test.php?page=page3
    echo "<h2>This is page3</h2>";
    break;
    case 'page4':
    // if $p = page4 i.e url was something like test.php?page=page4
    echo "<h2>This is page4</h2>";
    break;
    default:
    // if page != any of the above, then default is executed
    echo "<h2>This is the Default Page</h2>";
	break;
}
?>

Save the file as test.php.

Test out the script, if we access
http://myserver.dev/prettyurl/test.php?page=page1
the result will be ‘This is page1′.
Similarly http://myserver.dev/prettyurl/test.php?page=page2
will show the output ‘This is page2′ and so on.

If we access
http://myserver.dev/prettyurl/test.php?page=page1&var=foo
the output will be ‘This is page1 And foo’

This sample code in PHP is to just show you how a general linking system works. It shows how $_GET works and how we can add data in the URL’s using ‘&’ operator.

Step 3 : .htaccess file

There are different methods to create “Pretty URLS”. I`ll just discuss the most common and the most optimized ones.

Ok ! Firstly our local server won`t have a .htaccess file, so we will have to create one. Fire up notepad, then type the following code.
Save the file as .htaccess. Place it in the directory where you have saved your test.php script.

Method 1 – For only a single Variable

Consider our dynamic URL to be
http://myserver.dev/prettyurl/test.php?page=page2
and we want our pretty url to look something like
http://myserver.dev/prettyurl/page2.html

#.htaccess code
RewriteEngine On
RewriteRule ^(.*)\.html$ test.php?page=$1 [L]

Let me explain what every line does.

  • RewriteEngine On
    This tells to start the Rewrite Engine.
  • RewriteRule ^(.*)\.html$ test.php?page=$1 [L]
    The basic syntax of
    RewriteRule pattern target_url [flag,flag,flag,…]

    1. pattern is ^(.*)\.html$
      () – Parentheses allow you to group several characters as a unit and also to capture the results of a match for later use. The ability to treat several characters as a unit is extremely useful in pattern matching.

      (.*) – Matches anything.
      Eg: http://myserver.dev/prettyurl/page1.html where (.*)\.html matches page1.html

    2. target_url is test.php?page=$1
      $1 is a variable where $1 = (.*) from the pattern.
    3. flag is [L].
      There are various flags. [L] means, If there is a match with a particular rewrite rule, It has to be the last rewrite rule to be executed.

Now lets test run our script. If the dynamic link is like
http://myserver.dev/prettyurl/test.php?page=page1
then your pretty link will be
http://myserver.dev/prettyurl/page1.html
Similarly for page=page2 the link will be page2.html ,page=page3 the link will be page3.html.

Phew ! That took a lot of time. If you are able to see the same output for both the ugly links and the pretty links, then you Rewrite rules are working perfectly.

Method 2 – For 1 and more than 1 Variable(s)

Now what if your dynamic URL was like
http://myserver.dev/prettyurl/test.php?page=page1&var=foo.
For the above dynamic URL we want our static URL to look something like
http://myserver.dev/prettyurl/page1/foo.html.
We want the first variable to act as a directory, while the second one should be the file name.

Note that previously page=page1 had become ‘page1.html’ since there was just one variable. But now we have 2 variables (page=page1&var=foo) so we the structure should be like ‘page1/foo.html’

We have to write a new RewriteRule to support 2 variables.
Remember : As your variables increase, the new Rewrite rules come before the previous ones.

We are basically extending Method 1 by adding another RewriteRule to support 2 variables as input.

RewriteEngine On
RewriteRule ([^/]+)/(.*)\.html$ test.php?page=$1&var=$2 [L]
RewriteRule ^(.*)\.html$ test.php?page=$1 [L]

Let me Explain what the new line does.
RewriteRule ([^/]+)/(.*)\.html$ test.php?page=$1&var=$2 [L]

  1. pattern is ([^/]+)/(.*)\.html$
    ([^/]+) – Which has the effect of matching any characters up to a slash or the end of the string, whichever comes first.
    (.*) – Matches anything

    ([^/]+)/(.*)\.html$ – characters up to slash ‘/’ any characters ‘.html’
    Eg: page1/foo.html where ([^/]+) matches page1 and (.*)\.html matches foo.html

  2. target_url is test.php?page=$1&var=$2
    Every variable i.e $1 and $2 matches with the unit inside the paranthesis.
    $1 = ([^/]+)
    $2 = (.*)
  3. flag is [L].
    There are various flags. [L] means, If there is a match with a particular rewrite rule, It has to be the last rewrite rule to be executed.

You can test it out
For all dynamic links like
http://myserver.dev/prettyurl/test.php?page=page1&var=foo
will have static URL’s like
http://myserver.dev/prettyurl/page1/foo.html

Conclusion

(Method 1   Method 2)
Thus for all dynamic links like

http://myserver.dev/prettyurl/test.php?page=pagex

will have static URL’s like

http://myserver.dev/prettyurl/pagex.html

(Method 2)
For all dynamic links like

http://myserver.dev/prettyurl/test.php?page=pagex&var=foo

will have static URL’s like

http://myserver.dev/prettyurl/pagex/foo.html

This was quite a basic tutorial. It is tough to understand the string matching patterns initially. But the logic is very simple. I hope the tutorial wasn’t tough to understand. If you guys have any doubts, feel free to comment here, I`ll try to solve them. Cya

Click Here to download the files.

16 Responses to “Tutorial : Creating “Pretty SEO URLS” using Apache’s mod_rewrite”

  1. Adams D
    August 30, 2010 at 5:30 pm

    Great article…I will surely use it for my site http://www.livedirectorynow.com

  2. Esmeralda Cosey
    July 12, 2010 at 7:42 pm

    I just saw your web page on google its an incredible site you’ve done an incredible job I will surely come back Thanks!

  3. Kandy Perretta
    May 23, 2010 at 8:11 pm

    It’s a very time consuming process. Sometimes it’s better to hire a Atlanta Search Engine Optimization company to do the work for you.

  4. vicky
    May 7, 2010 at 6:28 pm

    that's really a fantastic post ! added to my favourite blogs list.. I have been reading your blog last couple of weeks and enjoy every bit. Thanks.

  5. bassie
    October 14, 2009 at 1:35 am

    I understand the rewrite htaccess.
    But Seo whise: The page still creates links with parameters and isn’t it so that the se crawlers will still see the links going to pages with parameters, and therefor isn’t there a need to 301 redirect, and make your php script create links that are seo friendly as well ?

    grtz

  6. ubh
    April 12, 2009 at 1:46 am

    patd, I am running apache 2.2 and php 5.2.9 and I have mod rewrite turned on.

    My question is with this guy:
    RewriteRule ^(.*)\.php$ index.php?pageName=$1 [L]

    Upon using it on a url like this:
    http://localhost/newSite/home.php

    The pageName variable in the index.php file comes out as “index” instead of the request “home”. Please my friend can you shed some light why when passing home.php into the pageName variable it comes out as “index”?

  7. patd
    April 11, 2009 at 12:00 pm

    I have to say this .htaccess thing is pretty hard.

    try tutorials that are available online, or try this book, its good “Definitive Guide to Apache mod_rewrite”

  8. danreb
    April 11, 2009 at 11:52 am

    thanks, patd now it works, but i was pretty confuse, maybe need help with all the master here!, I was able to create a pretty URL in my company site , from this ugly URL – http://teamquest-inc.com.ph/index.php?id=1 now can be browse with this pretty URL of http://teamquest-inc.com.ph/pages1.html and so on ( all other pages also comes in that format – pages2,3,4,5.html)

    but this URL I find it hard to convert into pretty URL -
    [code]http://teamquest-inc.com.ph/index.php?id=6&action=show_blog_entry&blog_entry_id=1&blog_id=1
    [/code] all I want is to Rewrite this URl to this one
    [code]http://teamquest-inc.com.ph/pages/blog/entry1.html[/code] and so on….

    Any suggestion how can I achived this? I am very new in URL Rewriting , thanks in advanced.

  9. patd
    April 11, 2009 at 7:49 am

    actually its was the problem of easyphp, but I used xampp, and it worked fine.

    so friends use xampp.

  10. danreb
    April 10, 2009 at 9:26 pm

    Yes, just as patd said , the sample file is not working also in my server, the mod_rewrite option is also enabled.

  11. patd
    March 6, 2009 at 4:05 pm

    Hi,
    I have used the files you have provided, but its not working in my server.
    I have already check the mod_rewrite option and its enabled.

    can you tell me what could be the problem, does it work on windows. I have easyphp installed on windows.

  12. OnYoK
    October 28, 2008 at 11:48 am

    Hi Tolinho,

    Can you please share also to me what you did?. I just can’t get it..Thanks in advance..

  13. Tolinho
    October 9, 2008 at 11:27 pm

    Hi Michael.
    Thanks for your fast reply :)
    I understand that the .html is really only a mask to the .php file that get called instead.

    So lets imagine I have a list os products, that list gets created automatically from a table on the data base and the normal link to the product detail page would be:
    http://localhost/seo/product_details.php?id=5

    What we need is to created a nice SEO link for the product details has the main product list page gets created.
    In other words, instead of getting page with a list of products like:
    http://localhost/seo/product_details.php?id=5
    http://localhost/seo/product_details.php?id=6
    http://localhost/seo/product_details.php?id=7

    That page must be constructed with the nice seo url for example
    http://localhost/seo/usb-tv-tuner-p-5.html
    http://localhost/seo/usb-mouse-p-6.html
    http://localhost/seo/19-monitor-lg-7.html

    To get these nice seo urls in the main product list we will need a funcion to build those links as the page get created correct?

    I thought the “convertion” would be automatic but now I think I see that needs to be done.

    Ill try to make a function that will create nice seo links has that main product list page get built, instead of using the ordinary links.
    Thanks for your help :)

  14. Michael
    October 9, 2008 at 5:24 pm

    Hey Tolinho,

    I think you haven`t understand what happens here. The thing is instead of typing http://localhost/seo/test.php?page=page1 in the browser to get “This is page1? we can simply type http://localhost/seo/page1.html to get the same result.

    Please note that we are not actually creating a .html file and putting in the server, rather modifying the incoming link which is dynamic to a static one, even though the static one will execute the php file to get the result.

    Its more like we are putting a mask over our dynamic url which shows the static url to the world. But actually the dynamic php file is getting executed in both ways.

  15. Tolinho
    October 9, 2008 at 2:01 pm

    Hi.
    I have a question regarding this article.

    If I type http://localhost/seo/test.php?page=page1 in by browser I get “This is page1″

    But my question is regarding the URL. Shouldnt I get redirected to http://localhost/seo/page1.html and get the message This is page1?

    I see this beaviour on some websites, like oscommerce websites, I just dont know how to do it.
    I would say it would make more sense to the search engine to pickup the statik links rather than the dymanic ones.
    Any help will be apreciated. Thanks :)

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <p> <q cite=""> <strike> <strong>