How to Replace the First Occurrence of an Element in Hugo

Published Aug 5, 2022  ∙  Updated Aug 6, 2022

Let’s use replaceRE to replace only the first occurrence of an element in our Hugo site.

Suppose we have many h2 tags (i.e. <h2></h2>) in our Hugo site. How can we modify only the first instance of this element?

From the replaceRE documentation from Hugo:

strings.ReplaceRE returns a copy of INPUT, replacing all matches of the regular expression PATTERN with the replacement text REPLACEMENT. The number of replacements can be limited with an optional LIMIT parameter.

1. Find .Content

First, we’ll want to find where our content is being displayed.

We’ll do that by searching for usage of .Content.

Normally, we’ll find it in single.html.

{{ .Content }}

2. Modify .Content with replaceRE

We can modify this content by targeting specific elements with replaceRE.

replaceRE can receive 4 arguments: pattern, replacement, input, and limit.

  • Pattern: "(<h2.*</h2>)"
  • Replacement: <div id="head">${1}</div>
  • Input: .Content
  • Limit: 1

The above arguments will wrap the first h2 tag inside a div with id="head". If we don’t include the limit of 1, we’ll wrap every single h2 tag inside that div.

{{- with .Content -}}
  {{ replaceRE "(<h2.*</h2>)" `<div id="head">${1}</div>` . 1 | safeHTML }}
{{- end -}}

safeHTML declares the string provided by replaceRE as a “safe” HTML document to avoid escaping by Go templates.

Potential Errors

If you run into an error regarding number of arguments passed into replaceRE, try upgrading HUGO_VERSION to the latest version.

ERROR: render of "page" failed: "/opt/build/repo/layouts/_default/single.html": 
execute of template failed: template: _default/single.html: executing "main" at 
<replaceRE>: wrong number of args for replaceRE: want 3 got 4