From .md to the Edge: Deploying this Hugo Site on Cloudflare Pages

Hugo has been powering this site for a while now. It lets me write Markdown, run a build, and get a website. No database, no backend, no server sitting somewhere waiting for me to accidentally break it.

That is exactly the kind of arrangement I like.

This site, arpitjn.com, is a collection of notes about things I learn, build, break, and occasionally fix. The source code lives on GitHub, and the site is deployed on Cloudflare Pages.

Why Hugo? #

The notes are mostly text, images, and a few scripts. They do not need a database or a complicated application server. They need to turn Markdown files into HTML and serve the result to people on the internet.

Hugo does the first part very well.

The repository is fairly simple:

  • Markdown notes live in content/notes.
  • hugo.toml contains the site configuration.
  • The theme is included as a Git submodule.
  • Static files such as favicons live in static.
  • Hugo generates the final website in public.

There is something satisfying about a website that can be rebuilt from a folder and a command. It feels less like operating infrastructure and more like assembling furniture, except the furniture has front matter.

Moving to Cloudflare Pages #

Cloudflare Pages was a natural fit for this site. The repository already contains everything Hugo needs to build the website. Pages just needs to run Hugo and serve the generated files.

The general setup is pleasantly uneventful:

  1. Connect the GitHub repository to Pages.
  2. Choose the production branch.
  3. Use Hugo as the build command.
  4. Set public as the build output directory.
  5. Deploy.

Cloudflare’s Hugo deployment guide documents the same basic setup.

During the first deployment, the build failed because Pages was using an older Hugo version than the one I was using locally. I found the fix in the Cloudflare Community thread Hugo site does not build correctly: set the HUGO_VERSION environment variable in the Pages project. Shout-out to the Cloudflare Community for preventing me from spiraling for hours over a theme that was perfectly innocent.

Once the project is connected, publishing a note is just a normal Git workflow. A Markdown file gets written, committed, pushed, and then the build does its thing.

A commit becoming a deployment still feels slightly magical. It is also much safer than manually uploading files and then wondering which version of index.html is currently online.

The domain migration #

This site originally used a domain registered with Namecheap. After about a year, the domain moved to Cloudflare as well. Namecheap refused to give me a discount on renewal, which was ..a teeny bit heartbreaking. :(

However, the transfer itself was not particularly dramatic, which is probably the nicest thing one can say about a migration. There was some waiting, some verification, and the usual DNS-related activity that makes everyone stare at a dashboard as if it contains the secrets of the universe.

After the move, Cloudflare handled both the domain and the Pages deployment. This site continued to be available at arpitjn.com, instead of making visitors remember a temporary pages.dev address.

During the custom-domain setup, existing DNS records got in the way and the domain refused to cooperate. The Cloudflare Community thread Continuous Error with Custom Domain Configuration pointed me to the fix: remove the conflicting records and add the hostname from the Pages project’s Custom domains section. Shout-out to the community for preventing me from adding yet another DNS record and spiraling for hours yet again.

This distinction is worth noting: moving a domain registrar and connecting a custom domain to Pages are related, but they are not exactly the same operation. Cloudflare’s custom domain documentation explains the DNS and nameserver requirements for using an apex domain such as arpitjn.com.

Screenshot from the custom-domain migration to Cloudflare

What I like about the setup #

The best thing about this deployment is that there is not much to think about after setting it up.

The site is static. Hugo builds it, Pages serves it, and Git stores the source. I can focus on writing instead of maintaining servers and mysterious files named final-final-v3.

This site is not complicated, and that is the point. A Markdown file can become a real website on a real domain with a repository and a build. For now, this site will keep hosting notes and documenting things learned the long way. The source is on GitHub, and the finished site is at arpitjn.com.