My complete blogging workflow

There's an online discussion about blogging workflows as they relate to images and static site generators (h/t Kev). Ru was asking specifically about images but I thought I'd just use it as an opportunity to document my whole process, soup to nuts. No blogger worth their salt will pass up an opportunity to blog about blogging.

Tech stack

Let's talk about one of my favorite things first!

My static site generator of choice is Eleventy. I've never used a different static site generator so I can't really compare it to the others but I've really grown to love it. The community is really supportive, friendly and nice. I wish they would branch out and participate in the Fediverse instead of Twitter and Discord but we don't always get what we want. ;)

Unlike many other bloggers who use static site generators, I do not use any sort of automated CI/CD pipeline using managed services like GitHub, Netlify, or Vercal. Instead, I host my site on a VPS at Capsul. I've been very pleased since switching. My initial motivation for moving away from GitHub Pages was I didn't want to host my site on Microsoft owned properties but now I find pleasure in the simplicity of it. When I build my site, a bunch of text based files and a few optimized images are put onto my local computer and I copy those files to my web server. The web server runs on a server in Atlanta GA and I'm able to talk to the real humans who run the server by logging into their matrix instance. That's web0 easy; it's easy to understand and has few external dependencies.

I write the content for my posts using Typora on Linux. I really like the minimalist look and feel of the writing experience. I much prefer it to writing in Visual Studio Code, Obsidian or Zettlr.

Idea management and writing workflow

I'm using a modified version of Josh Ginter's Writing Workflow to manage my writing. Instead of having seven buckets, I only have three.

  • Ideas - My idea's bucket is actually split into two different places. When something relevant or interesting comes across one of my feeds, and I feel I may want to write a blog post about it, I save it to my Read Later bucket on Pinboard. I also have an Ideas folder on my local computer. When I'm processing my Read Later bucket on Pinboard, anything that passes muster is moved into the Ideas folder as a markdown file, with a link to the article that caught my interest. Only about 50% of items get moved from my Read Later bucket on Pinboard to my Ideas folder on my computer. What seemed interesting at 9 pm as I'm tired scrolling on the sofa, doesn't seem as interesting in the light of day so I just delete the item.
  • Writing - The writing bucket is just a folder on my computer. When I start writing a post, I move the markdown file from the Ideas folder to the Writing folder. I generally do not use many images in my day-to-day blogging but for posts with images, I go ahead and gather the images up and place them in an images folder along with the markdown file at this time. While I'm writing, I put in a placeholder for each image to remind myself to complete the manual step during the deployment step.
  • Archive - After posting the article, I move it from the Writing folder to the Archive folder.


After I've written all the content for my post, now it's time to stage it for deployment.

The first step is to fire up Visual Studio Code and create a folder for the new post and any associated images to live. All my source posts live in a posts directory in my projects folder and are further grouped by year and then by blog title. Example: /posts/2022/blog-title/. Inside the post directory, I create Images are copied into /posts/2022/blog-title/images/ at this time.

Next, I open and add my front matter at the top of the file. I created a snippet in VS Code to create the boiler plate. The output of the snippet looks like this:

title: "this is the title"
desc: "this is the description field"

I also use a VS Code extension called Front Matter. Mostly I just use the extension to populate the date field in the front matter section as it outputs a full and properly formatted datetime value like so: 2022-01-29T07:34:03.769-06:00.

Once I've populated the front matter section of the file, I copy and paste the contents of the post from Typora into the new file in VS Code, below the front matter section.

A note on Images

Since images as they relate to static site generators was the catalyst for this whole post, I want to be sure to cover this part in detail.

When I built this workflow process, it was important to me that my post images exist with the post text. I point this out because nearly every other person who has shared their workflows and setups seem to put their post images in an entirely different place from the post content. This structure allows me to more easily pick up my blog posts and move them into a different blogging platform if I so desired. This requirement is only for the source files BTW. When the build process runs, it sticks all the output images in a root /images/ directory and the HTML file for the post has a different convention, /posts/2022/01/29/blog-title.

Image workflow

I use the excellent Eleventy image plugin for image processing. It allows the use of a shortcode in the markdown file which is processed during the build stage. Since the plugin is going to convert and resize the images, I spend very little time or effort thinking about the size or resolution of the source images. The plugin generates responsive, lazy loading image markup and does all the compressing, resizing and converting needed at build time.

OK, so back to my workflow! I review the post and start replacing the image place holders from the writing step with the Eleventy shortcodes. Below is the boilerplate I use for images. Again, I use a snippet in VS Code to automatically place this on the page on command.

{% myImage "image.jpeg", "Alt text should go here." %}
  • myImage is the actual shortcode
  • "image.jpeg" is the name of the file. No need for a path here as my workflow assumes the image is located in an /images/ directory relative to the post directory.
  • Alt text is the alt text placed on the image markup.

If I want to caption an image, I use this boilerplate:

{% myImage "image.jpeg", "Alt text should go here." %}
<figcaption>Fig caption should go here.</figcaption>

The shortcode generates the following markup and six images during build. Three different size break points and two different types of images, webp and jpeg. All of what's generated is 100% configurable with Eleventy image.

srcset="/images/c9GnJ8efL7-360.webp 360w,
/images/c9GnJ8efL7-651.webp 651w,
/images/c9GnJ8efL7-778.webp 778w"


srcset="/images/c9GnJ8efL7-360.jpeg 360w,
/images/c9GnJ8efL7-651.jpeg 651w,
/images/c9GnJ8efL7-778.jpeg 778w"


alt="Alt text should go here."

<figcaption>Fig caption should go here.</figcaption>

Images are by far the most tedious part of publishing posts. Not just setting up the shortcodes but writing good alt text and captions is hard.


After one final review, I build the site:

npx @11ty/eleventy --incremental

This builds all the files for my whole website and places them into the output directory on my local file system. I almost always run the local copy in Live Server just to make sure nothing is obviously wrong with my post. Occasionally I forget the date and this is obvious at this stage.


I "deploy" my site by using the rsync command to copy the files from my computer to my server.

rsync -rtv --delete -e "ssh" ~/Projects/localdir/ user@


I now open the post in the browser for a final review then I manually share the post on Mastodon and Twitter. I then anxiously wait for positive external feedback. :D

So that's my whole process for writing and publishing posts with Eleventy. These are the opportunities for improvement in my mind:

  • I could script parts of the staging step. It would be nice if I could type in the writing directory and that would automatically create the correct folder with the correct name, then lift and shift the markdown file and the images. It could maybe even insert the front matter part of the file.
  • I could script the build --> deploy --> syndicate bit pretty easily as well. I'd want to perform some error checks on the most common things I tend to forget like forgetting the datetime.

What's your publishing workflow look like? Do you have any suggestions for improvements to mine? I'm open to constructive feedback.

Reply via email