Is it possible to customize the page served by `file_server browse`?

1. Caddy version (caddy version):

v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=

2. How I run Caddy:

Idk what to write here. I generate my site using Cobalt, I use LetsEncrypt (certificates obtained via a standalone Certbot on my router, then scped to my server), TLS1.3 only, secure HTTP headers as recommended by OWASP and others… My domain is

a. System environment:

I run Caddy inside Minijail in a Vpid Linux VM. It is started by Runit, however, I use a small C program instead of a shell script, as for some reason the service wouldn’t reliably start with any shell other than Zsh.

b. Command:

minijail0 -lnv -b /etc/resolv.conf -u caddy -g fantasycookie17 -C /srv/caddy /caddy run

c. Service/unit/compose file:

#include <stdio.h>
#include <unistd.h>

int main() {
    char* argv[] = { "-l", "-n", "-v", "-b", "/etc/resolv.conf", "-u", "caddy", "-g", "fantasycookie17", "-C", "/srv/caddy", "/caddy", "run", NULL };
    char* envp[] = { "HOME=/home", NULL };
    execve("/usr/bin/minijail0", argv, envp);
    return 1;

d. My complete Caddyfile or JSON config:

        http_port 8080
        https_port 8443
        admin off
} {

        root * /htdocs/

        import /headers

        tls /tls/ /tls/ {
                protocols tls1.3

        encode zstd gzip

        file_server browse

} {

        root * /htdocs/

        import /headers

        tls /tls/ /tls/ {
                protocols tls1.3

        encode zstd gzip

        file_server browse



header {

        # Security
        Strict-Transport-Security "max-age=63072000; includeSubDomains"
        X-Frame-Options DENY
        X-Content-Type-Options nosniff
        Content-Security-Policy "default-src 'none'; style-src 'self'; img-src 'self'; base-uri 'self', require-trusted-types-for 'script'"
        X-Permitted-Cross-Domain-Policies none
        Referrer-Policy no-referrer
        Feature-Policy "accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; usb 'none'"
        Expect-CT "max-age=31536000, enforce"

        Tk N


route {
        header Cache-Control "max-age=600"
        header /static/* Cache-Control "max-age=86400"

3. The problem I’m having:

I want Caddy to apply my own CSS, and perhaps also use a different layout for the archive. Thus, customizing the HTML of the file_server browse directive would be nice, however, the documentation doesn’t mention how to do that, afaict, if it is possible at all.

4. Error messages and/or full log output:


5. What I already tried:

Nothing so far, as I have no idea what I could do to achieve what I want to. However, the alternative would be to somehow generate these archives with Cobalt, or something like that, or having to deal with not having a custom style.

Yep, if you look at the syntax for the file_server directive, you can specify a template file for browse if you specify it as a subdirective.

file_server {
	browse my_template_file.html

The default template Caddy uses is found at the link below, embedded in the source code (i.e. the bits between the backtick characters). You can copy this and make the appropriate changes you need.


Thanks. I must have somehow overlooked that option. This should solve it then.


This topic was automatically closed after 30 days. New replies are no longer allowed.