# ToC with anchors in posts

**URL:** <https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627>\
**Category:** support\
**Tags:** asciidoc\
**Created:** [July 12, 2019, 8:54pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627 "2019-07-12T20:54:06Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![kwladyka](https://avatars.discourse-cdn.com/v4/letter/k/47e85d/32.png) [@kwladyka](https://discourse.gohugo.io/u/kwladyka)\
**Post date:** [July 12, 2019, 8:54pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/1 "2019-07-12T20:54:06Z")

</div>

The best example is github, for example: [GitHub - concourse/concourse: Concourse is a container-based continuous thing-doer written in Go.](https://github.com/concourse/concourse#quick-start)  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/gohugo/original/2X/c/cf9d67a653a435fdb831c2d527ef9f6df4155108.png)

There is an anchor to click on it.

How can I achieve it in hugo? I don’t want to use shortcodes. I want to use standard markdown `# H1`, `## H2` etc.

---

<div class="post-metadata">

**Author:** ![maiki](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/maiki/32/16384_2.png) [@maiki](https://discourse.gohugo.io/u/maiki)\
**Post date:** [July 12, 2019, 9:56pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/2 "2019-07-12T21:56:04Z")

</div>

> [@kwladyka](#):
>
> How can I achieve it in hugo?

That’s JavaScript. It reads the heading’s ID and loads a graphic linking to it. Hugo adds the ID by default (see [Content formats | Hugo](https://gohugo.io/content-management/formats/#blackfriday-options)). The Hugo docs uses such a script, I believe it lives at [https://github.com/gohugoio/hugoDocs/blob/master/themes/gohugoioTheme/assets/js/anchorforid.js](https://github.com/gohugoio/hugoDocs/blob/master/themes/gohugoioTheme/assets/js/anchorforid.js).

---

<div class="post-metadata">

**Author:** ![kwladyka](https://avatars.discourse-cdn.com/v4/letter/k/47e85d/32.png) [@kwladyka](https://discourse.gohugo.io/u/kwladyka)\
**Post date:** [July 13, 2019, 7:02am UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/3 "2019-07-13T07:02:59Z")

</div>

![03](https://canada1.discourse-cdn.com/flex036/uploads/gohugo/original/2X/4/4f3294de8f436a3a8c4f951e2fbf35e0c485cfad.png)

Hmm but I am not sure if google will make Vars / Atoms / Agents then.

Not sure if it has to be static vs javascript. Do you know maybe?

---

<div class="post-metadata">

**Author:** ![maiki](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/maiki/32/16384_2.png) [@maiki](https://discourse.gohugo.io/u/maiki)\
**Post date:** [July 13, 2019, 5:00pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/4 "2019-07-13T17:00:17Z")

</div>

> [@kwladyka](#):
>
> Do you know maybe?

No. You’ll need to read the documentation for the systems you use, that is out of scope for Hugo troubleshooting. 🙂

---

<div class="post-metadata">

**Author:** ![freethebit](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/freethebit/32/8908_2.png) [@freethebit](https://discourse.gohugo.io/u/freethebit)\
**Post date:** [July 13, 2019, 6:01pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/5 "2019-07-13T18:01:23Z")

</div>

> [@kwladyka](#):
>
> re is an anchor to click o

or use a kind of post processing following the links in this link:

> [@Creating a clickable link from an anchor generated by hugo](https://discourse.gohugo.io/t/creating-a-clickable-link-from-an-anchor-generated-by-hugo/19623/2):
>
> Thanks for this tip @freethebit. For reference, @kaushalmodi does the same thing, in one line [here](https://github.com/kaushalmodi/hugo-onyx-theme/blob/master/layouts/partials/headline-hash.html) slightly_smiling_face, and I attempt to explain it to myself [here](https://zwbetz.com/create-header-links-hugo-vs-javascript/).

---

<div class="post-metadata">

**Author:** ![kwladyka](https://avatars.discourse-cdn.com/v4/letter/k/47e85d/32.png) [@kwladyka](https://discourse.gohugo.io/u/kwladyka)\
**Post date:** [July 15, 2019, 8:17am UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/6 "2019-07-15T08:17:53Z")

</div>

@maiki solution to write own simple js is the one which I choose to solve it. I modified it a little to get GitHub effect.

If somebody is interested in about effect you can see it here [Clojure Blog](https://clojure.wladyka.eu/) . It is simple JS + CSS.

JS

```auto
var anchorForId = function (id) {
    var anchor = document.createElement("a");
    anchor.className = "anchor-link";
    anchor.href = "#" + id;
    anchor.innerHTML = '<svg width="16" height="16" viewBox="0 0 16 16" version="1.1"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>';
    return anchor;
};

var linkifyAnchors = function (level, containingElement) {
    var headers = containingElement.getElementsByTagName("h" + level);
    for (var h = 0; h < headers.length; h++) {
        var header = headers[h];
        if (typeof header.id !== "undefined" && header.id !== "") {
            header.prepend(anchorForId(header.id));
        }
    }
};

document.onreadystatechange = function () {
    if (this.readyState === "complete") {
        var contentBlock = document.getElementsByTagName("article")[0]
        if (!contentBlock) {
            return;
        }
        for (var level = 2; level <= 4; level++) {
            linkifyAnchors(level, contentBlock);
        }
    }
};

```

SCSS

```auto
article {
    a {
        color: $link;
    }

    h2, h3, h4, h5 {
        &:hover .anchor-link {
            @media screen and (min-width: map-get($grid-breakpoints, "md")) {
                visibility: visible;
            }
        }
        .anchor-link {
            visibility: hidden;
            float: left;
            margin-left: -20px;
            padding-right: 4px;                
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![Grob](https://avatars.discourse-cdn.com/v4/letter/g/f14d63/32.png) [@Grob](https://discourse.gohugo.io/u/Grob)\
**Post date:** [July 15, 2019, 9:33am UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/7 "2019-07-15T09:33:06Z")

</div>

I personlly try to avoid JavaScript for this.

> [@kwladyka](#):
>
> I don’t want to use shortcodes.

This is probably because you do not want to insert a shortcode before/after each heading.

## This is another approach

This is the partial `header-link.html`:

```auto
{{ $content := . | replaceRE "(<h[2] id=\"([^\"]+)\">)(.+)(</h[2]+>)" `${1}${3} <a aria-label="header link for ${3}" href="#${2}" class="header-link">#</a>${4}` }}
{{ $content = $content | replaceRE "(<h[3] id=\"([^\"]+)\">)(.+)(</h[3]+>)" `${1}${3} <a aria-label="header link for ${3}" href="#${2}" class="header-link">#</a>${4}` }}
{{ $content | safeHTML }}

```

And in `single.html` you can use:

```auto
{{ partial "header-link.html" .Content }}

```

[See here](https://zwbetz.com/create-header-links-hugo-vs-javascript/).

---

<div class="post-metadata">

**Author:** ![kwladyka](https://avatars.discourse-cdn.com/v4/letter/k/47e85d/32.png) [@kwladyka](https://discourse.gohugo.io/u/kwladyka)\
**Post date:** [July 18, 2019, 10:01am UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/8 "2019-07-18T10:01:50Z")

</div>

> I personlly try to avoid JavaScript for this.

why?

Thanks for alternative solution.

---

<div class="post-metadata">

**Author:** ![Grob](https://avatars.discourse-cdn.com/v4/letter/g/f14d63/32.png) [@Grob](https://discourse.gohugo.io/u/Grob)\
**Post date:** [July 18, 2019, 1:36pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/9 "2019-07-18T13:36:53Z")

</div>

> [@kwladyka](#):
>
> > I personlly try to avoid JavaScript for this.
> 
> why?

Good question: At first I thought it was just a matter of taste. But it’s a bit more than that.

This seems to be my policy:

- Use semantic HTML5.
- Use pure CSS—following a DRY style. (I do not use SASS any more.)
- Use (vanilla) JavaScript as little as possible, as much as necessary. (CSS3 provides cool stuff that makes at least JS obsolete.)
- Inline CSS and JS (unless the file sizes are really huge).
- Use web-optimized, responsive images (I use a shortcode [similar to this one](https://discourse.gohugo.io/t/img-shortcode-bootstrap-4/19467).
- Definitely use Hugo to put it all together and minify everything.

Of course, if JS is necessary, I am happy to use it (or even Vue or React).

All this makes websites extremely fast, easily maintainable, and valid.

---

<div class="post-metadata">

**Author:** ![\_nm](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/_nm/32/7662_2.png) [@\_nm](https://discourse.gohugo.io/u/_nm)\
**Post date:** [July 22, 2019, 6:42pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/10 "2019-07-22T18:42:47Z")

</div>

This thread inspired me to do this on my site so thanks for posting this @kwladyka. Doing this in an AsciiDoc content file that’s rendered by `asciidoctor` involves setting one or both of these attributes:

```auto
:sectlinks:
:sectanchors:

```

Details are in [https://asciidoctor.org/docs/user-manual/#links](https://asciidoctor.org/docs/user-manual/#links) and [https://asciidoctor.org/docs/user-manual/#anchors](https://asciidoctor.org/docs/user-manual/#anchors).

I hope this is helpful to other `asciidoctor` users.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/totallyinformation/32/5668_2.png) [@TotallyInformation](https://discourse.gohugo.io/u/TotallyInformation)\
**Post date:** [July 22, 2019, 10:18pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/11 "2019-07-22T22:18:09Z")

</div>

> [@kwladyka](#):
>
> How can I achieve it in hugo?

There is a CSS-only method that is on this forum somewhere and that I use in my theme.

> **[GitHub - TotallyInformation/hugo-theme-twenty-sixteen: A blog and information...](https://github.com/TotallyInformation/hugo-theme-twenty-sixteen)**
>
> A blog and information management theme for Hugo roughly based on the Wordpress Twenty Sixteen theme - GitHub - TotallyInformation/hugo-theme-twenty-sixteen: A blog and information management theme...

I found the post that explained it the other day but can’t put my finger on it at the moment.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/totallyinformation/32/5668_2.png) [@TotallyInformation](https://discourse.gohugo.io/u/TotallyInformation)\
**Post date:** [July 22, 2019, 10:26pm UTC](https://discourse.gohugo.io/t/toc-with-anchors-in-posts/19627/12 "2019-07-22T22:26:25Z")

</div>

OK, found it:

> [@Adding anchor next to headers](https://discourse.gohugo.io/t/adding-anchor-next-to-headers/1726/10):
>
> Slight variation to make it closer to a GitHub style: .hanchor { font-size: 50%; visibility: hidden} h2:hover a { visibility: visible} function addAnchor(element) { element.insertAdjacentHTML('beforeend', `\<a href="#${element.id}" class="hanchor" ariaLabel="Anchor"\>link\</a\>` ) } document.addEventListener('DOMContentLoaded', function () { // Add anchor links to all headings var headers = document.querySelectorAll('article h1[id], article h2[id], article h3[id], article h4[id]') if…
