NameSilo

SEO with mod_rewrite and .htaccess

Spaceship Spaceship
Watch

cDizzle

Established Member
Impact
1
This tutorial is originally written for my site, but I will share with you guys here since I know no one would end up visiting my site :p


Introduction
In this tutorial, you will learn how to use mod_rewrite in .htaccess files to alter users requests into what we want them to be. Before I get started, I must note that your server must be running apache (only like 99% of all servers run apache :p).

Ok lets get started!




First things first
To use mod_rewrite, you must use .htaccess files. To make a .htaccess file, do exactly that; create a file with the name of .htaccess (yes, starting with a dot). You may need to use double quotes around the name in a "Save As" dialog box.

In Macromedia Dreamweaver no matter what you do it will save as whatever document type you selected when selecing new. In this case, you must then rename the file to .htaccess

Once you have created this file, you are ready to use mod_rewrite.
To enable the mod_rewrite engine you must use the following directive before any rewrite commands:
Code:
RewriteEngine On

simple enough?




Force www. in the URL
The next bit of code will make any requests to http://domain.com be pointed to http://www.domain.com
It also keeps the requested file in the url, ie: domain.com/dir/to/page.php => www.domain.com/dir/to/page.php


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

Explaination:
>>> %{HTTP_HOST} is the requested hostname, such as google.com, or in our case domain.com (duh!)

>>> RewriteCond is like an if statement in PHP. It can use regular expressions to find patterns or positions of text. In this case it would be saying:
if( %{HTTP_HOST starts with 'domain.com' }
since ^ means the beginning of a string.

>>> if the string starts with www. or any other subdomain, it will return false since it would not begin with domain.com and would not end up being redirected.

>>> Since RewriteRule is the next command after RewriteCond, if RewriteCond returns true, this is the command it does next. RewriteRule is like find and replace; if it doesnt find the string, it will skip the rule. Since in this case we are searching for ^(.*)$ it will match anything since (.*) is a wildcard
Syntax: RewriteRule FIND REPLACE directives

>>> [L] means its the last rewrite command, and no more mod_rewrite commands will be processed since it could screw up the result.

>>> [R=301] means permanent redirect. This is so the client (browser, whether search engine, or users browser) knows not to check the old URL again (which would be without the www.) and this helps with SEO so search engines don't see duplicates since www.domain.com and domain.com are considered two different pages

>>> You can seperate directives by , So [L] and [R=301] must be combined to [L,R=301]




Setting unhandled URLs to index.php
In this part of the tutorial, I will explain how to make URLs like site.com/pagename/subpage/option/etc execute to /index.php and the client (users browser, or search engine) wont even know it! The client will treat it like directories.

Why you ask, might we want this?
You and I could assume that these are 2 different pages with their own content:
--> site.com/tutorials.php?page=1
--> site.com/tutorials.php?page=2



-- and --

I think we could assume that these would be the same page with different styles.
--> site.com/tutorials.php?styleid=5
--> site.com/tutorials.php?styleid=1



-- thats great but... --

Search engines dont care, they see it as one page either way; to a seach engine, any of the above would be equivelent to
--> site.com/tutorials.php



-- pretty crappy huh? --

You put all that work into having your fancy pagination so tutorials are displayed across multiple pages and now search engines still see it as one page. Thank heaven (or the apache guys (and ladies (but mostly guys))) for mod_rewrite.



-- how should i set this up? --

well there is many different ways you can do it, but the way I will show you is probably the easiest and most flexible.

>> If a user requests a URL, and a file, or directory exists with that name, we should follow through with the request. I mean, this would be images; css; javascript; etc; and we wouldnt want them to miss out on that

>> If that file or directory doesnt exist (ie: we are using fake directory names in the URL) then lets rewrite to index.php and let our script handle the rest for us.



-- THE CODE --

Code:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+) - [PT,L]

RewriteRule ^(.*) /index.php



-- explaination --


if the requested filename is an existing file
Code:
RewriteCond %{REQUEST_FILENAME} -f


or... duh... meaning one of or both conditions
Code:
[OR]


if the requested filename is an existing directory
Code:
RewriteCond %{REQUEST_FILENAME} -d

follow through with the request, L for last rewrite, and PT to reveal the real path to directory
Code:
RewriteRule ^(.+) - [PT,L]

else, rewrite to /index.php, remember the client still believes this is directories, and the request goes to PHP just as is requested
Code:
RewriteRule ^(.*) /index.php


Congrats!
All requests to non-existant files will now be rewritten to index.php and the script can now handle the rest of it




The script -- index.php[size]
Now that we have all other requests going to index.php we need to find a way to parse the fake "directories" on the request into usable data.


PHP:
$req = explode('/', str_replace('//', '/', $_SERVER['REQUEST_URI']));

now $req will be an array. For every / in the REQUESTED URI.
The array starts at 0 (ie: $req[0])

say the url we requested was http://site.com/tutorials/PHP/1
$_SERVER['REQUEST_URI'] would be /tutorials/PHP/1

when we explode that, $req[0] will be blank since there is nothing before the first /, and the / counts as the first seperator.
$req[1] would be 'tutorials'
$req[2] would be 'PHP'
and so on

You do str_replace('//', '/') on it so that http://site.com/tutorials//PHP/1 wouldnt =
array(
0 => '',
1 => 'tutorials',
2 => '',
3 => 'PHP',
4 => 1
)

cus it would totally screw it all up

we can do a switch on $req[1]

PHP:
switch($req[1])
{
	case '': // if $req[1] is empty, this would be if u requested site.com/
		include('home.php');
		break;
	case 'pagename2': // if $req[1] == 'pagename2' site.com/pagename2
		include('pagename2.php');
		break;
	case 'tutorials':
		include('tut_functions.php');
		switch($req[2]) // just an example of how you can switch the next variable as well, so if the REQUEST_URL = /tutorials/view it would get to listtuts(); (which actually doesnt exist, but it is for example)
		{
			case 'list':
				listtuts();
				break;
		}
		break;
	default: // this is a 404
		include('404.php');
}




Bringing it all together
-- .htacces source (replace domain.com with your domain) --
Code:
RewriteEngine on

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

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+) - [PT,L]

RewriteRule ^(.*) /index.php


-- index.php (will vary fo' sho') --
PHP:
<?php
error_reporting(E_ALL & ~E_NOTICE);
ob_start("gz_handler"); // will compress your pages, saves you a ton of bandwidth, I will make a tut on this sometime
$req = explode('/', str_replace('//', '/', $_SERVER['REQUEST_URI']));
?>

<!-- navbar -->
<a href="/">Home</a> - <a href="/about">About</a>
<!-- these are just examples of how to link to the fake "directories" -->
<?php
switch($req[1])
{
	case '':
		include('home.php');
		break;
	case 'about':
		include('about.php');
		break;
	default:
		include('404.php');
}
?>

That wraps up this tutorial, hope you learned something, and please feel free to comment on this tutorial (just as soon as I make the comments system)





Hope you learned a little somethin from this tutorial since i know how all you domainers are realy worried about SEO :p
 
1
•••
The views expressed on this page by users and staff are their own, not those of NamePros.
AfternicAfternic
excellent tutorial - REP added
 
0
•••
Dynadot โ€” .com TransferDynadot โ€” .com Transfer
Domain Recover
DomainEasy โ€” Live Options
  • The sidebar remains visible by scrolling at a speed relative to the pageโ€™s height.
Back