# Auto ID generation partially incompatible with allowable CSS selectors

**URL:** <https://discourse.gohugo.io/t/auto-id-generation-partially-incompatible-with-allowable-css-selectors/54940>\
**Category:** support\
**Created:** [June 1, 2025, 9:18am UTC](https://discourse.gohugo.io/t/auto-id-generation-partially-incompatible-with-allowable-css-selectors/54940 "2025-06-01T09:18:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmahnke](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/cmahnke/32/14148_2.png) [@cmahnke](https://discourse.gohugo.io/u/cmahnke)\
**Post date:** [June 1, 2025, 9:18am UTC](https://discourse.gohugo.io/t/auto-id-generation-partially-incompatible-with-allowable-css-selectors/54940/1 "2025-06-01T09:18:12Z")

</div>

I’m using the following setting to generate IDs for headings:

```auto
    [markup.goldmark.parser]
        autoHeadingID = true
        autoHeadingIDType = "github"

```

Most are certainly aware of this setting, but it has a major backdraw: If one has a heading starting wit a digit, the generated ID will itself start with one. While this is perfectly valid on the HTML side, it is quite an inconvenience when working with CSS selectors. Those can work, but need to be escaped, is there a way to prepend an ID with some default, like `id_`?

More on the CSS ID issue in [this Stackoverflow answer](https://stackoverflow.com/a/5672936).

---

<div class="post-metadata">

**Author:** ![irkode](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/irkode/32/26135_2.png) [@irkode](https://discourse.gohugo.io/u/irkode)\
**Post date:** [June 1, 2025, 10:15am UTC](https://discourse.gohugo.io/t/auto-id-generation-partially-incompatible-with-allowable-css-selectors/54940/2 "2025-06-01T10:15:23Z")

</div>

You may use a [heading render hook](https://gohugo.io/render-hooks/headings/#article) to add a prefix:

Used of `_`here , but you may conditionally add it, define as site parameter …

##### `layouts/_markup/render-heading.html`

```auto
<h{{ .Level }} id="_{{ .Anchor }}" {{- with .Attributes.class }} class="{{ . }}" {{- end }}>
  {{- .Text -}}
</h{{ .Level }}>

```

when generating headings in your layouts, use [urls.Anchorize](https://gohugo.io/functions/urls/anchorize/)

```auto
<h1 id="{{ add "_" (site.Title | urls.Anchorize) }}">{{ site.Title }}</h1>

```

---

<div class="post-metadata">

**Author:** ![jmooring](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/jmooring/32/4214_2.png) [@jmooring](https://discourse.gohugo.io/u/jmooring)\
**Post date:** [June 1, 2025, 6:32pm UTC](https://discourse.gohugo.io/t/auto-id-generation-partially-incompatible-with-allowable-css-selectors/54940/3 "2025-06-01T18:32:02Z")

</div>

Altering the `id` attribute in a heading render hook will break tables of content (e.g., `Page.TableOfContents`). See [Issue 8383](https://github.com/gohugoio/hugo/issues/8383), which I suspect will not or cannot be addressed (🐔 🥚).

Instead, use a [Markdown attribute](https://gohugo.io/content-management/markdown-attributes) to override the `id` as needed. For example:

```plaintext
## 1 The first heading {#foo}

```

Which is rendered to:

```html
<h2 id="foo">1 The first heading</h2>

```

Changing the way we auto-generate `id` attributes has been discussed here:  
[https://github.com/gohugoio/hugo/issues/8997](https://github.com/gohugoio/hugo/issues/8997)
