404 page with Publish and GitHub Pages
I have been meaning to try out John Sundell's static site generator Publish for a while now and since holidays during coronavirus pandemic meant more free time than usual I decided to do it. For a Swift enthusiast as myself the tool was a joy to use and I ended up redoing the whole website using it. While most of the things I wanted to do were simple, it took me a bit of research and trial-and-error to figure out how to create my own 404 page.
My website is hosted on GitHub Pages and ultimately it is your hosting solution that prescribes how you should implement your 404 page. GitHub Pages offers a nice documentation page saying you should either have a 404.html or a 404.md page.
First attempt - add 404.md
I first tried simply adding a 404.md page under the Content folder to see what happens. After running publish generate
, a new page index.html
was generated in Output/404
. This is, however, not what GitHub Pages expects. Accessing your.website/404
does indeed show the custom page, however navigating to any other unsupported URL doesn't.
Another downside of this approach is that this way the 404 page gets added to your sitemap.xml
, meaning search engines can use it to index your website, and it could turn up in the search, which is also not what you want for your 404 page.
I decided to try alternatives.
Second attempt - copy generated 404 HTML
My second idea was to add a custom step to publishing the website which will copy the generated 404 page to the output and name it as GitHub Pages expects.
try Website().publish(
...
additionalSteps: [
...
.step(named: "Copy 404 page") { context in
try context.copyFileToOutput(from: "Output/404/index.html",
to: "Output/404.html")
}
...
]
)
This approach also has two flaws. The first one is that it simply does not work, since at the time when this step is executed, the 404 page still hasn't been generated inside the Output
folder.
This could probably be solved by listing all the publish steps manually and executing the copy step as the very last one, but the other flaw remains, namely the 404 page is still listed in sitemap.xml
.
Therefore I quickly abandoned this approach as well.
Third attempt - 404.html in Resources
My final solution turned out to be really simple. I copied the HTML page generated by my first attempt, renamed it to 404.html
and moved it to the Resources
folder. Everything that is in the Resources
folder gets automatically copied to the Output
folder on website generation. The advantage here is that my 404 page is no longer listed in sitemap.xml
and, well, the obvious advantage is that this actually works for GitHub Pages 😄.
One downside is that my 404 page is pretty much hardcoded now and in order to change it I have to dig into the HTML and manually change that. This, however, does not pose a big issue as the page itself is actually pretty small and I do not expect to be changing this page that often anyways so this is what I ended up with.