Skip to content

➕ Extend Hugo Blox

How can you perform more advanced customization or integrate new third-party services?

Create a blox

Create a new blox

Create a shortcode

Create a new shortcode


The Hugo hooks system enables you to easily inject your own code into parts of a site for more advanced customization. No need to edit or override any of the framework’s files!

The following hooks are supported:

  • head-start
  • head-end
  • body-end
  • footer-start
  • toc-start (for the right sidebar table of contents only)
  • toc-end (for the right sidebar table of contents only)

To inject your code into one of the above places, create a file at layouts/partials/hooks/<hook>/<your-filename>.html, replacing <hook> with one of the hook names above and <your-filename> with any name, such as custom. You’ll need to create these new folders relative to the root of your site.

For example, to inject your code into the site head, you can create a file at layouts/partials/hooks/head-end/custom.html.

You can have multiple files in each hook folder, with Hugo determining the order which they are rendered in.

Add scripts (JS)

How can I add custom Javascript to my site, such as a third-party analytics script?

Create a file at layouts/partials/hooks/body-end/custom.html and paste your Javascript <script>...</script> within it.

For older sites prior to v5.6, create a file at layouts/partials/custom_js.html instead.

Custom head

How can I add custom metadata to my website’s <head> tag?

Create a file at layouts/partials/hooks/head-end/custom.html and paste your HTML tags within it.

For old Bootstrap-styled sites prior to v5.6, create a file at layouts/partials/custom_head.html instead.

Tip: This approach can also be used for adding third party scripts with an async or defer attribute to the site head.

Customize style (CSS)

To personalize Hugo Blox, start by choosing a light or dark appearance and a color theme in config/_default/params.yaml.

For further personalization, you can create your own color theme and font theme.

If advanced style customization is required, CSS code can be written to override or enhance the existing styles.

For Tailwind-styled sites:

  1. Create the assets/css/ folder if it doesn’t exist
  2. Create a file named custom.css in the assets/css/ folder
  3. Add your custom CSS code to the file you created and re-run Hugo to view changes

For Bootstrap-styled sites:

  1. Create the assets/scss/ folder if it doesn’t exist
  2. Create a file named custom.scss in the assets/scss/ folder
  3. Add your custom CSS code to the file you created and re-run Hugo to view changes


Custom CSS can also be added between HTML <style>...</style> tags within hooks (see Hooks section above).

Recompile Tailwind

If you wish to make changes to the built-in Tailwind styles, or use your own custom Tailwind-styled blocks, Tailwind will need to be recompiled for your site.

Tailwind can be recompiled by running the following command from the root of your site:

Terminal window
npm install -g pnpm && hugo && hugo mod vendor && cd ./_vendor/ && pnpm i && export HB_TW_CONTENT='../../../../../../hugo_stats.json' && npx tailwindcss -i ./assets/css/styles.css --config ./tailwind.config.js -o ../../../../../../assets/dist/wc.min.css --minify --postcss && cd ../../../../../../ && rm -rf _vendor

Note the use of && to combine multiple commands as one. If you experience issues, you may wish to run each of these sub-commands one by one to debug the issue.

Override a component

Hugo uses a template lookup which enables you to override any of Hugo Blox’s files without directly changing them.

Since you do not modify any of Hugo Blox’s files directly, this makes it easier to update your theme in the future.

To override any file in the theme, such as a layout or component, simply copy the file you are interested in from the version of the Hugo module your site uses and paste it in your site folder using a similar path.

Check your module version in go.mod and then select the closest version tag from GitHub’s branch/tag dropdown box on the top left of GitHub’s repository interface (by default, the selector displays main which represents the latest development version of the files).

To understand how this works, familiarize yourself with Hugo’s template lookup and then take a look at the example below.

Example: Custom Page Layout

For example, say we wish to change the default page layout for blog articles.

Let’s copy the relevant file blox-tailwind/layouts/_default/single.html to layouts/_default/single.html at the root of your site, creating the layouts/_default/ folders if they do not already exist.

Now you can make changes to your copy of the file.

Example: Custom Navbar

For example, say we wish to add some HTML code to the navigation bar.

Let’s copy the relevant file blox-tailwind/layouts/partials/components/headers/navbar.html to layouts/partials/components/headers/my-navbar.html at the root of your site, creating the layouts/partials/components/headers/ folders if they do not already exist.

Now you can make changes to your copy of the file.

To use your new navbar blox named my-navbar, reference it in your config/_default/params.ysml:

enable: true
blox: "my-navbar"

Permalinks, or permanent links, are URLs to individual pages and posts on your website. They are permanent web addresses which can be used to link to your content. Using Hugo’s permalinks option these can be easily customized. For example, the blog post URL can be changed to the form EXAMPLE.COM/2016/05/01/my-post-slug by adding the following near the end of your config/_default/hugo.yaml:

post: '/:year/:month/:day/:slug'

Where :slug defaults to the filename of the post, excluding the file extension. However, slug may be overridden on a per-post basis if desired, simply by setting slug: my-short-post-title in your front matter.

Example 2: let’s consider changing the URL path of posts from post/ to blog/. First, add the following parameters to your config/_default/hugo.yaml:

post: '/blog/:slug'

Then add aliases: [/blog/] to your post archive page at post/ so that it can be accessed from the /blog/ URL.

Theming Custom Integrations

How can you theme your customizations and third-party plugins according to the user’s light/dark mode?

Theming can be performed with CSS styles and/or JS.

Plugins can be themed by creating a custom style (see Style section above) and prefixing dark components with .dark such that you might have:

/* Light component */
.your-class {
color: black;
/* Dark component */
.dark .your-class {
color: white;

Furthermore, Hugo Blox emits an hbThemeChange event to help support themeable community plugins.

We can add some JavaScript using the approach in the Add Scripts section above to listen to the event and perform some action.

For example, create a file at layouts/partials/hooks/body-end/custom.html containing the following snippet:

document.addEventListener('hbThemeChange', (e) => {
// Replace the example message below with the action you wish to perform when a user changes the theme
console.log('isDarkTheme? ' + e.detail.isDarkTheme());

Then in your browser, right-click a page of your site and click Inspect. Then, in the Console tab, you’ll see the above message everytime you change the theme between light and dark.