How I publish project demos alongside my Hugo blog

Date: 2019-01-21 | hugo | static | static-site | tutorial |


What is Hugo?

Hugo is an open source static-site generation engine. If you've ever used Jekyll before, the basics are much the same. Basically it takes in content organized in a specific folder structure and pipes (or generates) them into output HTML / JS files as prescribed by the configured template. This allows you to create your content without worrying about the output "cruft" required to make your site look cohesive while maintaining the ability to easily customize the look and feel of your site all in one place.

How I use Hugo and hosting arbitrary static sites

Overall it's a pretty cool paradigm. I currently use Hugo to support two of my primary sites HAMY.BLOG and HAMY.LABS. Feel free to poke around if you want but we're most interested in how I use it for Labs today.

Labs hosts content concerning my technical explorations in the process of "building dope shit" - my self-prescribed public mantra. Though it was cool to write about my projects, I also wanted a way to show them off when it made sense.

To do so, I leveraged Hugo's ability to host arbitrary static content to publish these projects.

See moon-eye and Geolog for examples.

The solution

So as I mentioned, Hugo supports the publishing of arbitrary static content to your website. So basically what I did was figure out the output url my projects would be hosted at and create a subpath in the static folder that mapped to that outputUrl + "demo".

Note that this is the same mechanism you'd use if you wanted to host images with an idiomatic url.

So what exactly does this mean? Before we can get into that, it'll be useful to have a brief overview of how Hugo's directory structure works.

Essentially the directory structure looks like:

  • archetypes // templates for metadata
  • content // where your main content goes
    • posts
    • projects
    • whateverElseIWant
  • public // this is the output folder for all build artifacts, so html/css/etc
  • static // this is the folder Hugo will just publish as-is to the corresponding directory
  • themes // this is where your style templates go
  • config.toml // config obvs

I've bolded the top-level folders I think are most important for this tutorial - content and static. The content folder holds your primary content (like the text of this post) while static will hold arbitrary files that can then be accessed directly on the output website.

Basic site publishing via the static folder

So how do you publish your site via the static folder mechanism? To put it plainly, you just move your files into the given folder.

Say I wanted to publish myProject to url BASEURL/myProject where BASEURL is your site's domain (this site's would be

To do so, I would just create a folder inside static so that the directory path looked like static/myProject then git clone (or I guess just copy the files in directly) to that directory. Once I hugo serve (the hugo flavor of spinning up a local dev server), that project will now be accessible via BASEURL/myProject (where BASEURL would be whatever localhost:PORT your hugo serve bound itself to).

Note that this is assuming your project is a web project accessible via browser and that it contains an index.html file that serves as the entrypoint to it in the top-most level of your project directory i.e. static/myProject/index.html

Advanced site publishing via the static folder

Okay so now we know how to get our web project published and on our site but what if we want it to play nicely with the rest of our Hugo content? For example, say I've already written a page about myProject that lives at BASEURL/projects/myProject, how do I get my demo to live at BASEURL/projects/myProject/demo?

We already have all the tools to make this possible, we just have to put them together. As we've mentioned, the content of the static folder gets published to the site on a url corresponding to its directory structure. So in the previous example static/myProject became BASEURL/myProject in the output site.

So in order to get myProject published at BASEURL/projects/myProject/demo we need to create a corresponding directory structure in static which would look something like static/projects/myProject/demo and contain the files for myProject.

You might be thinking, "man, this is a lot of manual labor just to get this configured" and you'd be right. There is a fair amount of configuration that goes along with this, but the tradeoff is that you get the niceties of the rest of the static-site generator in the rest of your website. If you're just going to be hosting a bunch of projects, then Hugo may not be the best choice, but if you're going to throw in the occasional content page/post, the tradeoff starts to make a lot more sense.


That's all for now. If you see something wrong/have questions, feel free to hit me here or contact me otherwise.

I'll be publishing more posts on Hugo and how I use it in the coming months. If you want to get updates, we have various options to stay up-to-date. Try one.


Want more like this?

The best / easiest way to support my work is by subscribing for future updates and sharing with your network.