User Friendly URLs

Make your URLs SEO-friendly

One of the useful functions of the .htaccess file is the ability to change URLs. You can use it to redirect one URL to another or use it to make a broad sweeping change to all URLs on your website. A facet of this ability was demonstrated in the last section.

In this chapter, we will look at how to use the rewrite rules to fix common an SEO problem. The problem we will be fixing will be non-SEO-friendly URLs. SEO-friendly URLs are user and machine readable with a logical hierarchy.

Understanding SEO-friendly URLs.

SEO-friendly URLs are fundamentally URLs that use relevant, common language, and semantically significant words in the domain, path, and page. What does that mean? It means that people who look at the URL should be able to read it and understand what should be on the page it serves.

Example: SEO-Friendly URLs

This URL is NOT SEO-friendly.

This URL is SEO-friendly.

If this seems complicated, you can follow several basic rules that will help. Those rules are as follows:

  • Use a single domain.
  • Only use a subdomain if it is absolutely necessary.
  • Use plain words for the folder/paths and page names.
  • Use keywords in the URL. Yes, just using words is not the same as using descriptive, relevant words.
  • Shorter URLs are better.
  • Keep URLs similar to page titles.
  • Keep special characters out of the URL as much as possible.
  • Avoid having too many folders.
  • Try to stick to all lowercase URLs.
  • Separate words with hyphens.

If you follow these rules, your URLs will be much more readable.

SEO-friendly URLs via .htaccess.

Now, that we have covered what SEO-friendly URLs are, we can look at how to use the .htaccess file to achieve them.

Removing file extensions

One of the problems with many websites is that the file extensions are cluttering the URL. This is not necessarily bad from a technical SEO perspective. However, removing them can clean up the URLs and improve the user experience.

The following code will change to

## Redirects to
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteCond %{REQUEST_URI} ^(.+)\.html$
RewriteRule (.*)\.html$ /$1 [R=301,L]

You can do the same thing with by changing each instance of .html to .php in the previous snippet.

Redirect index.php to the root

It is common to have an index.php file as part of most PHP based CMSs. It does not look good and is bad for the user experience. This is a simple fix.

## Redirects the index.php file to the root domain
RewriteRule ^index.php$ [R=301,L]

I have seen this cause an endless redirect loop. If that happens on your server, you should try this method.

## Redirects the index.php file to the root domain
RewriteCond %{THE_REQUEST} ^[A-Z][3,9]\/([^/]+/)*index\.php\ HTTP/
RewriteRule ^(([^/]+/)*)index.php$$1 [R=301,L]

Making URLs lowercase


Some Linux servers don't handle uppercase characters in URLs very well. The server will often return a 502 Bad Gateway response header. In my experience, this is more common with non-physical URL paths. In other words, if is not a part of the physical file system on your web server it is more likely to return an error code.

Google’s John Mueller responded to a question about uppercase characters in URLs.

John Mueller tells us that Google does not care what case you use. However, URLs are case-sensitive. This means that is not the same as This can cause a duplicate content issue.

I personally recommend using lowercase for everything on your web server and website. This allows for the simplest correction of this issue.

Note: In most cases, a canonical tag is enough to correct this issue. However, this does not affect images and other non-HTML documents.

To solve this issue, we need to first determine if there are capital letters. If there are we will redirect to the same URL with all lowercase characters.

For the sake of space, I will not discuss each element of this rule. However, please note that we are storing the variable HASCAPS via the [E] environment variable flag. This allows us to check against it later in our rewrite rule.

## If there are caps, set HASCAPS to true and skip next rule
RewriteRule [A-Z] - [E=HASCAPS:TRUE,S=1]

## Skip this entire section if no uppercase letters in requested URL
RewriteRule ![A-Z] - [S=28]

## Replace single occurrence of CAP with cap, then process next Rule.
RewriteRule ^([^A]*)A(.*)$ $1a$2 [DPI]
RewriteRule ^([^B]*)B(.*)$ $1b$2 [DPI]
RewriteRule ^([^C]*)C(.*)$ $1c$2 [DPI]
RewriteRule ^([^D]*)D(.*)$ $1d$2 [DPI]
RewriteRule ^([^E]*)E(.*)$ $1e$2 [DPI]
RewriteRule ^([^F]*)F(.*)$ $1f$2 [DPI]
RewriteRule ^([^G]*)G(.*)$ $1g$2 [DPI]
RewriteRule ^([^H]*)H(.*)$ $1h$2 [DPI]
RewriteRule ^([^I]*)I(.*)$ $1i$2 [DPI]
RewriteRule ^([^J]*)J(.*)$ $1j$2 [DPI]
RewriteRule ^([^K]*)K(.*)$ $1k$2 [DPI]
RewriteRule ^([^L]*)L(.*)$ $1l$2 [DPI]
RewriteRule ^([^M]*)M(.*)$ $1m$2 [DPI]
RewriteRule ^([^N]*)N(.*)$ $1n$2 [DPI]
RewriteRule ^([^O]*)O(.*)$ $1o$2 [DPI]
RewriteRule ^([^P]*)P(.*)$ $1p$2 [DPI]
RewriteRule ^([^Q]*)Q(.*)$ $1q$2 [DPI]
RewriteRule ^([^R]*)R(.*)$ $1r$2 [DPI]
RewriteRule ^([^S]*)S(.*)$ $1s$2 [DPI]
RewriteRule ^([^T]*)T(.*)$ $1t$2 [DPI]
RewriteRule ^([^U]*)U(.*)$ $1u$2 [DPI]
RewriteRule ^([^V]*)V(.*)$ $1v$2 [DPI]
RewriteRule ^([^W]*)W(.*)$ $1w$2 [DPI]
RewriteRule ^([^X]*)X(.*)$ $1x$2 [DPI]
RewriteRule ^([^Y]*)Y(.*)$ $1y$2 [DPI]
RewriteRule ^([^Z]*)Z(.*)$ $1z$2 [DPI]

## If there are any uppercase letters, restart at very first RewriteRule in file.
RewriteRule [A-Z] - [N]

RewriteRule ^/?(.*) /$1 [R=301,L]

I have found the [DPI] flag is not always needed. However, if it is not included on some server configurations it can return a 502 error.

There are a few other ways to force lowercase URLs. You can use mod_speling. However, this module should set to only correct the URL case, if you have enabled WebDAV on any of your subdirectories. You can read more about mod_speling in the Apache documentation. (Yes... that's mod_speling not mod_spelling.)

If you have access to the httpd.conf file or your host provider will make changes for you, there is another way to do force lowercase URLs with .htaccess.

In this method, we will take advantage of a mod_rewrite directive that seems to be unknown or overlooked by many web developers. The directive we will be using is a RewriteMap. A RewriteMap allows for predefined substitution strings that can be used in a RewriteRule. This is an invaluable tool. The trouble for most webmasters is that the RewriteMap directive cannot be used in <Directory> sections or in .htaccess files. However, you can set it in the server context via the httpd.conf file.

To force lowercase URLs with a RewriteMap we will set the following directive in the httpd.conf file.

RewriteMap lc int:tolower

After that, we will set a RewriteRule in our .htaccess file.

RewriteRule "(.*)" "${lc:$1}" [R]

This is so small and pretty! It makes me happy!

Please note that the lc is the map name, and it is arbitrary. However, it is vital that the map name matches in both the RewriteMap and RewriteRule directives.

The int: in the RewriteMap directive defines an internal map source. tolower is a default internal functions that ships with Apache. It converts the key to lowercase characters.


Some image tools save images with uppercase file extensions by default e.g. .PNG not .png. This can cause these images not to work in some instances. Ensure your image file extensions are lowercase before forcing lowercase URLs on an existing website.

Dynamic URL rewriting

URLs that are created dynamically (i.e. have no correspondence to the server physical file structure) often are not very readable. Creating a rewrite rule to "beautify" the URLs on your site can be very helpful.

If your URL looks like this it is anything but SEO-friendly. We can fix this with a little help from the .htaccess file.

## Rewrites /blog.php?id=243 as /epic-blog-post
RewriteRule ^epic-blog-post$ blog.php?id=epic-blog-post [L]
RewriteCond %{THE_REQUEST} ^[A-Z][3,9] /blog.php?id=243 HTTP/
RewriteRule ^blog.php$ [R=301,L]

It will now look like this That looks a lot better.

.htaccess is not a fix-it file

If your URLs are anything but SEO-friendly trying to fix them with the .htaccess file is not wise. It would be difficult to create redirect rules that logically rewrite URLs with only one redirect. You are better off using your server-side language like PHP or Python to create SEO-friendly URLs in the first place.

There are times when you will need to combine your coding language with .htaccess to achieve the desired result. But, don't use the .htaccess file as a catch-all for URL issues.

Daniel Morell

Daniel Morell

I am a self-taught web developer with a passion for SEO, creating stunning websites, and organic marketing. I am a perfectionist. That means I get obsessed with the nitty-gritty details.

I live in Wisconsin's Fox Valley with my beautiful wife Emily.

Daniel Morell

I am a self-taught web developer, SEO, and builder of things (mostly digital).

I started with just HTML and CSS, and now I mostly work with Python, PHP, JS, and Golang. The web has a lot of problems both technically and socially. I'm here fighting to make it a better place.

© 2018 Daniel Morell.
+ Daniel + = this website.