Blog Workflow

For people who don’t create websites regularly, the process of setting up a blog and writing consistently and figuring out how to use products like Hugo and GitHub can be daunting. I hope this can shed some light on what my setup is and provide some useful resources to get started.

To be honest, I’m writing this post because it’s been a few months since I’ve published a blog post and I’ve started to forget all of the necessary steps and commands. This post started out as a way of documenting the steps and specific commands in Terminal for Hugo and GitHub, but I figured it would be a good opportunity to write about my overall workflow as well.

Writing

One of my goals this year is to increase my output of blog posts. Like any tech nerd, I set a metric to measure my output / consistency. My metric is writing on average 5 days a week for the year (260 days). Taking a lesson from Hemingway, I count it as a successful day if I can write just ‘one true sentence’. The book Atomic Habits (James Clear) talks about the Two Minute Rule - “When you start a new habit, it should take less than two minutes to do.” I want to make writing less daunting by accepting the fact that even writing one sentence is a successful day. My guess is that once I sit down, I’ll be able to do a lot more than that.

For idea tracking, I have a document that is split into Marketing and Non-marketing ideas. I continually add to those lists as I think of them. There are currently 15 marketing blog post ideas and 9 non-marketing, but I suspect that number will grow quickly as I think about writing more.

I do all of my planning and writing on Notion. It’s a simple tool that allows you to quickly create task lists and documents without much software bloat. Some reasons why I chose Notion:

  • Flexibility - all of my blog-related needs in one place. For example, I can have a Trello-like task list to track all of my potential site cosmetic updates in the same place as my drafts and blog post ideas.
  • Cross-platform - I write regularly on my desktop PC, MacBook, and iPad. My drafts in Notion sync quickly and I never have to worry about editing an out-of-date document.
  • Simplicity - For all of its flexibility, Notion still keeps the writing experience pretty spartan. I love that I can have basically a blank screen and just write. No toolbars at the top, no distracting colors - just sit down and write.
  • Markdown - Notion’s pages support markdown, making it easy for me to copy and paste into a markdown (.md file) document once I’m finished writing. More on why this is important later.

Notion works great for my needs, but I hesitate to recommend it. A couple of years ago, I was collaborating with a friend and found that the mobile app was basically unusable due to lag and performance issues. Even though we had a decent amount of work in Notion, we eventually had to migrate off the platform. Because of this experience, I never recommend Notion unless you just need a glorified word editor.

I use Visual Studio Code (free!) to open all of my markdown files after I transfer them from Notion. I really like the plug-in that color-codes the different tags when I’m looking at a HTML or CSS file.

Static Site Generator

Some common options for people who want to quickly set up a blog are WordPress, a static site generator (Hugo / Jekyll), and Ghost. WordPress felt too bloated and I didn’t want to spend money with Ghost. This left me with Hugo and Jekyll - similar products with active communities. I honestly picked Hugo because I came across a helpful step-by-step guide on how to set up Hugo with Github. One additional option to consider is Substack, but I crossed them off the list early on because their platform isn’t very flexible with design.

So far, Hugo has been super straightforward. Pick a theme, make some updates to the CSS, and launch the site. It’s very fast and well documented for any troubleshooting needs. A couple of things to note:

  • Learning some HTML and CSS went a long way in updating the look and feel of the template I used. There’s a ‘custom css’ file that allows me to change specific tags attributes. Knowing how to inspect elements, understanding relative sizing, how margins work, etc has been useful.
  • One potential downside to Hugo is that there aren’t any plug-ins that you’d find on WordPress. For example, I’d love to add an option for people to subscribe to my blog for email updates. Since it’s an SSG, there’s no backend database to store emails. Forms are not possible natively, so I’ll have to look for another solution and try to integrate it myself.

Hosting

When I created my first couple of websites in high school and college, I paid for hosting and managed all of the files via FTP. Much to my surprise, that’s no longer needed for simple sites with mostly text.

I chose GitHub Pages to host my site mostly because I wanted to use and understand Github more. I thought it would be helpful to stay within the ecosystem. I don’t have the opportunity to use it at work so this was a good excuse. Netlify is another similar option that helps with deploying and hosting sites.

Setting up my page took a bit more trial and error than I expected because of the Github concept of a submodule. A submodule allows you to keep the raw Hugo and markdown files in a private repository while keeping the public files (stuff that web browsers read) in the submodule. One downside is that I have to update both repos separately. It can be a bit cumbersome. Adam Ormsby wrote a great guide on how to set up the submodule with Hugo.

Creating and uploading a new post

I try to stay in Terminal (or PowerShell on my Windows machine) as much as possible. Again, just to practice and get comfortable.

The first thing I do is go to my folder (/XuanLi.Me/blog) where the GitHub repository is located and run git pull to ensure that my local files are up to date. Because I switch between my Macbook and Windows computer often, I’ve made the mistake of trying to make changes with an out-of-date local repository several times.

From the /blog folder, I use this Hugo command to create a new blog post: hugo new content/posts/XYZ.md. Hugo generates a blank markdown document with all of the metadata fields for the theme that I’m using.

I open the markdown file with Visual Studio Code, add the post’s category and tags, and then paste the content from Notion. As I mentioned earlier, one of the benefits of using Notion is its support for markdown. I had a much harder time copy and pasting from Google Docs since none of the bolding, links, or formatting copied over.

The hugo server command lets me view my new blog post and subsequent changes in real-time without needing to push everything to GitHub. I just have to go to http://localhost:1313/ on my web browser to see the instance. It refreshes with the changes I make in my document instantly which makes formatting and small updates a breeze. The only downside is that it doesn’t work as well for images. You can have the server load a local image, but that same code (/blog/images/example.png) in the markdown document won’t work once you upload it online since the path isn’t the same.

Assuming everything looks good, I generate a new ‘site’ by using the hugo command in the /XuanLi.Me/blog/ folder. Hugo basically creates new files with the new blog post or updates and overwrites all the previous files in the ‘public’ folder.

At this stage, I’m ready to push the files to my private GitHub repo. The git add . command prepares all of the new files for upload. Check the additions with git status, then commit to the changes with git commit -m "[descriptive message]".

Next, git push origin main will upload all of the new files to my repository.

By this point, all of my files are updated in my private repository. However, because the /public/ folder is actually a submodule, those files are not updated. I have to cd into the public folder and add —> commit —> push those files as well.

Voila - my site is updated.