Skip to main content
  1. Recipes/

Build your homepage using Blowfish and Hugo

<span title="Reading time">11 mins</span><span class="px-2 text-primary-500">&middot;</span> <span class="mb-[2px]"> <a href="https://github.com/nunocoracao/blowfish/tree/main/exampleSite/content/guides/202310-blowfish-tutorial/index.md" class="text-lg hover:text-primary-500" rel="noopener noreferrer" target="_blank" title="Edit content" ><span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M490.3 40.4C512.2 62.27 512.2 97.73 490.3 119.6L460.3 149.7L362.3 51.72L392.4 21.66C414.3-.2135 449.7-.2135 471.6 21.66L490.3 40.4zM172.4 241.7L339.7 74.34L437.7 172.3L270.3 339.6C264.2 345.8 256.7 350.4 248.4 353.2L159.6 382.8C150.1 385.6 141.5 383.4 135 376.1C128.6 370.5 126.4 361 129.2 352.4L158.8 263.6C161.6 255.3 166.2 247.8 172.4 241.7V241.7zM192 63.1C209.7 63.1 224 78.33 224 95.1C224 113.7 209.7 127.1 192 127.1H96C78.33 127.1 64 142.3 64 159.1V416C64 433.7 78.33 448 96 448H352C369.7 448 384 433.7 384 416V319.1C384 302.3 398.3 287.1 416 287.1C433.7 287.1 448 302.3 448 319.1V416C448 469 405 512 352 512H96C42.98 512 0 469 0 416V159.1C0 106.1 42.98 63.1 96 63.1H192z"/></svg> </span> </span></a > </span>
Nuno Coração
Open-Source Blowfish tutorial blowfish hugo
Author
Nuno Coração
Theme Creator
Table of Contents

Just one year ago, I created Blowfish, a Hugo theme crafted to build my unique vision for my personal homepage. I also decided to make it an open-source project. Fast-forward to today, and Blowfish has transformed into a thriving open-source project with over 600 stars on GitHub and a user base of hundreds. In this tutorial, I’ll show you how to get started and have your website running in a couple of minutes.

nunocoracao/blowfish

Personal Website & Blog Theme for Hugo

HTML
773
236

TL;DR #

The goal of this guide is to walk a newcomer to Hugo on how to install, manage, and publish your own website. The final version of the code is available in this repo - for those that would like to jump to the end.

Tutorial example

The visual style is just one of the many possibilities available in Blowfish. Users are encouraged to check the documentation page and learn how to customize the theme to their needs. Additionally, there are already great examples of the theme from other users available for inspiration. Blowfish also offers several extra features in the form of shortcodes available out of the box in the theme - check them out here and get inspired.

Setup your environment #

Let’s begin by installing all the tools you need. This guide will cover the steps for Mac so these instructions might not apply to your hardware and OS. If you are on Windows or Linux, please consult the guides on how to install Hugo, and GitHub’s CLI for your OS.

Anyway, if you are using MacOS let’s install brew - a package manager for mac - as that will help installing and managing the other tools.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Once brew is installed let’s install Git, Hugo and GitHub’s CLI.

brew install git
brew install hugo
brew install gh

Create a folder for your code and open a terminal session into it (I chose blowfish-tutorial in the commands below, feel free to call the folder whatever you want).

mkdir blowfish-tutorial
cd blowfish-tutorial

Once inside the folder, the next step is to initialize your local git repo.

git init -b main

Now, let’s create and sync the local repo to a GitHub repo so that your code is stored remotely.

gh auth login
gh repo create
git push --set-upstream origin main

Check the image below for the options I selected for this guide, again feel free to change names and description to your use-case.

gh repo create example

Finally, create a .gitignore file which allows you to exclude certain files from your repo automatically. I would start with something like the example below.

#others
node_modules
.hugo_build.lock

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes

# Hugo
public

The last step is to save all the changes to the repo.

git add .
git commit -m “initial commit”
git push

Create site and configure it #

With all the tools ready, creating and configuring your site will be easy. Still within the folder you created in the last section, let’s create an empty Hugo website (with no theme).

hugo new site --force .

Once the scaffolding finishes, try the command below to run your page. Open a browser on https://localhost:1313 to see your site…

hugo server

Ups… Page not found – right? This was expected, even though you created a website, Hugo doesn’t give any default experience – aka your site doesn’t have any page to show.

Next step, let’s install Blowfish using git submodules which will make it easier to manage and upgrade to new versions in the future.

git submodule add -b main https://github.com/nunocoracao/blowfish.git themes/blowfish

Next, create the following folder structure at the root of your code directory - config/_default/. Now you will need to download these files and place them in _default folder you just created. The final structure should look something like this.

config/_default/
├─ config.toml
├─ languages.en.toml
├─ markup.toml
├─ menus.en.toml
└─ params.toml
`

Open the config.toml and uncomment the line theme = “blowfish” and you are ready to go. Try the running the site again and check the result at https://localhost:1313

hugo server

You should see something like the image below. Not much yet as we didn’t add any content, but the main skeleton for Blowfish is already in place - just requires configuration.

blowfish empty site

Now let’s configure the theme.

FYI This guide will not cover in detail what each parameter available in Blowfish does – for everything available and how to use it, check Blowfish documentation for every option in every file.

menus.en.toml #

This file defines your menu structure, for the top banner and the footer. For this guide, let’s create two menu sections: one for Posts and one for Tags.

  • Posts - will display the full list of entries
  • Tags - automatically generated based on tags placed on each article

To achieve this, make sure the following entries exist in the menus.en.toml file. Once the changes are done, you should see the menus appearing by re-running hugo server.

[[main]]
  name = "Posts"
  pageRef = "posts"
  weight = 10

[[main]]
  name = "Tags"
  pageRef = "tags"
  weight = 30

languages.en.toml #

This file will configure your main details as the author of the website. Change the section below to reflect your details.

[author]
   name = "Your name here"
   image = "profile.jpg"
   headline = "I'm only human"
   bio = "A little bit about you" # appears in author card for each article

The images for the website should be placed in the assets folder. For this step, please add a profile picture to that folder named profile.jpg or change the configuration above to the filename you chose. If you don’t have a profile image available, you can use the one below for the tutorial.

profile
assets/profile.jpg

The last step is configuring your links – social media, GitHub, etc. The file includes all the supported options, but they are commented. You are welcome to uncomment everything and delete the ones you would rather not use. Replace the right links on the ones you decided to keep. You can also change the order.

params.toml #

This is the main configuration file for Blowfish. Most of the visual options or customization available can be configured using it, and it covers several areas of the theme. For this tutorial, I decided to use a background layout - check other layouts for Blowfish’s landing page - with the Neon color scheme - you can pick a different color scheme if you want to - check this list or create your own.

Add an image.jpg to the assets folder which will be the background for the site. You can also download the examples I am using in this tutorial.

background
assets/image.jpg

Now let’s jump into the params.toml and start configuring the file. I will focus only on the values that need to be changed, don’t delete the rest of the file without reading the docs. Let’s begin by making sure that we have the right color scheme, that image optimization is on, and configure the default background image.

colorScheme = "neon"
disableImageOptimization = false
defaultBackgroundImage = "image.jpg" # used as default for background images 

Next, let’s configure our homepage. We’re going with the background layout, configuring the homepage image and recent items. Furthermore, we are using the card view for items in the recent category. Finally, let’s configure the header to be fixed.

[homepage]
  layout = "background" # valid options: page, profile, hero, card, background, custom
  homepageImage = "image.jpg" # used in: hero, and card
  showRecent = true
  showRecentItems = 6
  showMoreLink = true
  showMoreLinkDest = "/posts"
  cardView = true
  cardViewScreenWidth = false
  layoutBackgroundBlur = true # only used when layout equals background

[header]
  layout = "fixed"

Now configure how the article and list pages will look. Here are the configurations for those.

[article]
  showHero = true
  heroStyle = "background" 
  showSummary = true
  showTableOfContents = true
  showRelatedContent = true
  relatedContentLimit = 3

[list]
  showCards = true
  groupByYear = false
  cardView = true

If you run hugo server again, you should see something like the image below.

blowfish no articles

Adding content to your site #

Create a folder to place your posts in /content/posts. This was also the directory configured in your menu to list all the articles. Within that folder, let’s create a new directory and give it the name myfirstpost. Within it create an index.md file – your article and place a featured.jpg or .png for in the same directory as the thumbnail for the article. Use the example below to get started. The first lines in the file are the Front Matter, which tell Hugo what the look and experience of the article will be – different themes support different params for this. Check the docs for more info.

---
title: "My first post"
date: 2023-08-14
draft: false
summary: "This is my first post on my site"
tags: ["space"]
---

## A sub-title

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi nibh nisl, vulputate eu lacus vitae, maximus molestie libero. Vestibulum laoreet, odio et sollicitudin sollicitudin, quam ligula tempus urna, sed sagittis eros eros ac felis. In tristique tortor vitae lacinia commodo. Mauris venenatis ultrices purus nec fermentum. Nunc sit amet aliquet metus. Morbi nisl felis, gravida ac consequat vitae, blandit eu libero. Curabitur porta est in dui elementum porttitor. Maecenas fermentum, tortor ac feugiat fringilla, orci sem sagittis massa, a congue risus ipsum vel massa. Aliquam sit amet nunc vulputate, facilisis neque in, faucibus nisl.

You can create additional articles to see what your site will look like once there is content in it. Your site should look like the images below. The main page shows the recent articles, each article is connected through others automatically via related section, you have tag aggregation, and full-text search.

Ship it #

The only thing missing is to ship your site. I will be using Firebase for hosting - it’s a free alternative and provides more advanced features if you are creating something more complex. Go to firebase and create a new project. Once that is done, let’s switch to the CLI as it will make it easier to configure everything.

Let’s install firebase’s CLI - if not on Mac check install instructions on Firebase.

brew install firebase

Now log in and init firebase hosting for the project.

firebase login
firebase init

Select hosting and proceed.

firebase init

Follow the image below for the options I recommend. Make sure to set up the workflow files for GitHub actions. These will guarantee that your code will be deployed once there is a change to the repo.

firebase options

However, those files will not work out-of-box, as Hugo requires extra steps for the build to work. Please copy and paste the code blocks below to the respective files within the .github folder, but keep the original projectId in the files generated by firebase.

firebase-hosting-merge.yml #

# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on merge
'on':
  push:
    branches:
      - main
jobs:
  build_and_deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Hugo setup
        uses: peaceiris/actions-hugo@v2.6.0
        env:
          ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'

      - name: Check out code into the Go module directory
        uses: actions/checkout@v4
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Build with Hugo
        env:
          # For maximum backward compatibility with Hugo modules
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production
        run: hugo -E -F --minify -d public

      - name: Deploy Production
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_BLOWFISH_TUTORIAL }}'
          channelId: live
          projectId: blowfish-tutorial

firebase-hosting-pull-request.yml #

# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools

name: Deploy to Firebase Hosting on PR
'on': pull_request
jobs:
  build_and_preview:
    if: '${{ github.event.pull_request.head.repo.full_name == github.repository }}'
    runs-on: ubuntu-latest
    steps:
      - name: Hugo setup
        uses: peaceiris/actions-hugo@v2.6.0
        env:
          ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'

      - name: Check out code into the Go module directory
        uses: actions/checkout@v4
        with:
          submodules: true  # Fetch Hugo themes (true OR recursive)
          fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Build with Hugo
        env:
          # For maximum backward compatibility with Hugo modules
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production
        run:  hugo -E -F --minify -d public

      - name: Deploy preview
        uses: FirebaseExtended/action-hosting-deploy@v0
        with:
          repoToken: '${{ secrets.GITHUB_TOKEN }}'
          firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_BLOWFISH_TUTORIAL }}'
          expires: 30d
          channelId: preview-${{ github.event.number }}
          projectId: blowfish-tutorial

The last step is committing your code to GitHub and let the workflows you created take care of deploying your site. Since we configured GitHub actions, this will trigger a job that will configure and deploy your site automatically.

git add .
git commit -m "add github actions workflows"  
git push  

If the actions tab for your repo, you should see something like this.

gh actions

Once all the steps finish, your Firebase console should show something like the image below - including the links to see your app – I got a version of this tutorial running on https://blowfish-tutorial.web.app/.

firebase console

Conclusion and Next Steps #

Now you have your first version of your homepage. You can make changes locally and once you commit your code they will automatically be reflected online. What shall you do next? I’ll leave you with some useful links to get you inspired and learn more about Blowfish and Hugo.

blowfish final

Related

Multiple Authors
<span title="Reading time">1 min</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_samples/multiple-authors/index.md" title="views">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg> </span> </span> </span><span class="px-2 text-primary-500">&middot;</span><span> <span id="likes_samples/multiple-authors/index.md" title="likes">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg> </span> </span> </span>
Nuno Coração
Dummy Second Author
authors sample
Multiple Authors
<span title="Reading time">5 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_docs/multi-author/index.md" title="views">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"> <path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg> </span> </span> </span><span class="px-2 text-primary-500">&middot;</span><span> <span id="likes_docs/multi-author/index.md" title="likes">0</span> <span class="inline-block align-text-bottom"> <span class="relative block icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg> </span> </span> </span>
authors config docs