how I built my blog site
With the release of my first blogpost on this new site, I also wanted to do a quick writeup on what I did to build it! This setup is heavily inspired by NetworkChuck’s Obsidian + Hugo video, as this was perfect for my use, so definitely consider checking out his video too!
Tooling
My blogpost workflow revolves around two amazing tools:
- Obsidian is a markdown-based note-taking tool meant to link ideas and notes. I use Obsidian for absolutely everything and have full intentions on sharing my Obsidian system in the future!
- Hugo is a free, open-source static website generator known for its ease of use and configurability. The plan is any content written in Obsidian can easily be copied into Hugo and displayed as a separate blogpost.
Generating a Hugo Website
Start by installing Hugo from the official installation page and install it based on your platform. I’m using macOS for everything, but the command should be the same.
In a terminal, navigate to the directory where you want to store your website, and type:
hugo new site blog
Replacing blog
with whatever you’d like to name the directory.
To make things pretty, I selected the Hugo Blog Awesome theme at the time of writing. There are many other themes available, so feel free to select your own and install it following the instructions addressed by the selected theme.
To test the website, type:
hugo server
Then navigate to localhost:1313
in a web browser, or whatever is displayed by the server. I won’t go into the hyper specifics of everything, but if you’d like to learn a lot more about the website building process and how Hugo works, definitely consider looking at NetworkChuck’s video and the Hugo documentation.
Generating A Blogpost
Markdown Front Matter
Front matter is a section at the top of markdown files that contains metadata, like the title and author, which tools like Hugo use to organize content. I use markdown front matter for both my Obsidian notes and my Hugo blogposts, as it allows me to extract various features for each tool. Here’s a quick image of my blogpost note front matter:
The goal
and status
fields are for my Obsidian system.
- The
status
field indicates if a note is active, which determines whether or not it show up on my central Obsidian dashboard. - The
goal
field provides a quick summary of what the note is about and what I want to achieve with it.
The title
, description
, author
, and date
fields are for my Hugo website.
- The
title
field is the actual title of any blogpost that shows up on my website. Unlike Obsidian, Hugo does not use file names as titles. - The
description
field is for additional information about the blogpost, which shows up in some web previews or embeds. - The
author
field indicates who wrote the blogpost (is permanently me, hun). - The
date
field indicates when a blogpost was published. This shows up on the website when navigating the posts I’ve made.
Migrating Content
With this simple system, I can theoretically migrate blogposts written in Obsidian into my Hugo site and it’ll simply work! While this is mostly true, one small issue comes with how Obsidian and Hugo handle images.
Obsidian embeds images in a specific way. For a photo called filename.png
, Obsidian handles it like this:
![[filename.png]]
These referenced images are stored in a single directory by default. To export a blogpost with images, you’ll need to navigate to Obsidian’s images directory, locate the file (likely out of a large number of files), and move it into Hugo’s structure, repeating the process for each image individually.
Even after exporting the images properly, making things slightly more challenging, Hugo embeds images in a different way. For the same photo called filename.png
, Hugo handles it like this:
![filename](</images/filename.png>)
Note: The /images/filename.png
path is a requirement if images are stored within the /static/images
directory within Hugo. Furthermore, the <>
around the file path ensures that it’s still properly handled if there’s a space in it.
This means after the blogpost and images have been copied from Obsidian and into Hugo, the resulting blogpost must be altered to accommodate Hugo’s syntax.
My Handy Export Script
Depending on the length of the blogpost, the number of images referenced in it, and the directory structures of both Hugo and Obsidian, this process can become extremely complicated and time-consuming very quickly. To solve this problem, I’ve created a little python script that automates the entire process! Feel free to download it here on my GitHub.
In a nutshell, the script does the following:
- Finds active blogs: Navigates to your Obsidian blog directory and checks the front matter of each file, looking for
status: active
. - Copies blog into Hugo: Once an active blog is found, the script asks what blog to copy the blogpost to. This will list the available directories in the
/content/posts
directory in Hugo. - Collects images: The script parses every instance of an image in the active blog, looking for the
![[]]
syntax that Obsidian uses to reference images. - Copies images into Hugo: It then navigates to the Obsidian image directory and copies the referenced images into the
/static/images
directory in Hugo. - Pushes to GitHub: Lastly, the entire blog repo is updated and pushed to GitHub, with the option to submit your own git commit message.
Feel free to use the script! It only requires five explicit paths:
- Obsidian blogs
- Obsidian images
- Hugo blogs
- Hugo images
- GitHub repo path (the created Hugo website directory)
Furthermore, this also assumes that the status
field within the Obsidian front matter is in use, so feel free to implement that front matter or modify the script in any way!
Publishing Content
To make my website and published blogs available on the internet, I’ve created a GitHub repository for my blog and linked it to Cloudflare Pages. A worker monitors the repository for updates, and when one is detected, it rebuilds and restarts the Hugo server almost instantly.
This method is fantastic because it’s completely free, and you also benefit from the network protection mechanisms that Cloudflare offers. I did purchase the hunio.org domain name and linked it to my Cloudflare Pages setup, but many domains are available for very low prices.
Hopefully that provides some insight on how I used these tools to create this little website! :)