5 Useful Hugo Snippets
1. Icon Partials
Every website needs icons! I personally, don’t like having lots of SVG’s in my HTML markup. Using a partial is a great way to keep your code clean and easy to read. I have a partial for each SVG icon and pass in the classes I want to use as a single string.
<svg class="{{ . }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12h15m0 0l-6.75-6.75M19.5 12l-6.75 6.75" />
</svg>
You can see on line 1 we use the class="{{ . }}"
template syntax which will let you pass in classes directly to the partial. Like so
{{ partial "icons/arrow-right.html" "w-6 h-6" }}
2. Related Content Snippet
This snippet is great for added a few related posts to the end of the current blog post. Related posts are assessed based off of your taxonomies, so it’s best to make sure you’re making use of your categories and tags.
{{ $related := .Site.RegularPages.Related . | first 3 }}
{{ if $related }}
<div>
<div class="prose">
<h3> Related Posts </h3>
</div>
{{ with $related }}
<!-- Your Markup Here! -->
{{ end }}
</div>
{{- end -}}
3. Next and Previous Post Snippet
This snippet will pull in the Next and Previous page into your template, which you can use to add links to the next and previous post.
<div class="grid md:grid-cols-2 gap-4">
<div>
{{ if .NextPage }}
<a class="" href="{{ .NextPage.Permalink }}">
{{ partial "icons/chevron-double-left" "h-4 w-4" }}
{{ .NextPage.Title | truncate 30 "..."}}
</a>
{{ end }}
</div>
<div>
{{ if .PrevPage }}
<a class="">
href="{{ .PrevPage.Permalink }}">{{
.PrevPage.Title |
truncate 30 "..."}}
{{ partial "icons/chevron-double-right" "h-4 w-4" }}
</a>
{{ end }}
</div>
</div>
4. Building a JSON API
Hugo has a lot of really cool feature, including the ability to render damn near any kind of file. One thing you might need is a Rest like API for your posts or pages. To do this you’ll need a few things.
First update your outputs in your configuration file. In this case I’m adding "JSON"
to the list of sections. So for every section page that’s rendered it’s also going to look for a list.json
file to render.
[outputs]
home = ["HTML", "RSS"]
section = ["HTML", "RSS", "JSON"]
Next place a list.json
in the layouts directory. In my case, I only want to render JSON for my blog
content type so I’ll create the file here: /layouts/blog/list.json
.
{{- $.Scratch.Add "index" slice -}}
{{- range .Pages -}}{{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "content" .Plain "permalink" .Permalink) -}}{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}
That’s it! Now you can access your API at https://yourdomain.com/blog/index.json
. You’ll have the following keys
title
- the title of the postcontent
- the content of the posttags
- the array of tags for the postpermalink
- the permalink for the post
This is extremely useful if you want to build a search engine for your static site, something we’ll look at more closely in a future post.
5. Dynamic Values in Javascript/Typescript
In order to have dynamic light/dark mode themes with Daisy UI I wanted to be able to dynamically set the dark and light themes outside of the javascript, but in order to remember the user’s preference I needed to store it in local storage. These snippets combined are a great way to leverage the data-
attributes in HTML to pass values to your javascript while not complicating your javascript code.
In this snippet I’m applying the data-theme-dark
and data-theme-light
attributes and rendering values from my Data files into them. When these are generated they’ll be replaced by the values in my /data/Global/Theme.yaml file.
<!DOCTYPE html>
<html
data-theme-dark="{{ $.Site.Data.Global.Theme.Dark }}"
data-theme-light="{{ $.Site.Data.Global.Theme.Light }}"
>
{{- partial "head.html" . -}}
<body>
{{- partial "header.html" . -}}
<div id="content">{{- block "main" . }}{{- end }}</div>
{{- partial "footer.html" . -}}
</body>
</html>
Here’s the yaml file
Light: business-light
Dark: business
And finally, here’s how I’m accessing those values in Javascript
const LIGHT_THEME = document.documentElement.getAttribute('data-light-theme') || "business-light";
const DARK_THEME = document.documentElement.getAttribute('data-dark-theme') || "business";
When the page is loaded and the javascript is executed the data attributes will be read into the LIGHT_THEME
and DARK_THEME
variables. I can now access these throughout the rest of my scripts and use them to set the theme. You can apply this same technique to any kind of data you may want to pass between your HTML and Javascript.