Skip to main content Dennis Traub - Software Engineer & Developer Advocate

Jekyll or Hugo?

I’ve been procrastinating on setting up a new blog/website–literally–for years, and today I finally looked into static site generators that allow me to simply push my changes to a GitHub repo and let everything build on its own.

I looked at Jekyll, and after installing Ruby and some other stuff, I quickly realized that I don’t really like it. I can’t even say why, it just didn’t feel right.

The next one I tried was Hugo, and–well–the result is the website you’re currently looking at. All in all, including finding and adapting a theme (I’m using Today I Learned, by Michael Henriksen), setting up the GitHub action, and getting everything up and running, took maby two or three hours. Not bad, Right?

But I must admit that Claude was of great help! If you’re interested, here’s the conversation transcript:


Me

I want to set up a blog, hosted on github pages, with Hugo and a minimalist theme similar to the one used by e.g. simonwillison.net. My local machine is a Windows PC. Guide me through the setup step by step

Claude

I’ll help you set up a Hugo blog on GitHub Pages with a minimalist theme. Let me create a comprehensive guide for Windows users.


// Beginning of artifact: Setting Up a Hugo Blog on GitHub Pages

Prerequisites Installation

  1. Install Git

  2. Install Hugo

    • Download Hugo Extended from https://github.com/gohugoio/hugo/releases
    • Choose the latest Windows-64bit extended version (e.g., hugo_extended_0.123.0_windows-amd64.zip)
    • Create a folder C:\Hugo\bin
    • Extract the hugo.exe file to C:\Hugo\bin
    • Add C:\Hugo\bin to your system’s PATH:
      • Search for “Environment Variables” in Windows
      • Under System Variables, find “Path”
      • Click “Edit” → “New”
      • Add C:\Hugo\bin
      • Click “OK” to save

Blog Setup

  1. Create GitHub Repository

    • Go to GitHub and create a new repository named username.github.io (replace username with your GitHub username)
    • Make it public
    • Don’t initialize it with any files
  2. Create Local Hugo Site

    bash code snippet start

    # Open Command Prompt and navigate to your desired location
    cd C:\Users\YourUsername\Documents
    
    # Create new Hugo site
    hugo new site my-blog
    cd my-blog
    
    # Initialize git
    git init
    
    # Add GitHub repository as remote
    git remote add origin https://github.com/username/username.github.io.git

    bash code snippet end

  3. Install Theme For a minimalist theme similar to simonwillison.net, we’ll use Paper:

    bash code snippet start

    git submodule add https://github.com/nanxiaobei/hugo-paper themes/paper

    bash code snippet end

  4. Configure Site Create/edit config.toml with these settings:

    toml code snippet start

    baseURL = 'https://username.github.io/'
    languageCode = 'en-us'
    title = 'Your Blog Title'
    theme = 'paper'
    
    [params]
      # Paper theme settings
      color = 'light'
      twitter = 'yourusername'  # Optional
      github = 'yourusername'   # Optional
    
    [menu]
      [[menu.main]]
        identifier = "about"
        name = "About"
        url = "/about/"
        weight = 10
      [[menu.main]]
        identifier = "posts"
        name = "Posts"
        url = "/posts/"
        weight = 20

    toml code snippet end

  5. Create First Post

    bash code snippet start

    hugo new posts/my-first-post.md

    bash code snippet end

    Edit content/posts/my-first-post.md:

    markdown code snippet start

    ---
    title: "My First Post"
    date: 2024-10-28
    draft: false
    ---
    
    Hello, world! This is my first blog post.

    markdown code snippet end

  6. Create About Page

    bash code snippet start

    hugo new about.md

    bash code snippet end

    Edit content/about.md:

    markdown code snippet start

    ---
    title: "About"
    date: 2024-10-28
    draft: false
    ---
    
    This is my personal blog where I write about...

    markdown code snippet end

  7. Test Locally

    bash code snippet start

    hugo server -D

    bash code snippet end

    Visit http://localhost:1313 to see your site

Deployment Setup

  1. Create GitHub Actions Workflow Create .github/workflows/hugo.yml:

    yaml code snippet start

    name: Deploy Hugo site to Pages
    
    on:
      push:
        branches: ["main"]
      workflow_dispatch:
    
    permissions:
      contents: read
      pages: write
      id-token: write
    
    concurrency:
      group: "pages"
      cancel-in-progress: false
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
            with:
              submodules: true
          - name: Setup Hugo
            uses: peaceiris/actions-hugo@v2
            with:
              hugo-version: 'latest'
              extended: true
          - name: Build
            run: hugo --minify
          - name: Upload artifact
            uses: actions/upload-pages-artifact@v2
            with:
              path: ./public
    
      deploy:
        environment:
          name: github-pages
          url: ${{ steps.deployment.outputs.page_url }}
        runs-on: ubuntu-latest
        needs: build
        steps:
          - name: Deploy to GitHub Pages
            id: deployment
            uses: actions/deploy-pages@v2

    yaml code snippet end

  2. Push to GitHub

    bash code snippet start

    # Add all files
    git add .
    
    # Commit
    git commit -m "Initial blog setup"
    
    # Push to main branch
    git push -u origin main

    bash code snippet end

  3. Configure GitHub Pages

    • Go to your repository settings
    • Navigate to “Pages”
    • Under “Build and deployment”:
      • Source: Choose “GitHub Actions”

Writing New Posts

To create new posts:

  1. Run hugo new posts/post-name.md
  2. Edit the markdown file in content/posts/
  3. Set draft: false when ready to publish
  4. Commit and push changes
  5. GitHub Actions will automatically deploy your updates

Customization Tips

  1. Modify Theme Colors Create assets/css/extended.css to override theme styles:

    css code snippet start

    :root {
      --primary: #1a1a1a;
      --secondary: #4a4a4a;
      --link-color: #0066cc;
    }

    css code snippet end

  2. Add Custom Favicon Place your favicon.ico in the static folder

  3. Enable Syntax Highlighting Add to config.toml:

    toml code snippet start

    [markup]
      [markup.highlight]
        style = "github"
        lineNos = true

    toml code snippet end


I’ll help you set up a Hugo blog on GitHub Pages with a minimalist theme. Let me create a comprehensive guide for Windows users.

Setting Up a Hugo Blog on GitHub Pages

Prerequisites Installation

  1. Install Git

  2. Install Hugo

    • Download Hugo Extended from https://github.com/gohugoio/hugo/releases
    • Choose the latest Windows-64bit extended version (e.g., hugo_extended_0.123.0_windows-amd64.zip)
    • Create a folder C:\Hugo\bin
    • Extract the hugo.exe file to C:\Hugo\bin
    • Add C:\Hugo\bin to your system’s PATH:
      • Search for “Environment Variables” in Windows
      • Under System Variables, find “Path”
      • Click “Edit” → “New”
      • Add C:\Hugo\bin
      • Click “OK” to save

Blog Setup

  1. Create GitHub Repository

    • Go to GitHub and create a new repository named username.github.io (replace username with your GitHub username)
    • Make it public
    • Don’t initialize it with any files
  2. Create Local Hugo Site

    bash code snippet start

    # Open Command Prompt and navigate to your desired location
    cd C:\Users\YourUsername\Documents
    
    # Create new Hugo site
    hugo new site my-blog
    cd my-blog
    
    # Initialize git
    git init
    
    # Add GitHub repository as remote
    git remote add origin https://github.com/username/username.github.io.git

    bash code snippet end

  3. Install Theme For a minimalist theme similar to simonwillison.net, we’ll use Paper:

    bash code snippet start

    git submodule add https://github.com/nanxiaobei/hugo-paper themes/paper

    bash code snippet end

  4. Configure Site Create/edit config.toml with these settings:

    toml code snippet start

    baseURL = 'https://username.github.io/'
    languageCode = 'en-us'
    title = 'Your Blog Title'
    theme = 'paper'
    
    [params]
      # Paper theme settings
      color = 'light'
      twitter = 'yourusername'  # Optional
      github = 'yourusername'   # Optional
    
    [menu]
      [[menu.main]]
        identifier = "about"
        name = "About"
        url = "/about/"
        weight = 10
      [[menu.main]]
        identifier = "posts"
        name = "Posts"
        url = "/posts/"
        weight = 20

    toml code snippet end

  5. Create First Post

    bash code snippet start

    hugo new posts/my-first-post.md

    bash code snippet end

    Edit content/posts/my-first-post.md:

    markdown code snippet start

    ---
    title: "My First Post"
    date: 2024-10-28
    draft: false
    ---
    
    Hello, world! This is my first blog post.

    markdown code snippet end

  6. Create About Page

    bash code snippet start

    hugo new about.md

    bash code snippet end

    Edit content/about.md:

    markdown code snippet start

    ---
    title: "About"
    date: 2024-10-28
    draft: false
    ---
    
    This is my personal blog where I write about...

    markdown code snippet end

  7. Test Locally

    bash code snippet start

    hugo server -D

    bash code snippet end

    Visit http://localhost:1313 to see your site

Deployment Setup

  1. Create GitHub Actions Workflow Create .github/workflows/hugo.yml:

    yaml code snippet start

    name: Deploy Hugo site to Pages
    
    on:
      push:
        branches: ["main"]
      workflow_dispatch:
    
    permissions:
      contents: read
      pages: write
      id-token: write
    
    concurrency:
      group: "pages"
      cancel-in-progress: false
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
            with:
              submodules: true
          - name: Setup Hugo
            uses: peaceiris/actions-hugo@v2
            with:
              hugo-version: 'latest'
              extended: true
          - name: Build
            run: hugo --minify
          - name: Upload artifact
            uses: actions/upload-pages-artifact@v2
            with:
              path: ./public
    
      deploy:
        environment:
          name: github-pages
          url: ${{ steps.deployment.outputs.page_url }}
        runs-on: ubuntu-latest
        needs: build
        steps:
          - name: Deploy to GitHub Pages
            id: deployment
            uses: actions/deploy-pages@v2

    yaml code snippet end

  2. Push to GitHub

    bash code snippet start

    # Add all files
    git add .
    
    # Commit
    git commit -m "Initial blog setup"
    
    # Push to main branch
    git push -u origin main

    bash code snippet end

  3. Configure GitHub Pages

    • Go to your repository settings
    • Navigate to “Pages”
    • Under “Build and deployment”:
      • Source: Choose “GitHub Actions”

Writing New Posts

To create new posts:

  1. Run hugo new posts/post-name.md
  2. Edit the markdown file in content/posts/
  3. Set draft: false when ready to publish
  4. Commit and push changes
  5. GitHub Actions will automatically deploy your updates

Customization Tips

  1. Modify Theme Colors Create assets/css/extended.css to override theme styles:

    css code snippet start

    :root {
      --primary: #1a1a1a;
      --secondary: #4a4a4a;
      --link-color: #0066cc;
    }

    css code snippet end

  2. Add Custom Favicon Place your favicon.ico in the static folder

  3. Enable Syntax Highlighting Add to config.toml:

    toml code snippet start

    [markup]
      [markup.highlight]
        style = "github"
        lineNos = true

    toml code snippet end

// End of artifact


I’ve created a comprehensive guide for setting up your Hugo blog. The guide includes detailed steps for:

  1. Installing prerequisites (Git and Hugo)
  2. Setting up your blog locally
  3. Installing and configuring a minimalist theme
  4. Creating initial content
  5. Deploying to GitHub Pages
  6. Writing new posts
  7. Basic customization options

Would you like me to clarify any particular step or provide more details about a specific part of the setup process?

Me

In Hugo there is the following snippet:

code snippet start

{{ define "main" }}
  <article class="main">
    {{- with .Title }}
      <header>
        <h1 class="!mb-1">{{ . }}</h1>
      </header>
    {{ end -}}
    {{- with .Content }}
      {{ . }}
    {{ end -}}

code snippet end

Where is .Content defined?

Claude

In Hugo, .Content is a built-in variable that refers to the rendered Markdown content of the current page being processed. It’s not something you explicitly define - Hugo automatically populates it based on the content files in your project. Here’s how it works:

  1. When you create a content file like content/posts/my-first-post.md:

markdown code snippet start

---
title: "My First Post"
date: 2024-10-28
---

This is my blog post content.
Some more paragraphs here...

markdown code snippet end

  1. Hugo processes this file and:
    • The frontmatter (between ---) gets parsed into page variables (so .Title becomes “My First Post”)
    • Everything after the frontmatter is considered the page content and gets converted from Markdown to HTML
    • This converted HTML becomes available as .Content

So if your markdown file contains:

markdown code snippet start

This is **bold** text and here's a [link](https://example.com).

markdown code snippet end

Then .Content will contain the HTML:

html code snippet start

<p>This is <strong>bold</strong> text and here's a <a href="https://example.com">link</a>.</p>

html code snippet end

Some key points about .Content:

  • It’s automatically available for any content page
  • It contains the fully rendered HTML
  • It’s available in templates when rendering that page
  • It excludes the frontmatter
  • It’s part of Hugo’s Page variables (along with others like .Title, .Date, .Summary, etc.)
  • For non-content pages (like list pages or the homepage), .Content will be empty unless you have an _index.md file in the corresponding directory

Would you like me to explain any other aspects of Hugo’s template variables or content handling?

Me

How or where do I define the content for the homepage?

Claude

For the homepage in Hugo, you can define the content in one of two ways:

  1. Create an _index.md file in the root of your content directory:

plaintext code snippet start

content/
  _index.md    <- This will be your homepage content
  posts/
  about.md

plaintext code snippet end

The _index.md would look something like this:

markdown code snippet start

---
title: "Welcome to My Blog"
---

This is my homepage content. I can write anything here using Markdown.

## Recent Projects
- Project A
- Project B

You can find my blog posts in the Posts section.

markdown code snippet end

  1. Or you can create a custom homepage template in your theme’s layout directory:

plaintext code snippet start

layouts/
  index.html    <- This overrides the theme's homepage template

plaintext code snippet end

Here’s a sample index.html template that shows recent posts:

html code snippet start

{{ define "main" }}
  <div class="homepage">
    <h1>Welcome to My Blog</h1>

    <div class="intro">
      <p>Hi, I'm [Your Name]. I write about...</p>
    </div>

    <h2>Recent Posts</h2>
    {{ range first 5 (where .Site.RegularPages "Section" "posts") }}
      <article>
        <h3><a href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
        <time>{{ .Date.Format "January 2, 2006" }}</time>
        {{ .Summary }}
      </article>
    {{ end }}
  </div>
{{ end }}

html code snippet end

The best practice is usually to combine both approaches:

  1. Use content/_index.md for your main content that you want to edit frequently
  2. Use layouts/index.html for the structure and dynamic elements like recent posts

Then your index.html template could look like:

html code snippet start

{{ define "main" }}
  <div class="homepage">
    <!-- Your _index.md content -->
    {{ .Content }}

    <!-- Dynamic recent posts section -->
    <h2>Recent Posts</h2>
    {{ range first 5 (where .Site.RegularPages "Section" "posts") }}
      <article>
        <h3><a href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
        <time>{{ .Date.Format "January 2, 2006" }}</time>
        {{ .Summary }}
      </article>
    {{ end }}
  </div>
{{ end }}

html code snippet end

This gives you the flexibility to:

  • Edit the main content through Markdown (_index.md)
  • Control the layout and dynamic elements through the template (index.html)
  • Override the theme’s default homepage if needed

Would you like me to explain more about how to customize the homepage layout or how to work with Hugo’s template logic?

Me

I’m using this blog to collect notes, code snippets, learnings, etc. It’s more of a log for myself. Please create a nice short welcome header

Claude

I’ll create a welcoming but practical header that reflects the personal knowledge-base nature of your blog.

markdown code snippet start

---
title: "Digital Garden"
---

Welcome to my digital garden - a collection of notes, code snippets, and learnings I've gathered along the way. This space grows organically as I explore new technologies, solve problems, and document insights. It's more of a work-in-progress than a polished blog; you might find some paths well-trodden and others just beginning to sprout.

[Browse the latest entries →](/posts)

markdown code snippet end

Or a more concise alternative:

markdown code snippet start

---
title: "Code & Notes"
---

A personal logbook of technical discoveries, useful code snippets, and hard-won learnings. This is where I document things I don't want to forget and solutions I might need again.

[View entries →](/posts)

markdown code snippet end

Choose whichever style resonates more with you - you can place either version in your content/_index.md file. Would you like me to adjust the tone or length?