This might sound slightly silly, but I’m currently writing this in raw HTML, after finally configuring a copy of NGINX to work properly with (almost) how I want it.
You probably didn’t notice it, but if this is working right, no pages should have any .html
in the path, and the path for some pages should end in /
and some should not have that trailing slash.
For some reason, this is extremely hard to configure in NGINX (or I’m just missing something incredibly obvious, that is always a thing that can happen), and I am absolutely not happy with the config, but I might as well put it here in-case anyone else has a similar desire to me.
# NOTE: both of these blocks go into a http {} block.
map $uri $uri_noslash {
~(.+[^\/]) $1;
}
server {
# NOTE: I'm omitting the listen and server_name stuff here because that isn't relevant.
location / {
try_files $uri $uri/ $uri.html =404;
index index.html;
location ~ .+\/$ {
index index.html;
try_files $uri/index.html @redirect_to_no_slash;
}
location ~ (^.+\.html$)|(index$) {
if ($request_uri != "/") {
return 404;
}
}
}
location @redirect_to_no_slash {
return 301 $uri_noslash;
}
# NOTE: again this omits the rest of the server {} block...
}
# NOTE: also this omits the rest of the HTTP block, this should be part of your existing/default NGINX config somewhere.
Well, the goal is “just” to get it so that I can have pages with or without a trailing slash, and hide the file extension of HTML files and also hide the index files, and if a browser (either through manual entry or through a link) goes to a page using one but expecting the other (in either direction), it redirects to the correct one.
The why of THAT boils down to me preferring to hide the implementation details where possible, whilst also allowing for relative URLs in my hand-written HTML files to work. Essentially, in blog/
, any relative links will start with blog/
, regardless of if it’s in blog/
or in blog/nginx-troubles
. When it works it’s pretty neat!
It also looks nice and orderly when it works.
The small flaw is also the thing that has been stressing me out the whole time (if you ignore the config being unpleasant to look at).
Essentially, if the pages you are trying to visit actually exists, everything will be fine. Otherwise, a small bit of a “jank” happens when you try to visit blog/non-existent-page-for-example/
, as it will try to redirect you to blog/non-existent-page-for-example
, which as it doesn’t exist, will do a traditional 404 not found error, which thankfully is the correct error. It’s just a shame that it had to redirect first, as otherwise this would be perfect.
Sort-of! From my reading of the documentation, it feels like this is the thing that I’m not really supposed to be doing with NGINX. Oops. So, it might have been better if I switched web-server, or wrote something myself that I could plug into NGINX (there’s many scripting options or other things I could have experimented with). It was really just a combination of reaching “good-enough” whilst not wanting to completely change my server that made me stop at this point.
In the end, I’ve basically given myself a bit of tech-debt that I may end up cursing myself for in the future. In fact, as of writing this, I’ve only got this running on a test server running on my laptop, not on my actual server with its actual config. Things might go wrong there! (Though, if you’re reading this and I didn’t come in to correct myself, then it probably worked well enough, we’ll see, eh?)
So I wrote most of this on the 17th, and it's now the 20th (just for this section under this subheading).
I was able to translate the config pretty easily from my laptop test environment to my server / “production” (lol) environment.
There was one difference, though… instead of the map $uri $uri_noslash { ~(.+[^\/]) $1; }
thing, I just replaced location @redirect_to_no_slash { return 301 $uri_noslash; }
with;
location @redirect_to_no_slash {
rewrite (.+[^\/]) $1 permanent;
}
…which basically does the same thing but with less lines overall, which I’m happy with.
Anyway, back to past me.
Yeah, this was the reason why I even made this change. I wanted to setup my blog in a way where the layout of the URIs made sense to me. That’s it, and it was almost fitting that the troubles I had doing this were something I could write down as the first entry.
Of course, there’s more to do to really make this “work” and be easy to write, and I may experiment with server-side-includes or HTML embed tags, but... for now hand-written HTML to explain a somewhat janky NGINX config is what I’ll be using.
Whilst I have no illusions of this being popular or anything, you can contact me if you have any thoughts or corrections, or if you have money burning in your pocket and you feel this helped you, there’s always the option to give me money if you’d like.
Regardless, if you’ve made it this far, thanks for reading!