Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hugo: Automatically Link Headers

With Hugo static site generator, is it possible to have it automatically put links around header elements? I see that it does fill in the ID attribute so it can be referenced but I would like to automatically create the link as well, like this:

<a href="/post/cool-blog-post#some-interesting-title">
    <h2 id="some-interesting-title">Some Interesting Title</h2>
</a>

I did not see anyway in the documentation to do this and I think it would be helpful for users linking to a particular point in a lengthy post.

like image 264
Erik Berkun-Drevnig Avatar asked Oct 29 '22 12:10

Erik Berkun-Drevnig


2 Answers

As far as I'm aware it's not possible to achieve it out-of-the-box, that is, out-of-the-hugo.

I had this same wish myself; I solved it via jQuery, wrapping all h2's and h3's dynamically with links, generating slugs on the go:

enter image description here

Then I've got a sticky sidebar nav which acts as a way to smooth-scroll between the headings, plus it highlights the current heading:

enter image description here

Today I would code it differently code-wise (probably without jQuery) but I'm quite happy with how it works. I think JS overhead is minimal, especially if coded neatly.

like image 186
revelt Avatar answered Jan 02 '23 21:01

revelt


This doesn't seem to be possible out of the box. There are two ways of working around it that I can think of: using JavaScript, as revelt suggested, or using HTML in your markdown.

For example, consider the HTML you supplied above.

<a href="/post/cool-blog-post#some-interesting-title">
    <h2 id="some-interesting-title">Some Interesting Title</h2>
</a>

If you put this code directly into a Hugo markdown document, it will produce the kind of link you are looking for. However, this is a pain to type every time, so to reduce your work you can make a shortcode.

In layouts/shortcodes/link-heading.html:

{{ $id := .Get 0 | lower | replaceRE "[^0-9a-z]" "-" | replaceRE "-+" "-" -}}
<a href="#{{ $id }}">
  <h2 id="{{ $id }}">{{ .Get 0 }}</h2>
</a>

In your markdown document:

{{< link-heading "Some Interesting Title" >}}

I have left the base URL out here, but you can pass it as a parameter from your markdown document if you want. (Of course, then you have to know what the URL is without having Hugo do it for you, which is not ideal.)

This approach has the disadvantages that you can't use the normal markdown heading syntax, and that you don't get Hugo's built-in resolution of duplicate anchors. But it will get the job done.

like image 40
Jack Taylor Avatar answered Jan 02 '23 19:01

Jack Taylor