Clean URLs

By default, Drupal passes path arguments to itself via its internally generated URLs. This results in URLs that look like the following: "http://www.example.com/?q=node/83." This can make URLs hard to read and it also stops many search engines, like Google, from indexing the pages with these URLs.

You can tell Drupal to use "clean URLs", eliminating the "?q=" in internal URLs. Note that this works only for Apache servers which have the LoadModule rewrite_module configured and mod_rewrite enabled in httpd.conf configuration file.

There are two ways to enable URL rewrites in Apache. If there is complete control of the Apache webserver clean URLs should be enabled in the httpd.conf as this has better performance and security.

Warning. Enabling "Clean URLs" if your server is not properly configured can make it difficult to navigate back to administration pages to undo your mistake. If you find yourself in this situation, you can return to the administrative settings page by typing in the URL in the 'non-clean' form: http://www.example.com/?q=admin/settings.

Enabling clean URLs involves three steps:

  1. Enable mod_rewrite for Apache. Please talk to your web host or consult the Apache documentation for mod_rewrite to get more information on how to do this. At a minimum, this will involve making sure that mod_rewrite is enabled for your installation of Apache.

    To test if mod_rewrite is available in Apache2, you can go

    apache2ctl -M

    It will have to be either compiled-in or made available as a loadable module. Generally speaking, you can tell Apache to load the module by including

    LoadModule rewrite_module modules/mod_rewrite.so
    AddModule mod_rewrite.c

    in your Apache configuration file. Be sure to uncomment AddModule mod_rewrite.c.

    Note that this may not be the case for all distributions of *nix operating systems. Consult your distribution's documentation that came packaged with your Apache software. We also recommend disabling multiviews in Apache as they conflict with clean URLs.

  2. You may need to edit your Apache configuration files for your site: the configuration information may be found in httpd.conf, a virtual-host-specific file, or in an .htaccess file in your Drupal installation directory. You can find this file usually in /etc/httpd/conf/httpd.conf or /etc/apache2/apache2.conf. You may use
    find /etc -name httpd

    to find the file if it is located else where in your Unix system.

If you do not have write permissions to these files, and Clean Urls is not working out-of-the-box for you, you may have to ask your sysadmin to help about now. You may still be able to READ these conf files to troubleshoot a little however.

Option A: enable and use .htaccess file over-rides

- Best for shared hosts or multisites, if your provider allows over-ride.

You will also need to have the Allow Override settings in httpd.conf so that local .htaccess commands will be run for your site. If you are changing the .htaccess file in the Drupal distribution you want to set it to

AllowOverride All

to ensure rewrites are enabled.
If it's not already, ensure that
AccessFileName .htaccess

is uncommented also.

Read "Behind the scenes with Apache's .htacces for a thorough review of .htaccess.Here are samples of Apache 2 directives.

Option B: Copy or Include the Drupal-specific settings directly into httpd.conf or the vhost.conf

- Good if you have full control of the server, or at least your conf files. Slightly better for performance.

If you don't use the .htaccess that comes with Drupal you'll need to add or include some rewrite rules into your apache directory directive.
How to include the drupal directives.

Consult the .htaccess file in Drupal for examples of rules.

<Directory /var/www/example.com>
   RewriteEngine on
   RewriteBase /
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
</Directory>

Optional: RewriteBase. Only do this if you are having trouble

The main configuration option which may need to be changed for your site is the RewriteBase. This is usually specified in the Drupal .htaccess file.
For example, if your Apache DocumentRoot is /var/www/ (i.e., /var/www/index.html is what is displayed when you point your browser at http://www.example.com/) and your Drupal installation is installed in the subdirectory /var/www/mysite/, then the RewriteBase should be set to /mysite. In some configurations setting

RewriteBase /

will allow mod rewrite to work.

  • In Drupal

    You should ensure your Drupal site has the path module enabled and the correct permissions set in order to create custom URLs. You can enable the path module in administer >> modules. You can then set permissions to administer URL aliases and create URL aliases. Enable clean URLs on your administration >> settings page. First, see if you can go to the settings page on your site using clean URLs: type in the URL http://www.example.com/admin/settings (where www.example.com is replaced by your hostname). If you get no errors and get to the same page you would have gotten to by clicking on "administer" then "settings" , then you know that you have setup the ReWriteRule rules successfully and can then click the Yes checkbox for "Clean URLs:" . If you have problem you can read the instructions to unset clean URLs. If you If you still have problems with clean URLs you can set the Drupal Settings.php $conf['clean_url']=1;.

  • Note: The standard Drupal installation contains a sample .htaccess file which supports clean URLs. It is easy to miss copying this file, because of the leading "dot".

    Note Regarding MultiViews: The Apache webserver supports a feature called "MultiViews" (more generally: "Content Negotiation"), which allows navigation to your pages without the need for file extensions. For instance, if you had a file called "evaluation.txt", a MultiViews-enabled site could access this file with the URL "example.com/evaluation". While MultiViews can be a handy feature when used knowingly, they can cause problems when Drupal's Clean URLs are enabled. Unless you know what you're doing, you should consider disabling MultiViews if you plan to use the clean URLs feature of Drupal. Be aware that there's a good chance that MultiViews is already disabled, however; it's not enabled in a default Apache installation. Consult the Apache documentation for further information about MultiViews.

    Clean URLs stylesheet problem fixed by setting $base_url

    daggett - May 25, 2007 - 08:21

    In the process of writing a new forum topic elsewhere, I worked out that the solution to the problem, that is to correctly specify $base_url in sites/default/settings.php. (Read this somewhere here, but I can't find it again1).

    When I did the "Clean URL test" at:

    http://proto-saveinskip.org/admin/settings/clean-urls (on my local network)

    ... I lost my ability to retrieve stylesheets and so all the page formatting was lost.

    Unsurprisngly, the problem did not go away when I set the radio button to "Enable clean URLs".

    Having admin access to my server, I preferred not to use .htaccess as shown above because of performance issues. Instead I put equivalent statements into the apache2 virtual host definition file2 (in /etc/apache2/sites-available/saveinskip.org on my Debian Sarge system), the likely most relevant parts of which are shown below3:

    <VirtualHost 192.168.0.6:80>
            ServerName proto-saveinskip.org
            ServerAlias www.proto-saveinskip.org
            ServerAdmin webmaster@localhost

            DocumentRoot /var/www/saveinskip.org
            <Directory /var/www/saveinskip.org>
                    DirectoryIndex index.php index.html
                    Options Indexes FollowSymLinks
                    AllowOverride All
                    Order allow,deny
                    allow from all
             </Directory>
    # ...
            <IfModule mod_rewrite.c>
              Options All
              RewriteEngine on
              RewriteLog /var/log/apache2/saveinskip.org-rewrite.log
              RewriteLogLevel 9
              RewriteCond %{HTTP_HOST} ^www\.proto-saveinskip\.org$ [NC]
              RewriteRule .* http://proto-saveinskip.org/ [L,R=301]

              RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
              RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
              RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]

            </IfModule>
    </VirtualHost>
                                                   

    My $base_url value in settings.php in /var/www/saveinskip.org/sites/default was:

    $base_url = 'http://saveinskip.org';

    ... but, on my local testbed web server, should have been:

    $base_url = 'http://proto-saveinskip.org';

    When it was changed, I was able to see the pages properly formatted again.

    Footnotes

    1. I had checked some of the other "Clean URL" forum discussions on this site but have got no joy in regard to this particular problem. Examples included:

    2. See also Apache 2 configuration of clean URLs on Debian, referred to above.

    3. The first rewrite rule has nothing to do with Clean URLs. it is simply to drop the leading 'www.' in accord with the recommendations of http://no-www.org.)
    The RewriteLog level value of 9 is the most verbose. For a live drupal installation, this, of course, should be 0.

    If you want to try this...

    dman - July 31, 2007 - 12:27

    A variation on this approach, Including the file rather than embedding the rewrite rule, is written up in the handbook here

    I did something similar and encountered no problems with or need for either %{DOCUMENT_ROOT} or $base_URL

    .dan.
    How to troubleshoot Drupal | http://www.coders.co.nz/

    No CSS - stylesheets

    timurek - December 18, 2007 - 23:28

    I solved identical problem today, but another way. After loosing CSS I tried to simply write css file address in the adress bar. Strange thing - I got 500 - internal server error. After some digging I got stylesheets back with simply switching "Aggregate and compress CSS files" OFF on page admin/settings/performance. While it is on, there are NO CSS styles. Then I recognized, that this choice was ON wile I ran Clean-URL test. Now I tried to switch this ON on a site where Clean URLs are already working, and there is no problem.

    Negative thing here is that I cannot switch "Aggregate and compress CSS files" back on ... any hint?

    Seems like a BUG to me ...

    Regards

    Patrik Timura

    Clean URL's on a Drupal 5.7

    tourguide - April 25, 2008 - 16:17

    A sample .htaccess file

    http://cdmug.org/node/174

    -
    tourguide

    Here is what I did to get Clean URLs working on my testbed

    rtivel - August 26, 2007 - 03:25

    Hi,

    Here is what I did to get Clean URLs working on my Apache2 testbed:

    (1) In the Apache httpd.conf file C:\Apache2\conf\httpd.conf --

    Uncomment this: #LoadModule rewrite_module modules/mod_rewrite.so

    --> LoadModule rewrite_module modules/mod_rewrite.so

    (2) Also, change the following statement to read AllowOverride All --

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    # Options FileInfo AuthConfig Limit
    #
    # AllowOverride None
    --> AllowOverride All

    (3) Insure the RewriteBase path is correct in the .htaccess file in the Drupal directory
    (C:\Apache2\htdocs\drupal\.htaccess) --

    # Modify the RewriteBase if you are using Drupal in a subdirectory and
    # the rewrite rules are not working properly.
    RewriteBase /drupal

    Royce Tivel

    This works for my WAMP

    elvisparsley - October 2, 2007 - 15:45

    Thanks rtivel,

    I just needed to alter one thing what rtivel wrote. That one was (3) RewriteBse /drupal-5.2 since my drupal has this name.

    And restart all the Services and then it worked.

    Step 1 needs more clarification, please

    ben_c - September 22, 2007 - 02:32

    Step 1 is vague. What happens after I run "apache2ctl -M"? What feedback do I expect to get?

    "Drupal and the Power of Categories (Taxonomy)"
    http://digitalsolutions.ph/couchkamotereviews/power_drupal_categories

    Clean URLs on temporary URLs

    technivant - September 29, 2007 - 18:26

    When attempting to use clean urls on a server where I only have a temporary url like "webhost.com/~yourusername" (in the case of a new hosting account before DNS changes propagate) I've received the dreaded clean url 404 error. mod_rewrite was triple checked.

    Once domain name began resolving, clean urls started working fine. seems like at least for the handful of servers that I've tried, clean-urls might not work for temporary urls...

    RewriteBase in your .htaccess

    IrDA - October 17, 2007 - 15:50

    You would have to alter the RewriteBase directive in your .htaccess

    RewriteBase in your .htaccess

    mmwebdev - November 17, 2007 - 22:47

    Hi IrDA,

    Thanks for your comment. We too are developing a new Drupal-based site for a client whose existing site is hosted on another server (i.e. we have yet to transfer the DNS until the Drupal site is completed).

    It is worth noting that since we have not transferred the DNS, we are accessing the test site via our server's IP address and the user account subdirectory, i.e.:

    http://111.222.333.444/~myuser/

    Using the RewriteBase directive in Drupal's .htaccess file, we were able to get mod_rewrite to ignore the IP Address portion of the URL and start the rewriting from /~myuser:

    RewriteBase /~myuser

    This worked, so now Clean URLs are working; moreover, the ImageCache module is functioning as well, making our Ubercart catalog pages look much better!

    ** Important note: Once the site's DNS has been switched to our server the RewriteBase /~myuser will no longer be correct. At that point we are assuming that by commenting out the RewriteBase /~myuser will then work. Planning to test soon and will try to update this comment with the results.

    Kim and Chuck

    Thanks for this gem of

    Slim Pickens - February 23, 2008 - 06:46

    Thanks for this gem of information.

    This worked for me on a new webhosting service where I'm migrating several Drupal sites while waiting for DNS transfer.

    My hosting account allows for multiple domains installed in webroot directories, so in my case I used:

    RewriteBase /~myuser/example.com

    or

    RewriteBase /~myuser/example

    depending on how the addon domain directory is named.

    As described above, this is applicable on hosts where you browse to your webroot before DNS propogation with a URL which looks like this:

    http://217.123.456.7/~myuser

    Cheers!

    Don't forget to restart Apache.

    jeffreymcmanus - October 23, 2007 - 23:43

    It's worth mentioning in documentation like this that Apache needs to be restarted when you make these kinds of configuration changes. (I was just futzing with this for an hour without realizing that I needed to restart it for my changes to take effect.)

    When it doesn't work

    jonkun227 - November 12, 2007 - 19:12

    It took me quite a while to figure out why this wasn't working on my installation. (5.2, Westhost.com hosting as a VPS, full access to my httpd.conf & etc.) Clicking the Test url gave me a 404 - not found.

    I checked my httpd.conf and it was loading mod_rewrite. I ran a phpinfo on the server and it showed that mod_rewrite had loaded.

    I ran the clean url test on my installation of Gallery2 (gallery.menalto.com) and it was showing mod_rewrite as functioning correctly.

    I finally figured out that my .htaccess file was missing on the server. I had copied the Drupal installation from inside the Drupal 5.2 folder on my desktop to the web root folder on my server via Transmit (FTP app). But because I don't have hidden files shown in my Finder it didn't copy .htaccess. I enabled the viewing of hidden files in Finder and copied the .htaccess file to the server and suddenly clean URLs work.

    This is obvious to anyone who does a lot of admin work, and anyone who administers their site by command line, but for those of us who only set up this sort of thing a few times a year tend to forget. Hopefully this note helps others in similar positions.

    Incidentally after I figured it out I found this: http://drupal.org/node/163303 , but I thought it made sense to put the writup here on the Clean URLs page where it's easier to find.

    - Jon

    When it doesn't work and your mad about it!

    rzm102 - November 21, 2007 - 14:44

    Thanks Jon, This is what happened to me too. For all of us on *nix based systems where .files hide, this might be the reasons why your rewrites are not working. I extracted my drupal right in my webserver folder, but then moved them to the root webserver folder and moved out the drupal folder. Doing so didn't move the .htaccess. Thanks!

    .htaccess

    momendo - January 9, 2008 - 23:53

    If you're sure mod_rewrite is enabled and working, make sure your .htaccess file is present in the root drupal folder! :-)

    Debian simplest solution !

    DynV - December 19, 2007 - 04:19

    Got Apache2 and Debian ? You're in luck, simply paste this line in your terminal :
    a2enmod rewrite
    SEE I TOLD YOU ! :)

    .htaccess

    DynV - May 7, 2008 - 02:03

    Also don't forget to copy the possibly hidden file .htaccess in the drupal directory.

    FOR godaddy.com users!!

    travel-diaries.info - November 30, 2007 - 22:31

    NOTE!!

    May drupal is not in the first main folder but in subfolder so I was trying to implement RewriteBase /something

    in

    # Rewrite current-style URLs of the form 'index.php?q=x'.
    RewriteBase /something
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

    And it was not working so I was confused but tried to act stupid and deleted the something part and don the exactly as sparkguitar05

    # Rewrite current-style URLs of the form 'index.php?q=x'.
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

    AND IT WORKED :)

    Google doesn't need Clean URLs

    Rogdor - December 1, 2007 - 15:52

    I'd just like to point out that it's misleading to say that Google won't index GET-style URLs, because it has managed that just fine for years, so unless you're going back in time and using search engines from the 90's-- Clean URLs also do not affect page ranking.

    What Clean URLs do bring as a benefit in relation to Google is provide possible keywords, although in the case of pathauto the keywords would already be present on the page itself, since the title of posted content is generally linked anyway.

    The real benefit to Clean URLs is the human readable aspect.

    Other modules do

    hbetts3 - December 18, 2007 - 03:12

    Modules like Imagecache require clean urls to be running

    clean urls with apache alias (not serveralias)

    gonenr - December 22, 2007 - 13:07

    i tried to make clean urls work, but my drupal installation was configured as an alias
    in my apache.
    meaning i had a virtual host with the following configuration:

    servername www.mydomain.com
    documentroot
    /home/sites/somthing
    alias /mydrupal /home/sites/drupal

    the clean urls didn't work untill i gave drupal a virtual host of it's own...

    hope it will be helpful information to someone...

    Gonen.

    re: Clean url's with alias

    thewass - January 10, 2008 - 16:26

    Thanks, Gonen. This was just what my setup needed to get clean URL's working. I found this link helpful for getting a virtualhost up and running.

    http://apptools.com/phptools/virtualhost.php

    It only explains vitualhost in its simplest setup and requires access to the server configuration file so may not work for everyone.

    Just some clarification from my experience

    Rhodizzle - January 20, 2008 - 18:04

    If you have drupal set up in an Alias using WAMP, Clean urls won't work until you make its on VirtualHost. All you have to do is add:

    VirtualHost 127.0.0.1>
    DocumentRoot "yada\yada\wamp\apps\youraliasname"
    ServerName localhost/youraliasname
    /VirtualHost>

    You have to add a < to the two virtualhost entries, Drupal's code pulls it out when I try to post it...hehe

    Before this I was getting a 500 - Unrecognized Request when trying to run the clean urls test to enable them.

    All of this info may have been inferred by earlier posts, but I wanted to state it plainly for anyone else wanting to set up Drupal as an Alias under WAMP.

    UPDATE: this only seems to work for me if using the webserver to browse to it via localhost, I can't get it to work using an external DNS reference or external IP of the web server...

    Server 500 Errors & And Clean URLs

    mgifford - January 31, 2008 - 20:20

    I was running into this problem with the clean url's producing Server 500 errors with a new webhost and and they modified these rules in the .htaccess file:

      # Rewrite current-style URLs of the form 'index.php?q=x'.
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

    inserting the '/' as per:

      # Rewrite current-style URLs of the form 'index.php?q=x'.
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^(.*)$ /index.php?q=$1 [L,QSA]

    and it worked fine. Still trying to figure out what in their apache config might be different from the norm.

    Mike
    --
    OpenConcept | SEO | Tech | Screencasts

    To my understanding in the

    darumaki - January 2, 2008 - 10:09

    To my understanding in the above url example "http://www.example.com/?q=node/83" something like this index.php?q=page-title would be ok in search engine not sure about ?q= but there are people that use index.php?q=page-title and it doesn't effect their search ranking or being indexed by google. From what i heard its only when you have id= then they don't like it but q= is ok

    Apache/2.0.52 (CentOS) will not work with Clean URLs OutOfTheBox

    universeinside - January 28, 2008 - 00:05

    Hello,

    Just adding more casuistic in case is useful:

    I just moved to a VPS without control panel with CentOS4 and Apache 2.0.52 (MySQL database 5.0.54, PHP 5.1.6), and Clean URLs don't work out-of-the-box (I'm using Drupal 5.6).

    It is necessary to edit the Apache config file at /etc/httpd/conf/httpd.conf , and simply modify AllowOverride in these places:

    <Directory />
        Options Indexes FollowSymLinks
        AllowOverride All 
    </Directory>

    Default was AllowOverride None.

    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
        AllowOverride All

    Default was AllowOverride None.

    Save the modifications and it works just fine.

    I hope it helps. After reading the page above I was freaking out with all the many options to check for troubleshooting, but in this case it was as simple as that. :)

    BR,

    Nicolás Amado
    Universe Inside Entertainment S.L.
    http://universeinside.com

    .Universe Inside Consulting
    Designing Comprehensive Digital Experiences for your Brand

    .Universe Inside Studios
    Digital Entertainment Production Studios

    .................................................................

    Apache 2 specific configuration

    Albedo - February 27, 2008 - 07:22

    LoadModule rewrite_module modules/mod_rewrite.so
    AddModule mod_rewrite.c

    Be sure to uncomment AddModule mod_rewrite.c.

    This do not apply for Apache 2 (at least WAMP environment).
    AddModule isn't allowed anymore, hence adding this line could possibly screw your web server up.

    Suggestion: update the page above.

    Clean URLs on Shared Hosts Such as Hostway

    akolahi - March 20, 2008 - 20:33

    To get clean URLs to work on some Shared Hosts such as Hostway, you need to remove '+' from 'Options +FollowSymlinks', thus:
    Options FollowSymLinks

    How I Got Clean URLs Working on a Shared Server

    SurferLeo - April 10, 2008 - 15:43

    Step 1
    Create a .htaccess file in website's root directory and place the following code in it:

    RewriteEngine on RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

    Step 2
    Login to the Admin section of Drupal site and enable the Path module.

    Step 3
    Run a clean URL test and enable the Clean URLs.

     
     

    Drupal is a registered trademark of Dries Buytaert.