Customizing Nginx Autoindex Pages: HTML Styling and Template Overrides


2 views

By default, Nginx generates basic HTML pages when autoindex is enabled with autoindex on; in your server configuration. While functional, these pages often lack visual appeal and customization options.

The main limitation is that Nginx doesn't provide direct template modification through configuration directives. However, we have several effective workarounds:

Nginx 1.7.9+ introduced limited formatting control through the $autoindex_format variable:


location /files/ {
    autoindex on;
    autoindex_format html;
    # For JSON output:
    # autoindex_format json;
    
    # Customize output filename
    add_before_body /custom/header.html;
    add_after_body /custom/footer.html;
}

For complete control, we can use Nginx's SSI (Server Side Includes) or subrequests:


location /files/ {
    autoindex on;
    
    # Custom header/footer
    add_before_body /autoindex/header.html;
    add_after_body /autoindex/footer.html;
    
    # CSS styling
    location ~* \.css$ {
        add_header Content-Type text/css;
    }
}

For advanced implementations, consider this Lua-based solution (requires ngx_lua module):


location /custom-index {
    content_by_lua_block {
        local template = require "resty.template"
        local res = ngx.location.capture("/files/", {args = ngx.req.get_uri_args()})
        
        if res.status == 200 then
            template.render([[
                <!DOCTYPE html>
                <html>
                <head>
                    <title>Custom File Index</title>
                    <link rel="stylesheet" href="/styles/custom.css">
                </head>
                <body>
                    <h1>My Files</h1>
                    <div class="file-list">
                        {% for file in files %}
                        <div class="file-item">
                            <a href="{{file.url}}">{{file.name}}</a>
                            <span class="size">{{file.size}}</span>
                        </div>
                        {% end %}
                    </div>
                </body>
                </html>
            ]], {files = parse_autoindex(res.body)})
        end
    }
}

When implementing custom autoindex solutions:

  • Cache generated pages when possible
  • Minimize filesystem operations
  • Consider using XSLT for XML transformations if dealing with large directories

For complex cases, you might want to:

  1. Generate static index pages during deployment
  2. Use a separate application to serve directory listings
  3. Implement a client-side solution that fetches directory data via API

Nginx's built-in autoindex feature generates directory listings automatically when no index file (like index.html) is present. By default, it produces a functional but bare-bones HTML output.

While Nginx doesn't support direct template modification, we can leverage the autoindex module's directives for customization:


location /files/ {
    autoindex on;
    autoindex_format html;
    autoindex_exact_size off;
    autoindex_localtime on;
    add_after_body /custom/footer.html;
}

For complete control, consider these approaches:

1. Custom CSS Injection:


location /downloads/ {
    autoindex on;
    add_header Content-Style-Type "text/css";
    add_header Link "</custom.css>; rel=stylesheet; type=text/css";
}

2. Full Template Replacement:


location /special/ {
    autoindex off;
    rewrite ^ /custom-index-handler last;
}

location = /custom-index-handler {
    internal;
    root /path/to/templates;
    try_files /autoindex-template.html =404;
}

Here's a complete working configuration with custom styling:


server {
    listen 80;
    server_name files.example.com;
    
    location / {
        autoindex on;
        autoindex_format html;
        
        # Custom styling
        add_before_body /autoindex/header.html;
        add_after_body /autoindex/footer.html;
        
        # JSON alternative
        location ~* \.json$ {
            autoindex_format json;
        }
    }
    
    location = /autoindex/header.html {
        internal;
        alias /etc/nginx/templates/header.html;
    }
    
    location = /autoindex/footer.html {
        internal;
        alias /etc/nginx/templates/footer.html;
    }
}

For more complex needs:

  • Use FancyIndex with Nginx: https://github.com/aperezdc/ngx-fancyindex
  • Implement a Lua handler (requires ngx_lua module)
  • Create a proxy pass to a custom application