Redirect URLs with .html or .php in it to the ones without it

I have directive:

try_files {path}.php {path}.html {path}

so that /about.html can be loaded using URL /about
but I would also like to redirect(browser redirect, not internal rewrite) /about.html to just /about
(delete PHP/HTML extension from URL)
How to achive that, any help is appreciated

Do you only want to redirect requests where a file exists on disk, or all requests with those extensions?

To redirect all requests even if the file doesn’t exist on disk:

@stripExtensions {
	path_regexp strip (.*)\.(html|php)
}
redir @stripExtensions {http.regexp.strip.1}

FYI, in Caddy v2.1, this can be shortened to (v2.1 beta 1 is out and you can try it now):

@stripExtensions path_regexp strip (.*)\.(html|php)
redir @stripExtensions {re.strip.1}

If you want to first check if the file exists on disk before redirecting:

@stripExtensions {
	path_regexp strip (.*)\.(html|php)
	file {
		try_files {path}.php {path}.html
	}
}
redir @stripExtensions {http.regexp.strip.1}

In Caddy v2.1 this can also be shortened to:

@stripExtensions {
	path_regexp strip (.*)\.(html|php)
	file {path}.php {path}.html
}
redir @stripExtensions {re.strip.1}
3 Likes

Thank you so much for both

@francislavoie Just a note, every regex in your answer should use number 1 not 0

I ended up using this:

@stripExtensions {
	path_regexp strip (.*)\.(html|php)
	file {
		try_files {path}
	}
}
redir @stripExtensions {http.regexp.strip.1} permanent
1 Like

Ah yeah, you’re right - my mistake. I updated my post above :+1:

1 Like

And also you have to use either try_files {http.regexp.strip.1}.php {http.regexp.strip.1}.html in the file directive or even better like I wrote in my reply

just use try_files {path} it’s simpler and it works the same way

Ah yeah, right. I was confusing myself between requests like /foo and /foo.html and how each is handled. :+1:

You can actually simplify it even further then:

@stripExtensions {
	path_regexp strip (.*)\.(html|php)
	file
}
redir @stripExtensions {http.regexp.strip.1}

The file matcher implicitly does try_files {path} if you don’t give it any options :smile:

Also FYI if you try to use regexp results inside the same matcher, you might get inconsistent results. The order the matchers will run is kinda random. It would just be luck based whether they run in the correct order.

Thank you, I didn’t know that, and I’ll copy that to my Caddyfile, it does look nicer.

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