August 7th, 2008
Tutorial : Creating “Pretty SEO URLS” using Apache’s mod_rewrite
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
- Step 1 : Enable mod_rewrite in httpd.conf
- Step 2 : Create A Simple PHP file
- Step 3 : .htaccess file
Method 1 – For only a single Variable
Method 2 – For 1 and more than 1 Variable(s) - 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.
- Navigate to your apache folder and open httpd.conf
- Search for
#LoadModule rewrite_module modules/mod_rewrite.so
- Remove the commenting character i.e #, then save the file.
- 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;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,…]- 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 -
target_url is test.php?page=$1
$1 is a variable where $1 = (.*) from the pattern. -
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.
- pattern is ^(.*)\.html$
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]
- 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 -
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 = (.*) -
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.















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
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”?
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”
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.
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.
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.
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.
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..
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
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.
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