Skip to main content
  1. Documentation/

Advanced Customisation

<span title="Reading time">9 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_docs/advanced-customisation/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/advanced-customisation/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><span class="px-2 text-primary-500">&middot;</span><span> <button id="likes_button" class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400" onclick="process_article()"> <span id="likes_button_heart" style="display:none" 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 id="likes_button_emtpty_heart" 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="M244 84L255.1 96L267.1 84.02C300.6 51.37 347 36.51 392.6 44.1C461.5 55.58 512 115.2 512 185.1V190.9C512 232.4 494.8 272.1 464.4 300.4L283.7 469.1C276.2 476.1 266.3 480 256 480C245.7 480 235.8 476.1 228.3 469.1L47.59 300.4C17.23 272.1 0 232.4 0 190.9V185.1C0 115.2 50.52 55.58 119.4 44.1C164.1 36.51 211.4 51.37 244 84C243.1 84 244 84.01 244 84L244 84zM255.1 163.9L210.1 117.1C188.4 96.28 157.6 86.4 127.3 91.44C81.55 99.07 48 138.7 48 185.1V190.9C48 219.1 59.71 246.1 80.34 265.3L256 429.3L431.7 265.3C452.3 246.1 464 219.1 464 190.9V185.1C464 138.7 430.4 99.07 384.7 91.44C354.4 86.4 323.6 96.28 301.9 117.1L255.1 163.9z"/></svg> </span> </span> <span id="likes_button_text">&nbsp;Like</span> </button> </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/docs/advanced-customisation/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>
Advanced css docs
Table of Contents
Documentation - This article is part of a series.
Part 13: This Article

There are many ways you can make advanced changes to Blowfish. Read below to learn more about what can be customised and the best way of achieving your desired result.

If you need further advice, post your questions on GitHub Discussions.

Hugo project structure #

Before leaping into it, first a quick note about Hugo project structure and best practices for managing your content and theme customisations.

In summary: Never directly edit the theme files. Only make customisations in your Hugo project’s sub-directories, not in the themes directory itself.

Blowfish is built to take advantage of all the standard Hugo practices. It is designed to allow all aspects of the theme to be customised and overriden without changing any of the core theme files. This allows for a seamless upgrade experience while giving you total control over the look and feel of your website.

In order to achieve this, you should never manually adjust any of the theme files directly. Whether you install using Hugo modules, as a git submodule or manually include the theme in your themes/ directory, you should always leave these files intact.

The correct way to adjust any theme behaviour is by overriding files using Hugo’s powerful file lookup order. In summary, the lookup order ensures any files you include in your project directory will automatically take precedence over any theme files.

For example, if you wanted to override the main article template in Blowfish, you can simply create your own layouts/_default/single.html file and place it in the root of your project. This file will then override the single.html from the theme without ever changing the theme itself. This works for any theme files - HTML templates, partials, shortcodes, config files, data, assets, etc.

As long as you follow this simple practice, you will always be able to update the theme (or test different theme versions) without worrying that you will lose any of your custom changes.

Change image optimization settings #

Hugo has various builtin methods to resize, crop and optimize images.

As an example - in layouts/partials/article-link/card.html, you have the following code:

{{ with .Resize "600x" }}
<div class="w-full thumbnail_card nozoom" style="background-image:url({{ .RelPermalink }});"></div>
{{ end }}

The default behavior of Hugo here is to resize the image to 600px keeping the ratio.

It is worth noting here that default image configurations such as anchor point can also be set in your site configuration as well as in the template itself.

See the Hugo docs on image processing for more info.

Colour schemes #

Blowfish ships with a number of colour schemes out of the box. To change the basic colour scheme, you can set the colorScheme theme parameter. Refer to the Getting Started section to learn more about the built-in schemes.

In addition to the default schemes, you can also create your own and re-style the entire website to your liking. Schemes are created by by placing a <scheme-name>.css file in the assets/css/schemes/ folder. Once the file is created, simply refer to it by name in the theme configuration.

Note: generating these files manually can be hard, I’ve built a nodejs terminal tool to help with that, Fugu. In a nutshell, you pass the main three hex values of your color pallette and the program will output a css file that can be imported directly into Blowfish.

Blowfish defines a three-colour palette that is used throughout the theme. The three colours are defined as neutral, primary and secondary variants, each containing ten shades of colour.

Due to the way Tailwind CSS 3.0 calculates colour values with opacity, the colours specified in the scheme need to conform to a particular format by providing the red, green and blue colour values.

:root {
  --color-primary-500: 139, 92, 246;
}

This example defines a CSS variable for the primary-500 colour with a red value of 139, green value of 92 and blue value of 246.

Use one of the existing theme stylesheets as a template. You are free to define your own colours, but for some inspiration, check out the official Tailwind colour palette reference.

Overriding the stylesheet #

Sometimes you need to add a custom style to style your own HTML elements. Blowfish provides for this scenario by allowing you to override the default styles in your own CSS stylesheet. Simply create a custom.css file in your project’s assets/css/ folder.

The custom.css file will be minified by Hugo and loaded automatically after all the other theme styles which means anything in your custom file will take precedence over the defaults.

Using additional fonts #

Blowfish allows you to easily change the font for your site. After creating a custom.css file in your project’s assets/css/ folder, place you font file inside a fonts folder withing the static root folder.

.
├── assets
│   └── css
│       └── custom.css
...
└─── static
    └── fonts
        └─── font.ttf

This makes the font available to the website. Now, the font can just import it in your custom.css and replaced wherever you see fit. The example below shows what replacing the font for the entire html would look like.

@font-face {
    font-family: font;
    src: url('/fonts/font.ttf');
}

html {
    font-family: font;
}

Adjusting the font size #

Changing the font size of your website is one example of overriding the default stylesheet. Blowfish makes this simple as it uses scaled font sizes throughout the theme which are derived from the base HTML font size. By default, Tailwind sets the default size to 12pt, but it can be changed to whatever value you prefer.

Create a custom.css file using the instructions above and add the following CSS declaration:

/* Increase the default font size */
html {
  font-size: 13pt;
}

Simply by changing this one value, all the font sizes on your website will be adjusted to match this new size. Therefore, to increase the overall font sizes used, make the value greater than 12pt. Similarly, to decrease the font sizes, make the value less than 12pt.

Building the theme CSS from source #

If you’d like to make a major change, you can take advantage of Tailwind CSS’s JIT compiler and rebuild the entire theme CSS from scratch. This is useful if you want to adjust the Tailwind configuration or add extra Tailwind classes to the main stylesheet.

Note: Building the theme manually is intended for advanced users.

Let’s step through how building the Tailwind CSS works.

Tailwind configuration #

In order to generate a CSS file that only contains the Tailwind classes that are actually being used the JIT compiler needs to scan through all the HTML templates and Markdown content files to check which styles are present in the markup. The compiler does this by looking at the tailwind.config.js file which is included in the root of the theme directory:

// themes/blowfish/tailwind.config.js

module.exports = {
  content: [
    "./layouts/**/*.html",
    "./content/**/*.{html,md}",
    "./themes/blowfish/layouts/**/*.html",
    "./themes/blowfish/content/**/*.{html,md}",
  ],

  // and more...
};

This default configuration has been included with these content paths so that you can easily generate your own CSS file without needing to modify it, provided you follow a particular project structure. Namely, you have to include Blowfish in your project as a subdirectory at themes/blowfish/. This means you cannot easily use Hugo Modules to install the theme and you must go down either the git submodule (recommended) or manual install routes. The Installation docs explain how to install the theme using either of these methods.

Project structure #

In order to take advantage of the default configuration, your project should look something like this…

.
├── assets
│   └── css
│       └── compiled
│           └── main.css  # this is the file we will generate
├── config  # site config
│   └── _default
├── content  # site content
│   ├── _index.md
│   ├── projects
│   │   └── _index.md
│   └── blog
│       └── _index.md
├── layouts  # custom layouts for your site
│   ├── partials
│   │   └── extend-article-link/simple.html
│   ├── projects
│   │   └── list.html
│   └── shortcodes
│       └── disclaimer.html
└── themes
    └── blowfish  # git submodule or manual theme install

This example structure adds a new projects content type with its own custom layout along with a custom shortcode and extended partial. Provided the project follows this structure, all that’s required is to recompile the main.css file.

Install dependencies #

In order for this to work you’ll need to change into the themes/blowfish/ directory and install the project dependencies. You’ll need npm on your local machine for this step.

cd themes/blowfish
npm install

Run the Tailwind compiler #

With the dependencies installed all that’s left is to use Tailwind CLI to invoke the JIT compiler. Navigate back to the root of your Hugo project and issue the following command:

cd ../..
./themes/blowfish/node_modules/tailwindcss/lib/cli.js -c ./themes/blowfish/tailwind.config.js -i ./themes/blowfish/assets/css/main.css -o ./assets/css/compiled/main.css --jit

It’s a bit of an ugly command due to the paths involved but essentially you’re calling Tailwind CLI and passing it the location of the Tailwind config file (the one we looked at above), where to find the theme’s main.css file and then where you want the compiled CSS file to be placed (it’s going into the assets/css/compiled/ folder of your Hugo project).

The config file will automatically inspect all the content and layouts in your project as well as all those in the theme and build a new CSS file that contains all the CSS required for your website. Due to the way Hugo handles file hierarchy, this file in your project will now automatically override the one that comes with the theme.

Each time you make a change to your layouts and need new Tailwind CSS styles, you can simply re-run the command and generate the new CSS file. You can also add -w to the end of the command to run the JIT compiler in watch mode.

Make a build script #

To fully complete this solution, you can simplify this whole process by adding aliases for these commands, or do what I do and add a package.json to the root of your project which contains the necessary scripts…

// package.json

{
  "name": "my-website",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "server": "hugo server -b http://localhost -p 8000",
    "dev": "NODE_ENV=development ./themes/blowfish/node_modules/tailwindcss/lib/cli.js -c ./themes/blowfish/tailwind.config.js -i ./themes/blowfish/assets/css/main.css -o ./assets/css/compiled/main.css --jit -w",
    "build": "NODE_ENV=production ./themes/blowfish/node_modules/tailwindcss/lib/cli.js -c ./themes/blowfish/tailwind.config.js -i ./themes/blowfish/assets/css/main.css -o ./assets/css/compiled/main.css --jit"
  },
  // and more...
}

Now when you want to work on designing your site, you can invoke npm run dev and the compiler will run in watch mode. When you’re ready to deploy, run npm run build and you’ll get a clean Tailwind CSS build.

🙋‍♀️ If you need help, feel free to ask a question on GitHub Discussions.

Documentation - This article is part of a series.
Part 13: This Article

Related

Hosting & Deployment
<span title="Reading time">4 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_docs/hosting-deployment/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/hosting-deployment/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>
docs hosting deployment github netlify render
Markdown
<span title="Reading time">3 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_samples/markdown/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/markdown/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>
markdown css html sample
Firebase: Views & Likes
<span title="Reading time">2 mins</span><span class="px-2 text-primary-500">&middot;</span><span> <span id="views_docs/firebase-views/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/firebase-views/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>
firebase views likes