Skip to Content

Implementing a Personal Website with Hugo, Netlify, Org-mode, and Ox-Hugo

I’ve been reworking my online presence recently, and part of that has been to change how I handle the website at emsenn.net.

I’ve put a fair bit of thought into the generalities of how I want to handle it, but not the specifics. But first, let’s look at the parts of my online identity I have set up right now, that I don’t have any plans to change:

I’m not sure what the full scope of emsenn.net will be, but I don’t plan on it being a dynamic website - nothing I do happens so rapidly that I need to run something like that: I can serve up static resources like HTML and JSON files, that are compiled well in advance of the request.

I like Hugo as my static site generator - it’s powerful enough to meet my needs without being so powerful I get bogged down in different ways to do things.

So, I know that’s one part of my software stack: the layers of software used to accomplish a task.

I also like Netlify as a webhost for static websites - they have an incredible amount of features, that don’t get in the way until you want them there. That’s one end of the stack: publishing on Netlify.

Netlify can source its sites from three Git forges: Gitlab, Github, and Bitbucket. I prefer Gitlab to Github, since Gitlab is funded by users rather than owned by Microsoft, so I’ll use Gitlab as the source for Netlify. And since the Gitlab repo is simply a mirror of the Sourcehut Git forge, which is in turn just a presentation of my local Git repository, that gives me four sequenced tools in the stack: Git to Sourcehut to Gitlab to Netlify.

That still leaves what is in the Git repo unsorted, as well as how it gets built by Hugo. It’s been a bit since I’ve worked with Netlify and Hugo and all this, and I was never that experienced with it when I was, so at this point, I’ll need to start setting things up before fleshing out that part of the stack.

So let’s look at instead what I’m working with as the source code for the website. It’s organized like any of my other projects, under the ~/org/projects/ directory on my server. Here’s what the emsenn-website directory under that looks like:

./
 | README.md
 | emsenn-website.html
 | emsenn-website.org
 | emsenn-website.pdf
 | emsenn-website.tex
 | src/
      | emsenn-website.org
      | build/
	     | content/
	     |        | <site pages go here>
	     | data/
	     |     | <site data goes here>
	     | themes/
	     |       | hugo-personal-website-theme/
	     | config.toml

The only file I edit by-hand is ./src/emsenn-website.org - the other files are tangled from it - extracted from code blocks written into the text of ./src/emsenn-website.org.

Here’s an overview of that document’s sections:

The themes directory contains a directory, hugo-personal-website-theme, which is a Hugo theme that I’m working on - I’ll probably write about it elsewhere, but it’s a Git submodule, so it gets updated by using the git pull command after using git checkout master in the ./src/build/themes/hugo-personal-website-theme/ directory.

So - that’s one early part of the stack - update the themes with Git, and the commands for doing so are included in the “Operations” section.

The other early parts of the stack are exporting the content as Hugo-compatible Markdown, and the data as TOML files.

The former I accomplish with Ox-Hugo and Org-mode’s exporting features. The latter I accomplish with Babel, an Org-mode package that enables the running and extraction of computer code inside Org-mode files.

I think I’ve covered all of how I go from a single source file, src/index.org, to the directory I laid out above.

This whole directory is a Git repository, that as I said, I host on Sourcehut, Gitlab, and Github.

(Actually at the moment Gitlab isn’t working for me so I’m just using the other two.)

I’ve told Netlify to look at the Github version of the repository, and give it the build instructions cd src/build && hugo - apparently these days Netlify knows enough to do things properly from there - I also told it the final website is in ./src/build/public/, but beyond that, no other configuration was necessary.

So, to try and sum it up:

Editorial and License Information

My name is emsenn and I wrote this essay for the benefit of the commons. To the extent possible under law, I have waived all copyright and related or neighboring rights to it. If you're viewing it on a remote server, you're encouraged to download your own copy. Essays like this are made possible with financial support from readers like you. Thank you. To read more of my work and to learn more about me, visit https://emsenn.net