za/ch

baseUrl and publishDir in Hugo and Cloudflare Pages

TL;DR to use a different base url, in addition to modifying baseUrl, I also had to change publishDir = 'public/ch'. This fixes Cloudflare Pages but breaks the local development version that hugo server runs, so I also made separate config files development and production.

The problem

I wanted my website to be hosted on resmer.co.za/ch so it spells my name at the end. The Hugo docs are pretty clear on how to do this, just set baseUrl in the config to whatever you want the base URL to be.

Unfortunately, when I set baseUrl in the Hugo config and deployed it with Cloudflare Pages, the CSS and JavaScript didn’t load. The stylesheet and script links generated by Hugo were pointing to resmer.co.za/ch/css/ and resmer.co.za/ch/js/, but the actual files were in resmer.co.za/css and resmer.co.za/js. It took a lot of googling and frustration to figure this out, so here is my solution for the next weary traveller.

What is Cloudflare Pages actually doing when it builds a Hugo site?

Cloudflare’s deployment process seems to be:

Hugo’s built-in development server does something automagically to serve the files from /ch/ without actually putting them in a directory called ch. Cloudflare pages doesn’t have any way that I could find to do something similar with the routing, so I need to actually modify what folder that files are being copied into on the server. There is also no setting in Cloudflare to change that directly (other than, like, making the build command hugo && mkdir ch && cp * ch/ or something).

I guess Hugo is assuming that other servers might also do the same thing they do with routing, so baseUrl doesn’t change where the files go, just how the links are constructed. publishDir is what I need!

You still also have to set baseUrl, or the files would be in the ch directory but the links on rendered pages won’t point there. This is confusing because setting both baseUrl and publishDir breaks the local hugo server version (the files end up available at links like resmer.co.za/ch/ch/css/main.css, note the /ch/ch/). I split my config into dev and production so I could still run the local version.

Counterintuitively, I didn’t have to change any of the Cloudflare Pages settings to fix this, but I sure tried. Here’s what they are, and why they don’t work, since they sound so tempting.

Extra stuff

This q and a helped me figure it out (even though the accepted solution is something else): https://discourse.gohugo.io/t/change-output-folder-path-in-public-folder/18636

I’m using Hugo 0.136.3 locally and in production, (set using the HUGO_VERSION environment variable in Cloudflare). Maybe something has changed and if I used the default version Cloudflare suggests it would work correctly, but I wanted to use a newer version than that.

Tags: