Pretty, SEO-friendly URLs with .htaccess

techie-iconIt is often said that dynamic URLs – that is, URLs with a format like blog.php?id=1&title=hello – are at a disadvantage compared to static-looking URLs of the format blog/1/hello. There is much debate about this issue though and back in 2008 Google even recommended against rewriting URLs.

Google said:

Does that mean I should avoid rewriting dynamic URLs at all?

That’s our recommendation, unless your rewrites are limited to removing unnecessary parameters, or you are very diligent in removing all parameters that could cause problems. If you transform your dynamic URL to make it look static you should be aware that we might not be able to interpret the information correctly in all cases. If you want to serve a static equivalent of your site, you might want to consider transforming the underlying content by serving a replacement which is truly static.

So, according to Google back in 2008, blog.php?id=1 is just as good as blog/1/.

However, there are other reasons why you might want to rewrite your URLs. One of those is for URL keyword prominence. Google never really tells us much about the internal workings of its search engines but a lot of folk in the SEO world suggest that having keywords in the URL helps with the ranking of a page.

So blog/all-about-widgets/ may be a better URL than blog?id=1 but what about blog?title=all-about-widgets? I’d suggest that the latter is better than blog/1/ even though blog/1/ is static-looking and blog?title=all-about-widgetsisn’t.

To be honest, if a dynamic URL contains the same information as its static-looking equivalent, I don’t think it makes much difference to how a page is ranked.

I would suggest that:

blog?title=all-about-widgets

Ranks just as well as:

blog/all-about-widgets/

However, there is an argument that the second of the above two examples is easier for the human to read and may therefore improve click-through rates. This may be a valid point.

Still, whatever your reason for wanting static-looking URLs, you can go about it by messing about with your .htaccess file.

Let’s say you had a URL such as:

blog-single.php?id=1&title=this-is-my-first-blog

And you wanted to turn it into this:

blog/1/this-is-my-first-blog/

The sort of thing you’d need in your .htaccess file is:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/([0-9]+)/([0-9a-z-]+)/?$ blog-single.php?id=$1&title=$2 [NC,L]

The RewriteEngine On statement switches on URL rewriting.

The two RewriteCond statements check that what’s being requested is neither a valid file (!-f) nor a valid directory (!-d) and if those two conditions are true it will execute the RewriteRule statement that follows it.

The RewriteRule statement is where the work is done and it uses regular expressions.

It’s going to compare the URL’s path (that is, the part of it after the http://mydomain.com/ bit) with the regular expression indicated by: ^blog/([0-9]+)/([0-9a-z-]+)/?$

So let’s break down that regular expression and see what it says.

^ says “this is at the beginning” so, for example a path of xblog/1/title would not match here.
blog/ says simply match the characters ‘blog’ followed by a forward slash.
([0-9]+) says match any charater from 0 to 9. This is called a character class and is enclosed in square brackets. The + says match that character class any number of times. So it would match 1098 and 56789 but not 1abhello or 00000a. By enclosing the whole thing in rounded brackets we’re telling the system to save the output it gets here and use that as the $1 variable for the second part of the line (blog-single.php?id=$1&title=$2).
/ says just match with a forward slash
([0-9a-z-]+) is another character class, indicated by the square brackets, but as well as matching 0-9 it will also match a-z and a dash (-). Once again the + says it can match those characters any number of times. We’re also saving this in the $2 variable (as indicated by the round brackets).
/? says match the forward slash zero or one times. Essentially that’s saying we can use either blog/123/title/ or blog/123/title, so the trailing forward slash is optional.
$ says “this is the end of the string”.

Then we have the URL that will be used when a match is found, in this case: blog-single.php?id=$1&title=$2. The $1 and $2 parameters corresond to the stuff in the round brackets in the regular expression.

So blog/1/my-widget-article becomes blog-single.php?id=1&title=my-widget-article.

The [NC,L] tells us that this statement is case-insensitive (NC) and that no further .htaccess statements should be processed after it (L).

Whay happens is that the .htaccess file will force an internal redirect from blog/1/my-widget-article to blog-single.php?id=1&title=my-widget-article and the user’s address bar will still show the original blog/1/my-widget-article address.

If you actually wanted to a redirect and change the user’s address bar to blog-single.php?id=1&title=my-widget-article then you could add an R into the square brackets at the end (such as [R,NC,L]). Most people don’t want to do this but it can be useful for testing.

Anyway, that’s a brief introduction to .htaccess rewrites. Be prepared for a lot of frustration when playing around with this stuff – it rarely does what you think you’re telling it to.

2 comments
  1. Someone necessarily lend a hand to make critically articles I’d state.
    That is the first time I frequented your website page and to this point?
    I surprised with the research you made to
    create this particular submit extraordinary. Fantastic activity!

Leave a Reply