Extension-less Configuration for nginx

Many web designers want their URLs to appear in a particular format on the browser’s address bar. On this website we use pretty permalinks with a trailing slash.

But this article describes an nginx configuration that supports URLs without a trailing slash or a file extension. So the URL /foo might refer to a directory index (/foo/index.php), a static file (/foo.html) or a script (/foo.php), whichever is located first within a predefined order.

There are many ways to achieve this. However, complex nginx configurations rapidly become unwieldy with obfuscated redirection loops and unpredictable edge conditions.

The following configuration is simple, easy to understand, and therefore easily adapted to specific requirements.

upstream php {
  server unix:/var/run/php5-fpm.sock;
# server;
server {
  root /path/to/root;

  location / {
    try_files     $uri $uri.html $uri/index.html @php;
  location @php {
    try_files     $uri.php $uri/index.php =404;

    include       fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_pass  php;
  location ~* ^(.*)\.php$ { return 301 $1; }

It avoids the use of $uri/ within the try_files directive, as this causes an external redirect which adds a trailing slash to the URL. It also avoids the use of the index directive, but only because these rules are explicitly stated within the try_files directive.

Further Reading

nginx documentation