How to Create a Free Personal Blog Using Hugo and GitHub Pages

I have had more spare time since I changed my job earlier this year. I have been contemplating ways to share my life and technology experiences while also enhancing my writing skills. Although Wordpress appears to be a quite popular platform for personal blogs, I’d rather not deal with ongoing expenses for servers or disruptions caused by irrelevant technical tasks like virtual machine and database configurations.

That’s why using an open source Static Site Generator along with a free web hosting service seems like the ideal approach for me. Here are the tools I used:

  • Hugo: An open source Static Site Generator written in Go that allows you to create fast and flexible websites such as personal blogs, company homepages, galleries and many more.
  • GitHub Pages: A free web hosting service provided by GitHub that allows you to host your site directly from your GitHub repository.

In the end, I built this site to serve as my personal blog by following the documentations of those tools. I decided to document the entire process as a future reference for myself, and for anyone else, like you, who happens to come across this post by chance.


There are 3 other tools that required to be installed besides Hugo: Git, Go and Dart Sass. I installed these tools on both my Windows 10 PC and MacBook.

I installed Chocolatey first since both Hugo and Sass can also be installed through Chocolatey easily.

  1. Open PowerShell as administrator and type:

    1
    
    Get-ExecutionPolicy
    

    If it returns Restricted, run the following command:

    1
    
    Set-ExecutionPolicy AllSigned
    
  2. Run the following command to install Chocolatey:

    1
    
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
    
  3. Wait for the command to complete, then confirm Chocolatey has been installed correctly:

    1
    
    choco -?
    

After installing Chocolatey, install Hugo:

1
choco install hugo-extended

Download the standalone installer from download page and install it.

Follow this documentation to download and install Go.

Run following command in PowerShell:

1
choco install sass

Install homebrew whether it is not installed yet.

Open Terminal and run following command:

1
brew install hugo

Run following command:

1
brew install git

Follow this documentation to download and install Go.

Run following command:

1
brew install sass/sass/sass

Run following commands in PowerShell or Terminal.

  1. Create the directory structure in the mysite directory:

    1
    
    hugo new site mysite
    
  2. Change working directory to the root of mysite:

    1
    
    cd mysite
    
  3. Create an empty Git repository in the working directory:

    1
    
    git init
    
  4. Clone the DoIt theme to the theme directory, adding it to mysite as a Git submodule:

    1
    
    git submodule add git submodule add https://github.com/HEIGE-PCloud/DoIt.git themes/DoIt themes/DoIt
    
  5. Apply theme:

    1
    
    echo "theme = 'DoIt'" >> hugo.toml
    
  6. Now start Hugo’s development server and open the URL displayed in terminal to have a look at the site we created.

    1
    
    hugo server
    

Development server can be stopped by pressing Ctrl + C.

Add a post

  1. Add a new post to mysite:

    1
    
    hugo new content posts/my-first-post.md
    
  2. A markdown file was created in content/posts directory by Hugo. Open the file:

    1
    2
    3
    4
    5
    
    ---
    title: "My First Post"
    date: 2023-07-19T17:51:29+09:00
    draft: true
    ---
    
  3. Add some content to the body of the post and save the file.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    ---
    title: "My First Post"
    date: 2023-07-19T17:51:29+09:00
    draft: true
    ---
    
    ## Introduction
    
    Hello!
    This is my first post.
    
  4. Start Hugo’s development server again and have a look at the post:

    1
    
    hugo server -D
    
  1. A GitHub account is required for hosting site on GitHub Pages. Sign up an account if you don’t already have one.

  2. Create a new repository. Usually, a Pro(paid) account is needed to host site from private repository. Create a public repository if you want to host your site free.1

    Create a new repository

  3. Push local repository of mysite to GitHub:

    1
    2
    3
    
    git remote add origin [email protected]:$GitHubUserName/$RepositoryName.git
    git branch -M main
    git push -u origin main
    
  4. Open GitHub repository page. Click on Settings > Pages.

    Open Pages

  5. Change the Source to GitHub Actions.

    Change Source

  6. Create an empty file in local repository.

    .github/workflows/hugo.yaml

  7. Copy and paste the following YAML into the file created in step6. Change the branch name and Hugo version.(If you used the command in step3, the branch name should be main. And Hugo version can be confirmed by running hugo version in Terminal. It is better to use the same version in both local and remote repository.)

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    
    # Sample workflow for building and deploying a Hugo site to GitHub Pages
    name: Deploy Hugo site to Pages
    
    on:
    # Runs on pushes targeting the default branch
    push:
        branches:
        - main
    
    # Allows you to run this workflow manually from the Actions tab
    workflow_dispatch:
    
    # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
    permissions:
    contents: read
    pages: write
    id-token: write
    
    # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
    # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
    concurrency:
    group: "pages"
    cancel-in-progress: false
    
    # Default to bash
    defaults:
    run:
        shell: bash
    
    jobs:
    # Build job
    build:
        runs-on: ubuntu-latest
        env:
        HUGO_VERSION: 0.115.3
        steps:
        - name: Install Hugo CLI
            run: |
            wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
            && sudo dpkg -i ${{ runner.temp }}/hugo.deb          
        - name: Install Dart Sass
            run: sudo snap install dart-sass
        - name: Checkout
            uses: actions/checkout@v3
            with:
            submodules: recursive
            fetch-depth: 0
        - name: Setup Pages
            id: pages
            uses: actions/configure-pages@v3
        - name: Install Node.js dependencies
            run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
        - name: Build with Hugo
            env:
            # For maximum backward compatibility with Hugo modules
            HUGO_ENVIRONMENT: production
            HUGO_ENV: production
            run: |
            hugo \
                --gc \
                --minify \
                --baseURL "${{ steps.pages.outputs.base_url }}/"          
        - name: Upload artifact
            uses: actions/upload-pages-artifact@v1
            with:
            path: ./public
    
    # Deployment job
    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
    
  8. Commit the change to local repository and push to GitHub.

  9. Click on Actions from GitHub repository. The orange circle indicates the workflow is running now:

    Workflow running

  10. After the workflow finished, the indicator will change to a green check.

    Workflow finished

  11. Click on the workflow. the url to mysite will be shown:

    Build and deploy

  12. Click on the url to access mysite that is being hosted by GitHub Pages now. Normally, the URL should be in the format https://$GitHubUsername.github.io/$RepositoryName1. However, I have been using a custom domain which is why my URL is different. From now on, whenever a change is made to this GitHub repository, GitHub will rebuild mysite and deploy the changes.

If you have any questions or advice, leave me a comment below and I will try my best to respond!

Related Content