Search Engine-Friendly URLs

Share this article

On today’s Internet, database driven or dynamic sites are very popular. Unfortunately the easiest way to pass information between your pages is with a query string. In case you don’t know what a query string is, it’s a string of information tacked onto the end of a URL after a question mark.

So, what’s the problem with that? Well, most search engines (with a few exceptions – namely Google) will not index any pages that have a question mark or other character (like an ampersand or equals sign) in the URL. So all of those popular dynamic sites out there aren’t being indexed – and what good is a site if no one can find it?

The solution? Search engine friendly URLs. There are a few popular ways to pass information to your pages without the use of a query string, so that search engines will still index those individual pages. I’ll cover 3 of these techniques in this article. All 3 work in PHP with Apache on Linux (and while they may work in other scenarios, I cannot confirm that they do).

Method 1: PATH_INFO

Implementation:

If you look above this article on the address bar, you’ll see a URL like this: http://www.webmasterbase.com/article.php/999/12. SitePoint actually uses the PATH_INFO method to create their dynamic pages.

Apache has a “look back” feature that scans backwards down the URL if it doesn’t find what it’s looking for. In this case there is no directory or file called “12”, so it looks for “999”. But it find that there’s not a directory or file called “999” either, so Apache continues to look down the URL and sees “article.php”. This file does exist, so Apache calls up that script. Apache also has a global variable called $PATH_INFO that is created on every HTTP request. What this variable contains is the script that’s being called, and everything to the right of that information in the URL. So in the example we’ve been using, $PATH_INFO will contain article.php/999/12.

So, you wonder, how do I query my database using article.php/999/12? First you have to split this into variables you can use. And you can do that using PHP’s explode function:

$var_array = explode("/",$PATH_INFO);

Once you do that, you’ll have the following information:

$var_array[0] = "article.php"
$var_array[1] = 999
$var_array[2] = 12

So you can rename $var_array[1] as $article and $var_array[2] as $page_num and query your database.

Drawback:

There was previously one major drawback to this method. Google, and perhaps other search engines, would not index pages set up in this manner, as they interpreted the URL as being malformed. I contacted a Software Developer at Google and made them aware of the problem and I am happy to announce that it is now fixed.

There is the potential that other search engines may ignore pages set up in this manner. While I don’t know of any, I can’t be certain that none do. If you do decide to use this method, be sure to monitor your server logs for spiders to ensure that your site is being indexed as it should.

Method 2: .htaccess Error Pages

Implementation:

The second method involves using the .htaccess file. If you’re new to it, .htaccess is a file used to administer Apache access options for whichever directory you place it in. The server administrator has a better method of doing this using his or her configuration files, but since most of us don’t own our own server, we don’t have control over what the server administrator does. Now, the server admin can configure what users can do with their .htaccess file so this approach may not work on your particular server, however in most cases it will. If it doesn’t, you should contact your server administrator.

This method takes advantage of .htaccess’ ability to do error handling. In the .htaccess file in whichever directory you wish to apply this method to, simply insert the following line:

ErrorDocument 404 /processor.php

Now make a script called processor.php and put it in that same directory, and you’re done! Lets say you have the following URL: http://www.domain.com/directory/999/12/. And again in this example “999” and “12” do not exist, however, as you don’t specify a script anywhere in the directory path, Apache will create a 404 error. Instead of sending a generic 404 header back to the browser, Apache sees the ErrorDocument command in the .htaccess file and calls up processor.php.

Now, in the first example we used the $PATH_INFO variable, but that won’t work this time. Instead we need to use the $REQUEST_URI variable, which contains everything in the URL after the domain. So in this case, it contains: /directory/999/12/.

The first thing you need to do in processor.php is send a new HTTP header. Remember, Apache thought this was a 404 error, so it wants to tell the browser that it couldn’t find a page.

So, put the following line in your processor.php:

header("HTTP/1.1 200 OK");

At this time I need to point out an important fact. In the first example you could specify what script processed your URL. In this example all URLs must be processed by the same script, processor.php, which makes things a little different. Instead of creating different URLs based on what you want to do, such as article.php/999/12 or printarticle.php/999/12 you only have 1 script that must do both.

So you must decide what to do based on the information processor.php receives – more specifically, by counting how many parameters are passed. For instance on my site, I use this method to generate my pages: I know that if there’s just one parameter, such as http://www.online-literature.com/shakespeare/, that I need to load an author information page; if there are 2 parameters, such as http://www.online-literature.com/shakespeare/hamlet/, I know that I need to load a book information page; and finally if there are 3 parameters, such as http://www.online-literature.com/shakespeare/hamlet/3/, I know I need to load a chapter viewing page. Alternatively, you can simply use the first parameter to indicate the type of page to display, and then process the remaining parameters based on that.

There are 2 ways you can accomplish this task of counting parameters. First you need to use PHP’s explode function to divide up the $REQUEST_URI variable. So if $REQUEST_URI = /shakespeare/hamlet/3/:

$var_array = explode("/",$REQUEST_URI);

Now note that, because of the positioning of the /’ there are actually 5 elements in this array. The first element, element 0, is blank, because it contains the information before the first /. The fifth element, element 4, is also blank, because it contains the information after the last /.

So now we need to count the elements in our $var_array. PHP has two functions that let us do this. We can use the sizeof() function as in this example:

$num = sizeof($var_array); // 5

You’ll notice that the sizeof() function counts every item in the array regardless of whether it’s empty. The other function is count(), which is an alias for the sizeof() function.

Some search engines, like AOL, will automatically remove the trailing / from your URL, and this can cause problems if you’re using these functions to count your array. For instance http://www.online-literature.com/shakespeare/hamlet/ becomes http://www.online-literature.com/shakespeare/hamlet, and as there are 3 total elements in that array our processor.php would load an author page instead of a book page.

The solution is to create a function that will count only the elements in an array that actually hold data. This will allow you to leave off the ending / or allow any links from AOL”s search engine to point to the proper place. An example of such a function is:

function count_all($arg)  
{  
 // skip if argument is empty  
 if ($arg) {  
   // not an array, return 1 (base case)  
   if(!is_array($arg))  
   return 1;  
   // else call recursively for all elements $arg  
   foreach($arg as $key => $val)  
   $count += count_all($val);  
   return $count;  
 }  
}

To get your count, access the function like this:

$num = count_all($url_array);

Once you know how many parameters you need, you can define them like this:

$author=$var_array[1]; 
$book=$var_array[2];
$chapter=$var_array[3];

Then you can use includes to call up the appropriate script, which will query your database and set up your page. Also if you get a result you’re not expecting, you can simply create your own error page for display to the browser.

Drawback:

The drawback of this method is that every page that’s hit is seen by Apache as an error. Thus every hit creates another entry in your server error logs, which effectively destroys their usefulness. So if you use this method you sacrifice your error logs.

Method 3: The ForceType Directive

Implementation:

You’ll recall that the thing that trips up Google, and maybe even other search engines, when using the PATH_INFO method is the period in the middle of the URL. So what if there was a way to use that method without the period? Guess what? There is! Its achieved using Apache”s ForceType directive.

The ForceType directive allows you to override any default MIME types you have set up. Usually it may be used to parse an HTML page as PHP or something similar, but in this case we will use it to parse a file with no extension as PHP.

So instead of using article.php, as we did in method 1, rename that file to just “article”. You will then be able to access it like this: http://www.domain.com/article/999/12/, utilizing Apache’s look back feature and PATH_INFO variable as described in method 1. But now, Apache doesn’t know to that “article” needs to be parsed as php. To tell it that, you must add the following to your .htaccess file.

<Files article>    
 ForceType application/x-httpd-php    
</Files>

This is known as a “container”. Instead of applying directives to all files, Apache allows you to limit them by filename, location, or directory. You need to create a container as above and place the directives inside it. In this case we use a file container, we identify “article” as the file we’re concerned with, and then we list the directives we want applied to this file before closing off the container.

By placing the directive inside the container, we tell Apache to parse “article” as a PHP script even though it has no file extension. This allows us to get rid of the period in the URL that causes the problems, and yet still use the PATH_INFO method to manage our site.

Drawback:

The only drawback to this method as compared with method 2 is that your URLs will be slightly longer. For instance, if I were to use this method on my site, I’d have to use URLs like this: http://www.online-literature.com/ol/homer/odyssey/ instead of http://www.online-literature.com/homer/odyssey/. However if you had a site like SitePoint and used this method it wouldn’t be such a problem, as the URL (http://www.SitePoint.com/article/755/12/) would make more sense.

Conclusion

I have outlined 3 methods of making search engine friendly URLs – along with their drawbacks. Obviously, you should evaluate these drawbacks before deciding which method to implement. And if you have any questions about the implementation of these techniques, they are oft-discussed topics on the SitePoint Forums so just stop in and make a post.

Frequently Asked Questions (FAQs) about Search Engine Friendly URLs

What are the key elements of a search engine friendly URL?

A search engine friendly URL is one that is easy for both users and search engines to understand. It should be structured, clean, and descriptive. The key elements include a secure HTTPS protocol, a domain that is easy to remember, a path that accurately describes the content, and a file name that is descriptive and concise. It’s also beneficial to include keywords relevant to the content, but avoid keyword stuffing as it can lead to penalties from search engines.

How does a search engine friendly URL impact SEO?

A search engine friendly URL can significantly impact SEO. It helps search engines understand what your page is about, which can improve your ranking for relevant keywords. It also improves user experience, as users are more likely to click on a URL that clearly indicates what they will find on the page. This can increase click-through rates and decrease bounce rates, both of which can positively impact SEO.

What is the difference between a dynamic URL and a static URL?

A dynamic URL is one that changes and is generated automatically based on database parameters or user information. On the other hand, a static URL remains the same and is manually entered by the user. Static URLs are generally more search engine friendly as they are easier to read and understand, and they can include keywords relevant to the content.

How can I make my URLs more search engine friendly?

To make your URLs more search engine friendly, start by using a secure HTTPS protocol. Make sure your domain is easy to remember and your path accurately describes your content. Use a descriptive file name and include relevant keywords, but avoid keyword stuffing. Keep your URLs as short as possible, but ensure they are descriptive enough for users and search engines to understand what the page is about.

What are the common mistakes to avoid when creating search engine friendly URLs?

Common mistakes to avoid include using non-alphanumeric characters, using too many parameters, keyword stuffing, and using uppercase letters. It’s also important to avoid using session IDs in URLs, as this can create duplicate content issues. Lastly, avoid using generic page names like “page1” or “post123”, instead use descriptive names that give an indication of the content.

How does URL structure affect user experience?

URL structure can significantly affect user experience. A clear and descriptive URL can help users understand what they will find on the page before they click on it. This can increase trust and click-through rates. On the other hand, a confusing or misleading URL can lead to a poor user experience and high bounce rates.

Should I use hyphens or underscores in my URLs?

It’s generally recommended to use hyphens in URLs rather than underscores. This is because search engines treat hyphens as spaces, which makes the URL easier to read and understand. On the other hand, underscores are often treated as a single word, which can make the URL harder to read.

How important is it to include keywords in my URLs?

Including keywords in your URLs can help search engines understand what your page is about, which can improve your ranking for those keywords. However, it’s important to use keywords naturally and avoid keyword stuffing. The user experience should always be the priority, so ensure your URLs are descriptive and helpful for users first and foremost.

Should I change my existing URLs to make them more search engine friendly?

Changing existing URLs should be done with caution, as it can lead to broken links and a loss of SEO value. If you decide to change your URLs, make sure to set up proper 301 redirects to the new URLs to preserve SEO value and prevent broken links.

How can I check if my URLs are search engine friendly?

There are several tools available online that can help you check if your URLs are search engine friendly. These tools can identify issues such as long URLs, non-alphanumeric characters, and missing keywords. It’s also a good idea to manually review your URLs to ensure they are clear, descriptive, and easy to understand.

Chris BeasleyChris Beasley
View Author
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week