Table of Contents

URL Rewriting

By default, DokuWiki does no URL rewriting, resulting in URLs like this:

http://example.com/doku.php?id=page

These URLs are considered ugly and are not indexed well by some search engines.

The solution is to enable URL rewriting, which is disabled by default. DokuWiki supports two methods for URL rewriting through the userewrite option. One utilizes the rewriting cababilities of the webserver; the other one handles rewritten URLs inside DokuWiki. The table below summarizes these options.

Value Info Example URL
0 No URL rewriting is used. This is the default. http://example.com/dokuwiki/doku.php?id=wiki:syntax
1 Rewriting is handled by the webserver. http://example.com/dokuwiki/wiki:syntax
2 Rewriting is done by DokuWiki. http://example.com/dokuwiki/doku.php/wiki:syntax

URL-Rewriting is disabled by default because it requires some additional configuration besides setting the appropriate config option - these configs are discussed below.

Option 1: Webserver

$conf['userewrite'] = 1;

This option produces the nicer URLs but needs a webserver configured to parse rewritten URLs and give DokuWiki the deconstructed URL.

Apache

Rewriting URLs in Apache is done through the mod_rewrite module of Apache 1 or Apache 2. The module is enabled in httpd.conf with the following line (make sure it is not commented out):

LoadModule rewrite_module modules/mod_rewrite.so

The setup of this module is done through so called rewrite rules which can be either defined directly in the server's main config or in a .htaccess file located in DokuWiki's main directory. DokuWiki comes with an .htaccess.dist file which contains the needed rewrite rules for mode 1, but commented. Just copy the file to .htaccess (in the folder that contains doku.php, caveat debian users) and uncomment the lines to enable rewriting.

RewriteEngine on
 
RewriteBase /dokuwiki
 
RewriteRule ^_media/(.*)              lib/exe/fetch.php?media=$1  [QSA,L]
RewriteRule ^_detail/(.*)             lib/exe/detail.php?media=$1  [QSA,L]
RewriteRule ^_export/([^/]+)/(.*)     doku.php?do=export_$1&id=$2  [QSA,L]
RewriteRule ^$                        doku.php  [L]
RewriteCond %{REQUEST_FILENAME}       !-f
RewriteCond %{REQUEST_FILENAME}       !-d
RewriteRule (.*)                      doku.php?id=$1  [QSA,L]

On the line RewriteBase /dokuwiki, you need to replace the /dokuwiki with whatever directory you use in your URL to get to the wiki. Say that your normal (Option 0) URL is http://www.whatever.com/projects/documents/doku.php . You will need to set the above line to RewriteBase /projects/documents. However sometimes this line is not needed at all.

Some Notes

.htaccess files are only honored if Apache's main config allows it. Many default Apache installs don't. To enable them try adding the following to the httpd.conf:

<Directory /path/to/dokuwiki>
  AllowOverride All
</Directory>

Alternatively you may simply specify the rewrite rules mentioned above directly in the httpd.conf:

<Directory /path/to/dokuwiki>
  RewriteEngine on
  ... rewrite rules here ...
</Directory>

You may have to restart Apache for these changes to work.

Some users reported getting a “403 - Forbidden” Error after enabling the rewrite support. Setting the FollowSymlinks option seems to solve the problem:

Options +FollowSymlinks
RewriteEngine on
 
...etc.

The rewrite rules given above will map all non-existing files and directories to the DokuWiki main dispatcher, this may apply to virtual mappings (aliases), too. Eg. some hosters map web access statistics to a virtual /stats directory. To be able to still access thes virtual dirs you need to exclude them in the rewrite conditions. Example:

...
RewriteCond %{REQUEST_FILENAME}       !-f
RewriteCond %{REQUEST_FILENAME}       !-d
RewriteCond %{REQUEST_URI} !^/stats/(.*)$
...

If you're running without a RewriteBase, perhaps because you're hosting under a dedicated VirtualHost, you must modify the rewrite rules accordingly.

RewriteRule ^/_media/(.*)  /lib/exe/fetch.php?media=$1  [QSA,L]
RewriteRule ^/_detail/(.*) /lib/exe/detail.php?media=$1  [QSA,L]
RewriteRule ^/_export/([^/]+)/(.*) /doku.php?do=export_$1&id=$2  [QSA,L]
RewriteRule ^/$ /doku.php [L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule (.*) /doku.php?id=$1  [QSA,L]

Each RewriteRule stanza must have a leading slash included, or Apache will return a 400 response code.

IIS

ISAPI Rewrite Lite

IIS doesn't come standard with a rewrite module. I used ISAPI Rewrite Lite (free) successful with these rewrite rules (see the file C:\Program Files\Helicon\ISAPI_Rewrite\httpd.ini):

# Dokuwiki rules
# Fix RSS Feeds
RewriteRule ^(/wiki/)feed.php $1/feed.php [I,L]
RewriteRule ^(/wiki/)feed.php\?(.*) $1/feed.php\?mode=$2&$3 [I,L]
 
RewriteRule ^(/wiki/)_media/(.*)\?(.*) $1lib/exe/fetch.php\?media=$2&$3 [I,L]
RewriteRule ^(/wiki/)_detail/(.*)\?(.*) $1lib/exe/detail.php\?media=$2&$3 [I,L]
RewriteRule ^(/wiki/)_detail/(.*) $1lib/exe/detail.php\?media=$2 [I,L]
RewriteRule ^(/wiki/)_export/([^/]+)/(.*) $1doku.php?do=export_$2&id=$3 [I,L]
 
RewriteRule (/wiki/) $1doku.php [I,L]
 
RewriteRule ^(/wiki/)\?idx=(.*) $1doku.php\?idx=$2 [I,L]
RewriteRule ^(/wiki/)lib/(.*) $1lib/$2 [I,L]
RewriteRule ^(/wiki/)(.*)\?do=(.*) $1doku.php\?id=$2&do=$3 [I,L]
RewriteRule ^(/wiki/)doku.php\?id=(.*) $1doku.php\?id=$2 [I,L]
RewriteRule ^(/wiki/)(.*) $1doku.php\?id=$2 [I,L]
 
# this rule fixes a problem to see the old revisions
RewriteRule ^(/wiki/)(.*)\?(.*) $1doku.php\?id=$2&$3 [I,L]
 
# Diff still broken unless none is selected under 'use nice URL' options. You can still enter and link to nice URLs but the Dokuwiki program will use normal naming.

For all lines with RewriteRule ^(/wiki/), you need to replace the (/wiki/) with whatever directory you use in your URL to get to the wiki. Say that your normal (Option 0) URL is http://www.whatever.com/projects/documents/doku.php . You will need to set the above line to ^(/projects/documents/).

Ionics Isapi Rewrite Filter

It is also possible to use Ionics Isapi Rewrite Filter, which is free and open-source.

IterationLimit 1
 
# QSA is not supported, fix it
RewriteCond %{REQUEST_FILENAME}       !-f
RewriteCond %{REQUEST_FILENAME}       !-d
RewriteRule (.*)\?(.*) $1&$2
 
RewriteRule ^/_media/(.*)             /lib/exe/fetch.php?media=$1   [QSA,L]
RewriteRule ^/_detail/(.*)            /lib/exe/detail.php?media=$1  [QSA,L]
RewriteRule ^/_export/([^/]+)/(.*)    /doku.php?do=export_$1&id=$2  [QSA,L]
RewriteRule ^/$                       /doku.php                     [QSA,L]
# infinite redirect fix
RewriteCond %{REQUEST_FILENAME}       !-d
RewriteRule ^/(.*)/$                  /doku.php?id=$1               [QSA,L]
# end fix
RewriteCond %{REQUEST_FILENAME}       !-f
RewriteCond %{REQUEST_FILENAME}       !-d
RewriteRule ^/(.*)                    /doku.php?id=$1               [QSA,L]

Lighttpd

This is an improved version of one suggested for lighty.

url.rewrite-once = (                                                                                                   
                    "^(/|index.php)?$" => "/doku.php",                                                                     
                    "^/lib/(.*)/?$" => "/lib/$1",
                    "^/_media/(.*)?\?(.*)$" => "/lib/exe/fetch.php?media=$1&$2",
                    "^/_media/(.*)$" => "/lib/exe/fetch.php?media=$1",
                    "^/_detail/(.*)?\?(.*)$" => "/lib/exe/detail.php?media=$1&$2",
                    "^/_detail/(.*)?$" => "/lib/exe/detail.php?media=$1",
                    "^/_export/([^/]+)/(.*)$" => "/doku.php?do=export_$1&id=$2",
                    "^/(?!doku.php|feed.php|robots.txt|sitemap.xml.gz)(.*)\?(.*)/?$" => "/doku.php?id=$1&$2",
                    "^/(?!doku.php|feed.php|robots.txt|sitemap.xml.gz|lib|_media|_detail|_export)(.*)/?$" => "/doku.php?id=$1",
                  )

Here is a version from darix in irc.freenode.net #lighttpd which fixed many errors such as optional trailing slash etc…

$HTTP["host"] == "wiki.example.org" {
    server.document-root = "/srv/www/vhosts/example.org/wiki/htdocs"
    # DO NOT FORGET THE TRAILING SLASH HERE
    # var.wiki_base = "/wiki/"
    # var.wiki_base = "/"
    var.wiki_base = "/"
    #
    $HTTP["url"] =~ "^" + var.wiki_base {
      #RewriteRule ^$          doku.php  [L]
      #RewriteRule ^index.php$ doku.php
      index-file.names = ("doku.php")
    }
    url.rewrite = (
      #
      "^" + var.wiki_base + "lib/.*$" => "$0",
      #RewriteRule ^_media/(.*)              lib/exe/fetch.php?media=$1  [QSA,L]
      #RewriteRule ^_detail/(.*)             lib/exe/detail.php?media=$1  [QSA,L]
      #RewriteRule ^_export/([^/]+)/(.*)     doku.php?do=export_$1&id=$2  [QSA,L]
      #RewriteRule (.*)                      doku.php?id=$1  [QSA,L]
      #RewriteRule ^index.php$               doku.php
      "^" + var.wiki_base + "_media/(.*)"          => var.wiki_base + "lib/exe/fetch.php?media=$1",  #  [QSA,L]
      "^" + var.wiki_base + "_detail/(.*)"         => var.wiki_base + "lib/exe/detail.php?media=$1", #  [QSA,L]
      "^" + var.wiki_base + "_export/([^/]+)/(.*)" => var.wiki_base + "doku.php?do=export_$1&id=$2", #  [QSA,L]
      "^" + var.wiki_base + "doku.php.*"           => "$0",
      "^" + var.wiki_base + "(.*)\?(.*)"           => var.wiki_base + "doku.php?id=$1&$2",           #  [QSA,L]
      "^" + var.wiki_base + "(.*)"                 => var.wiki_base + "doku.php?id=$1",              #  [QSA,L]
    )
}

If darix's code produces errors when displaying images or the feed.php, try the following variation. It is a contamination of the first two examples:

# rewrite for dokuwiki, example 3
$HTTP["host"] == "wiki.example.org" {
    server.document-root = "/srv/www/vhosts/example.org/wiki/htdocs"
    # DO NOT FORGET THE TRAILING SLASH HERE
    var.wiki_base = "/dokuwiki/"
    #
    $HTTP["url"] =~ "^" + var.wiki_base {
    index-file.names = ("doku.php")
    }
    url.rewrite = (
      "^" + var.wiki_base + "lib/.*$"              => "$0",
      "^" + var.wiki_base + "_media/(.*)?\?(.*)$"  => var.wiki_base + "lib/exe/fetch.php?media=$1&$2",
      "^" + var.wiki_base + "_media/(.*)$"         => var.wiki_base + "lib/exe/fetch.php?media=$1",
      "^" + var.wiki_base + "_detail/(.*)?\?(.*)$" => var.wiki_base + "lib/exe/detail.php?media=$1&$2",
      "^" + var.wiki_base + "_detail/(.*)?$"       => var.wiki_base + "lib/exe/detail.php?media=$1",
      "^" + var.wiki_base + "_export/([^/]+)/(.*)" => var.wiki_base + "doku.php?do=export_$1&id=$2",
      "^" + var.wiki_base + "doku.php.*"           => "$0",
      "^" + var.wiki_base + "feed.php.*"           => "$0",
      "^" + var.wiki_base + "(.*)\?(.*)"           => var.wiki_base + "doku.php?id=$1&$2",
      "^" + var.wiki_base + "(.*)"                 => var.wiki_base + "doku.php?id=$1"
    )
}

Nginx

Nginx is a very fast and stable httpd, see more about nginx project, and an English wiki. In the following example, our server root is /var/www, and we extract dokuwiki to /var/www/dokuwiki.

    server {
        listen       80;
        server_name  _ *;
        port_in_redirect off;
        optimize_server_names off;

        access_log  /var/log/nginx/localhost.access.log;

        rewrite ^(/dokuwiki/)_media/(.*) $1lib/exe/fetch.php?media=$2 last;
        rewrite ^(/dokuwiki/)_detail/(.*) $1lib/exe/detail.php?media=$2 last;
        rewrite ^(/dokuwiki/)_export/([^/]+)/(.*) $1doku.php?do=export_$2&id=$3 last;

        location / {
            root   /var/www;
            index  index.html index.htm index.php;
        }

        location /dokuwiki/ {
            if (!-f $request_filename) {
                rewrite ^(/dokuwiki/)(.*)?(.*)  $1doku.php?id=$2&$3 last;
                rewrite ^(/dokuwiki/)$ $1doku.php last;
            }
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /var/www;
        }

        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:8888;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www$fastcgi_script_name;
            include        /etc/nginx/fastcgi_params;
        }
    }

Notes

Nginx has complete support for fastcgi, please reference nginx fastcgi document to fit your setup.

The last keyword of rewrite rules before location setup make sure that rewrite only happens once. You should replace all /dokuwiki/ appeared above to you wiki directory relative to web server root directory.

Option 2: DokuWiki

$conf['userewrite'] = 2;

This option won't need any webserver setup. However it relies on the PATH_INFO feature of the CGI standard as implemented by Apache. IIS is known not to work with this setting1).

Using apache's Alias directive with this option can lead to severe headaches and broken wiki!

Clean PHP session ID

Despite using “clean” URLs you may encounter a “DokuWiki” parameter in the URL looking like this:

PHP session ID:

http://example.com/example?DokuWiki=c81a95369a66576982119e2a60b557a5

This parameter is the PHP session ID and gets added by PHP automatically. It's completely unrelated to rewriting. To avoid it you can force PHP to always use cookies for sessions by setting the session.use_only_cookies option for PHP.

This usually done in the php.ini config file (when using a web hoster check their support page if and how you can edit these values):

session.use_only_cookies=1

If session id still work try:

session.use_trans_sid=0

When you PHP is used as Apache module you may be able to tweak these values using a .htaccess file using the following syntax:

php_flag session.use_only_cookies on
php_flag session.use_trans_sid off
My problem was that my session.cookie_domain was incorrectly set (I'm doing virtual hosting, and the domain name was incorrect). I added
php_value session.cookie_domain www.my.domain.com

to the appropriate virtualhost in my httpd.conf (though .htaccess would probably work just as well), and the polluted URLs disappeared. Also, if you can't get to your php.ini or apache config, you should be able to use ini_set('PHP variable', 'value'); to the same effect (it seems that conf/local.php is a good place to put this, as the file is included before the session is started).

In my case, FastCGI was causing session IDs to appear. Disabling it removed them.

DREAMHOST:

If still everything fails, comment out the following lines in inc/init.php:

//    session_name("DokuWiki");
//    session_start();

Discussion