SEO Friendly URLs With Mod Rewrite

So called ‘dirty URLS’ (E.g. not only look untidy but also pose a security risk as they expose the underlying technology used, in this case, ASP. A much preferred URL in this case would be or even better, The latter URL structure not only improves useability for your site (the URL makes more sense to the user) and is argued to improve search engine rankings. There is a lot of debate on this subject, but everyone agress that these so called pretty URL’s don’t hurt anything and mainly improve user experience.  Google has also recently posted a video (obviously not giving much away) saying that SEO friendly URL’s do in fact make a small difference and don’t hurt SERPs’

Take the example of this very blog. Pretty urls are used to display the post title and id within the url. There is the option to simply include the title, but this has been proven to slow down general performance of your blog. I digress, let’s get onto some examples where simple URL rewriting with mod rewrite is useful.

Currently at work I’m working on an internal administration system to handle invoices, customers, quotes – basically everything to replace a paper based admin system, I was given the brief to mimick the basecamphq project management system. With the except of several pages I’ve managed to keep the URL fairly clean looking using a directory structure (E.g. and POST data. However, a couple of URL’s do look ugly, namely the order detail page – I thought this would be the perfect excuse to use some URL rewriting. Reading some articles, you feel like you need a degree in regular expressions and LAMP setups to get this working, but it’s far from the truth, especially with the help of some online regex generaters.

So currently I have an order details page that simply fetches data for the order reference contaojed within the querystring. I’ll assume you know how to do the basics. I’ll get straight into it, here’s the familiar .htaccess file contents with a rule for my orders_detail.php page:

RewriteBase /
RewriteEngine on
RewriteRule ^order/detail/([^/]*)$ /orders_detail.php?orderRef=$1 [QSA,L]

To keep this article brief I’ll leave out the detail on what everything actually means but it basically redirects the url to, all without the user knowing, obviously the former URL is kept within the address bar too. It really is that simple!

However, as with anything good there are other factors to considor. If you use relative url paths in your page you’ll need to these to absolute paths. Take the example of my code to include a simple CSS file into my orders_detail.php page:

	<link href="css/main_compiled.css" rel="stylesheet" type="text/css" />

This worked fine when using the old URL, but now the page looks for, which doesn’t exist. You have several options here. You can use abolute paths for all your links, a base href within the header tag or add a rewrite base variable to each page and out it before the link. E.g.

define('BASE_PATH', '/');

and using it to a fix a hyperlink:

<a href="<?php echo MOD_REWRITE_BASE_PATH; ?>img/logo.png">View Logo</a>

That’s it!

Another place I use URL rewriting is to give custom news systems, blogs and events pages a little extra. For example, we’ll turn into – wordpress style. Again, I’ll take the example of a news system, where we have a front page with news listing and a detail page with the full news item. Firstly let’s dealwith outputting our pretty url on the front news page.

Currently we have a list of links with a post id attached to the link. Clicking rhe link will tajke you to a detail page. See here for the progress so far. However, at the minute our links page only has the post id and nothing mentioning the post title. This is simply a case of adding another variable (title) to the querystring, see here for an updated page. For simplicity I’ve used a single title (you would normally fetch the title from a database) and included hyphens to seperate words (search engines recognioze this as a space). Adding hyphens between words is a simply a case of running the title through a function. As the one I use is a at work I shamelessly used the one from the html blog. Here’s the PHP to generate our links page (note, I used a simple loop to output the links for quickness, in reality this list would come from a database):

function friendlyURL($string){
$string = preg_replace("`\[.*\]`U","",$string);
$string = preg_replace('`&(amp;)?#?[a-z0-9]+;`i','-',$string);
$string = htmlentities($string, ENT_COMPAT, 'utf-8');
$string = preg_replace( "`&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);`i","\\1", $string );
$string = preg_replace( array("`[^a-z0-9]`i","`[-]+`") , "-", $string);
return strtolower(trim($string, '-'));

$prettyTitle =  friendlyURL("seo friendly urls with mod rewrite");

for ($i = 1500; $i <= 1520; $i++) {
  echo "
<a href="\&quot;news-detail.php?postID=$i&title=$prettyTitle\&quot;">New Item Headline</a>


Now comes the time to update our htacess file with the following rule:

# This is a comment: Rewrite news-detail.php?postID=1234&title=text-text to /1234/text-text
RewriteRule ^(.*)/([a-zA-Z-]+)$ /news-detail.php?postID=$1&title=$2 [QSA,L]

On the page listing I’ve amened how our links are printed out (using the new pretty structure) and to show its working added an example of when an invalid article id is entered (E.g. when fetching it from our database). E.g. lets say article id 1503 is not in our database.

<!--?php if ($_REQUEST['postID']=='1503') { echo "Article Not Found!"; } else { ?--></pre>
<h1><!--?php echo str_replace("-","&nbsp;",$_REQUEST['title']); ?--> (ID<span class="highlight">
 <!--?php echo intval(htmlentities($_REQUEST['postID'])); ?--></span>)</h1>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab
        illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut
        odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum
        quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat
        voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur?
        Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo
        voluptas nulla pariatur?

<!--?php }  ?-->

That’s it in all honesty. I can’t show you an example on this server as WordPress uses the same structure. You can download the source files to play with.

This technique can easily be used in various forms for ecommerce sites – E.g. and in blogs or news systems. It’s a big subject andf I’ve only covered the basics here.

Published by

Rob Allport

Web Developer based in Stoke-on-Trent Staffordshire Google+ - Twitter

11 thoughts on “SEO Friendly URLs With Mod Rewrite”

  1. @SEO India

    I thought the same to be honest. Loads of tutorials explaining all the regexp patterns and what the markers within the htaccess file mean, bit none explaining how to get it up and running with a popular language like PHP.

    As I’m in a surprisingly good mood tonight, I’ll let the blatent and totally shameless SEO link anchor text go this time, consider yourself (mildly) warned 😉

  2. Finally, after many weeks of failing and failing I finally found a tutorial which covers everything and not just one single part of the whole ride.

    Thanks a lot man!

  3. SEO Urls have minimal effect on the website ranking in my experience. It definately doesn’t hurt to have them inn there though within reason. I’ve seen some seo urls so long that it totally defeats the object.

    You could have also done it wordpress style, where they have a single rewrite rule and handle all of the rewriting using php.

    I also agree, there are many articles out there that don’t explain this very well, so I’m glad someone has taken the time to exp[lain things from the start.

  4. thank a lot for article.
    it’s very helpful but i have problem when title come out something like ng-2-handle. it problem with number 2 at the title, how i can fix it at the function?
    it okay when i delete it use $prettyTitle= str_replace(“2″,””,friendlyURL($string)) ;
    need your help

Comments are closed.