Skip to main content
  1. Posts/

Migrating from Jekyll to Hugo Part 2: Content Migration

·575 words·3 mins
Chris Ayers
Author
Chris Ayers
I am a father, nerd, gamer, and speaker.

In Part 1, I covered why I switched from Jekyll to Hugo. Now let’s dive into the actual content migration.

Front Matter Conversion
#

Most Jekyll posts work with minimal changes, but there are key differences:

# Jekyll
---
layout: post
title: "My Post"
date: 2024-01-15
categories: development
tags: [docker, containers]
mermaid: true
---

# Hugo
---
title: "My Post"
date: 2024-01-15
categories:
  - Development
tags:
  - Docker
  - Containers
---

Key changes I made:

  • Removed layout: post - Hugo infers layout from content location
  • Converted tags/categories to arrays - YAML list format
  • Standardized capitalization - Consistent taxonomy naming
  • Removed mermaid: true - Blowfish auto-detects mermaid shortcodes
Tip: Run hugo server while migrating so you can preview each converted post immediately and catch front matter issues early.

Shortcode Conversions
#

Jekyll uses Liquid templates while Hugo has its own shortcode system.

Images and Figures
#

<!-- Jekyll -->
{% include figure.html src="/images/photo.jpg" caption="My caption" %}

<!-- Hugo -->
{{< figure src="/images/photo.jpg" caption="My caption" >}}

Here’s the Hugo figure shortcode in action:

Hugo Logo
The Hugo logo rendered with the figure shortcode

Mermaid Diagrams
#

This was a bigger change. Jekyll with the mermaid plugin uses fenced code blocks:

<!-- Jekyll -->
```mermaid
graph TD
    A --> B
```

Hugo with Blowfish requires the mermaid shortcode:

<!-- Hugo -->
{{< mermaid >}}
graph TD
    A --> B
{{< /mermaid >}}

I wrote a quick script to find and convert these across all posts. Here’s what a real mermaid diagram looks like after migration:

flowchart LR
    A["Jekyll Post\n(.md + Liquid)"] -->|migrate| B["Hugo Post\n(.md + Shortcodes)"]
    B --> C{"hugo build"}
    C --> D["Static HTML"]
    C --> E["Processed Images"]
    C --> F["Minified CSS/JS"]

Code Blocks
#

Standard fenced code blocks work the same, but Hugo adds features:

<!-- Hugo with line numbers -->
{{< highlight go "linenos=table,hl_lines=3" >}}
func main() {
    fmt.Println("Hello")
    fmt.Println("Highlighted!")
}
{{< /highlight >}}

Here’s what that looks like rendered with Hugo’s syntax highlighting and line numbers:

1
2
3
4
func main() {
    fmt.Println("Hello")
    fmt.Println("Highlighted!")
}

Static Assets
#

Jekyll and Hugo organize assets differently:

JekyllHugo
assets/images/static/images/
_data/data/
_includes/layouts/partials/

For images referenced in posts, I kept paths like /images/photo.jpg which maps to static/images/photo.jpg.

Watch out: Hugo’s assets/ folder is for files processed by Hugo Pipes (SCSS, image resizing, fingerprinting). Use static/ for files served as-is. Mixing them up leads to 404s.

Handling Excerpts
#

Jekyll uses excerpt_separator in config or <!--more--> in posts. Hugo works the same way with <!--more-->:

---
title: "My Post"
---

This appears in the summary.

<!--more-->

This is the full content.

Taxonomy Cleanup
#

I took the opportunity to consolidate tags:

  • Merged similar tags (vscodeVSCode)
  • Standardized capitalization
  • Removed unused categories

Bulk Migration Script
#

“The best migration is the one you automate. Don’t hand-edit 60 posts when a script can do it in seconds.”

For 60+ posts, I used a simple PowerShell script:

Get-ChildItem "content/posts/*.md" | ForEach-Object {
    $content = Get-Content $_.FullName -Raw
    
    # Remove layout: post
    $content = $content -replace "layout: post\r?\n", ""
    
    # Remove mermaid: true
    $content = $content -replace "mermaid: true\r?\n", ""
    
    Set-Content $_.FullName $content
}
Note: The PowerShell script above covers the basics, but you may need additional passes for things like Liquid {% raw %} blocks or custom Jekyll includes. Test thoroughly!

What’s Next
#

In Part 3, I’ll cover deployment with GitHub Actions and the challenges I encountered along the way.

Resources
#

Related

Customizing the Jekyll Theme

I haven’t done a lot with jekyll in the past, but I’m a big fan of Markdown everything. For me that usually means I’m taking notes in Markdown Obsidian, doing diagrams in mermaid in Azure DevOps or https://mermaid.live/. I’ve even started turning my talk slides into Markdown with a tool called MARP. Understanding when I use standard Markdown or some sort of templating language (jekyll uses Liquid) has been fun. I’ll do something in HTML or Markdown, then find out that Jekyll or my theme already has helpers to render that (like gists, videos, and figures). Sometimes rendering more advanced things takes a little tweaking of Jekyll and the theme.

Migrating from WordPress to GitHub Pages

I’ve been hosting on WordPress for a while. I wanted something that worked pretty well and was easy to work with. I picked a decent theme, added some plugins, pointed my domains and was up and running. I would work on blogs in Markdown, and then paste the txt into a Markdown. I could upload a few images and move them around in a wysiwyg. Lately, I’ve been doing a lot more in Markdown. All my conference talks were in PowerPoint but I’ve started switching over to Markdown slides using MARP. I should probably do a post on MARP sometime (I did :-) ). I wanted to reduce my overhead of WordPress Hosting and get back into more direct styling and coding of my theme. I decided to switch my hosting to Jekyll on GitHub Pages.

Embedding Draw.io Diagrams in VSCode

·942 words·5 mins
If you’re like me, you love discovering new ways to boost your productivity and workflows. One of my favorite tools is Draw.io. I’ve used the desktop tool and the site, but I found a new integration that has significantly elevated my VSCode experience: the Draw.io Integration extension.

Unleash Your Creativity with Marp Presentation Customization

·1338 words·7 mins
This is part 2 of the MARP series. You can read the series of articles here: Marp - Create Presentations with Markdown Unleash Your Creativity with Marp Presentation Customization Introduction # Marp is a powerful Markdown presentation framework that enables you to create stunning slides effortlessly. By using simple text-based formatting, you can easily customize your presentations to suit your unique needs and style. Although Marp provides built-in themes and configurations, the true potential of this framework can be realized by customizing your presentations to suit your unique needs and style. In this blog post, we will delve into some of the key customization options available in Marp and guide you through the process of creating a truly standout presentation.