Custom themes

Custom themes contain HTML and CSS templates using the Hugo blogging engine. Creating a new template in a custom theme will override a template with the same name in the built-in design you’ve chosen for your blog.

Getting started with themes

Creating a basic custom theme lets you edit any of the HTML for your blog:

  1. Click on Posts → Design → Edit Custom Themes → New Theme
  2. Give your theme a name and save it.
  3. Click on your theme to see its templates. If you haven’t imported a custom theme, you will see the default templates for your blog’s current design.
  4. Click on any of the templates to edit it.
  5. Go back to the Posts → Design page and select your new custom theme.

Importing a new theme

You can also pick the Blank design and clone an existing GitHub repository when creating your new custom theme. will download that repository and make its files available for editing in your custom theme.

Some special templates used by are stored in the Blank design and used by all themes. When picking a template to use, first looks in your custom theme, then one of the built-in designs, and then the Blank design. If you need to customize one of these special templates, you can copy it from our repository on GitHub.

There’s a 6-minute screencast video showing more about how custom themes work on YouTube.

Sharing themes

If you’ve created a theme and want to share it with other users, save it in its own repository on GitHub. Users can clone your repository when starting their own custom theme. If your custom theme depends on an existing built-in design, make sure to tell potential users of the theme to select that design too.

File types supports editing many common file types such as HTML files, Markdown, JSON, and CSS. When cloning a repository into a new custom theme, will skip any files that can’t be edited. For example, it will not copy image files. If you need to use an image file in your theme, upload it to your blog under Posts → Uploads.


For compatibility with Plugins, the following should be included in the <head> of your theme:

{{ range .Site.Params.plugins_css }}
  <link rel="stylesheet" href="{{ . }}">
{{ end }}
{{ range $filename := .Site.Params.plugins_html }} 
  {{ partial $filename $ }}
{{ end }}

According to this post on, we should also add code to the footer of a custom theme so that JS files from plugins can be included? Is that true?

The proposed code:

{{ range .Site.Params.plugins_js }}
    <script src="{{ . }}"></script>
{{ end }}

Yes, thanks y’all! Both the header and footer there are important, since it makes sure that plug-ins can hook into any theme.

Considering I am the author of that post on, you’d think I’d remember.


Is there a version of Hugo we should be targeting?

Currently 0.54

It’s been six and a half months since this post.

In recent months Hugo has received several important upgrades, such as support for WebP images, the ability to insert localized dates in different languages, a Javascript and SCSS transpiler, and many bug fixes. At the time of writing, the current version of Hugo is 0.89.2 and version 0.54 was released almost three years ago (2 years and 9 months ago).

This is not meant to be a criticism, but IMHO now it would be really nice to have support for a newer version of Hugo in


@manton has confirmed to me that the Hugo version will be updated at some point. He needs the time to make sure updating Hugo doesn’t unexpectedly break things.

Update: Also worth noting that my picking apart of Hugo version 0.54 has gone next level.

Check out the repository of my custom theme to see how I am using Hugo pipes to compile Sass (scss only, sass extensions don’t get cloned, guessing that ending in css tricks @manton’s repo clone logic) into CSS.

Check out the repository for my lightbox plugin to see how I build Javascript from a template such that plugin parameters affect the actual script content.

Checkout the repository for my prism plugin to see how I totally brought syntax highlighting into my posts.

Checkout the repository for my favicon plugin (along with the custom theme above) to see how the introduction of the config directory allows directly controlling the Hugo build such that the plugin can actually generate webappmanifests and browserconfig.xml files from templates that draw in the plugin parameters.

Check out the precision injection plugin to see how to easily customize specific injection points for plugin HTML on a per file basis … as well as how to easily use white listing by page path to control when a plugin’s assets get loaded at all.

Check out the bootstrap plugin for an as-it-is-distributed bootstrap build that has its Javascript injected along with its compiled CSS (this was basically a dry run for what I am now doing in my theme).

Is the Cardify shortcode used for generating Open Graph cards for links in a post? Please say this is the case. I’ve been waiting for a way to do that.

I just rolled that functionality into plugin-cards. I found Javascript to be more reliable than the shortcode. Holler with questions. Writing READMEs is like pulling teeth. I just dropped the README in here before looking at my help center notifications