Hugo Web Development Workflow on Windows

As I mentioned in my first article on this blog, I’m now using Hugo, the static site generator to build my personal website. Due to the needs of my work environment (mostly because I need to use MS Word and certain MATLAB features on a regular basis), I’ve been primarily using Windows as my operating system for the past year or so. Having used Linux for a long time, I definitely missed the conveniences offered by shell scripting and other command line tools. However, while setting up a workflow in Windows for publishing content to my website I discovered that Windows’ scripting tools are not all that bad. In fact, for anyone familiar with scripting from Linux, moving to Powershell isn’t that hard.


A typical Hugo website development folder looks like this: Folder Structure

I add new posts by creating new markown (.md) files in the post folder. When the website is compiled using the hugo command, the static website’s code is generated into the public folder. The content inside this is what goes into the folder that is served by any webserver. Since I am hosting the website on Github Pages, I found it most convenient to set up a separate folder with a clone of the repository. After article writing/editing is done, I can generate the website and copy the contents inside the public folder to the repository folder to publish.

When I am editing an article, I can preview content locally by using the hugo server --watch command in the top level directory. This sets up a local webserver on localhost:1313 so that you can preview the website.

To publish my website to Github pages after I’m done with development, I copy everything inside the public folder into my local copy of the github repository and then commit all and push.

Batch Script Automation

Most of the the steps in the workflow can be automated away using batch scripts to save large amounts of time. I mean, who wants to spend time manually copying files and commiting after every small edit to the website? The build_on_laptop.bat file in the top level directory handles everything. Diving into the source, I first delete everything inside the public folder (Hugo does not automatically do this) and build a fresh version of the website.

rmdir /S /Q public

My Github pages repo has a few files that are not generated by Hugo. So I can’t just nuke the folder and delete everything. So I have a set of commands that delete all the Hugo generated files in the repository folder:

rmdir /S /Q "C:\Users\Ashwin Narayan\\categories"
rmdir /S /Q "C:\Users\Ashwin Narayan\\css"
rmdir /S /Q "C:\Users\Ashwin Narayan\\fonts"
rmdir /S /Q "C:\Users\Ashwin Narayan\\home"
rmdir /S /Q "C:\Users\Ashwin Narayan\\img"
rmdir /S /Q "C:\Users\Ashwin Narayan\\js"
rmdir /S /Q "C:\Users\Ashwin Narayan\\post"
rmdir /S /Q "C:\Users\Ashwin Narayan\\project"
rmdir /S /Q "C:\Users\Ashwin Narayan\\publication"
rmdir /S /Q "C:\Users\Ashwin Narayan\\publication_types"
rmdir /S /Q "C:\Users\Ashwin Narayan\\tags"
rmdir /S /Q "C:\Users\Ashwin Narayan\\talk"
del "C:\Users\Ashwin Narayan\\404.html"
del "C:\Users\Ashwin Narayan\\index.html"
del "C:\Users\Ashwin Narayan\\index.xml"
del "C:\Users\Ashwin Narayan\\sitemap.xml"
del "C:\Users\Ashwin Narayan\\site.webmanifest"
del "C:\Users\Ashwin Narayan\\styles.css"

Then comes the task of copying your updated website source into the folder. While it’s possible to use the cp command, I found that the robocopy command is in general much better for copying files around in Windows.

robocopy public "C:\Users\Ashwin Narayan\" /E

Finally, I need to commit the new version of the website and push to github. This is also easily done:

cd "C:\Users\Ashwin Narayan\"
set /p commitmsg="Enter a commit message: "
git add --all .
git commit -m "%commitmsg%"
git push origin master

So the end result is that when I run this script, it automatically deletes everything in the public folder and the repository folder, rebuilds and copies the new website over and then commits and pushes the new version to github to deploy the website.

Even More Automation with Visual Studio Code

I can shave even more time off the workflow by using Visual Studio Code. VS Code has a really well made task management system. It’s also a natural choice since I do most of my markdown editing inside VS Code anyway. VS Code has a tasks.json file where you can bind custom tasks/commands to key combinations. In this case, I just bound the default build task mapped to Ctrl+Alt+B to the batch script. I also created a compose task which creates the local preview webserver.

    // See
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "tasks": [
            "taskName": "build",
            "command": "build_on_laptop.bat",
            "isShellCommand": true,
            "showOutput": "always",
            "echoCommand": true
            "taskName": "compose",
            "command": "hugo",
            "args": ["server", "--watch"],
            "isShellCommand": true,
            "showOutput": "always",
            "echoCommand": true

With most of the steps automated, writing and publishing new articles don’t take that long compared to off the shelf solutions like Wordpress or Medium. It also comes with the advantage that you have full control over the website’s source code.

Ashwin Narayan
Ashwin Narayan
Robotics | Code | Photography

I am a Research Fellow at the National University of Singapore working with the Biorobotics research group

comments powered by Disqus