Hugo is generating CSS IDs for Heading Elements; Should it?

Hello all,

I’m new to Hugo and rather liking it so far. However, I am scratching my head over something. I searched around and didn’t find any reference to this (did I miss something??) so here I am with my first question. :slight_smile:

I’ve noticed that Hugo seems to be automatically generating CSS IDs for my heading elements. Is this normal behavior for Hugo?

The IDs start with the text used in each element followed by a colon and a long series if letters and numbers. The letters/numbers are the same for all the elements (H1, H2, all the same), just the text varies, based on what the element says.

As far as I am aware, I haven’t done anything asking Hugo to do this. In fact, I’d like to eliminate it. Since I’m not using the IDs the styling is just falling back to what I do have defined for H2 in my CSS style sheet. But still, I’d rather not have the IDs at all.

Any insights, suggestions will be much appreciated.


Yes, this has to do with the BlackFriday markdown parser. Check the docs under configuration.

You can turn off the “long series of letters”:

      plainIDAnchors = true

Which will be default in Hugo 0.16.

These IDs aren’t CSS ids, they are HTML element identities – and used for lots of cool stuff, anchor identities for the autogenerated table of contents, to give one example.

Thanks for pointing the way! This does lead to some more questions, unfortunately…

So it seems some Blackfriday configuration is possible, great! From the look of it, Blackfriday extensions can be prevented from loading by using the extensionsmask flag. However, one must then specify the flag corresponding to the extension in question. The documentation gives an example for one case but that’s it.

If there is a way to tell what the flags are for each extension, or even tell for sure what extension is responsible for each behavior, it’s not clear to me in the linked-to GitHub materials. This stuff is not composed with laymen I mind.

I did try using the masking feature with the “autoHeaderIds” flag used as an example in the Hugo documentation–intuitively, it seemed like a likely culprit, actually. It did in fact eliminate heading IDs based on the heading text.

However, the result is that some other extension apparently asserts itself and creates heading IDs like “toc_0”, “toc_1”, etc, which I take to corresponds to a Table of Contents feature. Anyone happen to know the flag for disabling that??

Really, this is like pealing an onion, including the urge to cry. :wink: All I want is NO heading IDs to be generated at all.

I’m happy to hear of the change coming in Hugo 0.16.

Is there a way to just get nice clean headings, though? I just want my headings to be their happy unadulterated little selves. :slightly_smiling:

If you want total control of your HTML, you will have to create your HTML by hand or create your own static site generator. The last can be a daunting task, but also lots of fun.

Hugo does support content files in HTML, so that’s an option.

Ah, no “#” before the IDs, sorry I didn’t catch that. Well, at least that means if I should decide to use CSS ID selectors, this won’t be fighting me. :slight_smile: I guess I can just learn to live with them.

Well, drat. I was looking forward to using Markdown. I probably still will, and just overlook the HTML IDs I guess. For the most part Hugo does seem to stay nicely out of the way, which is one of the things that attracted me to it.

Fun is definitely subjective. :wink: I do appreciate all the work that has gone into the Hugo project, of all the site generators I’ve come across it seems like the best in so many ways–few hassles or dependencies, richly featured, lots of control, LiveReload etc.

1 Like

I will add that if you find markup that makes CSS selection of an element impossible, then I would say that is a bug and should be fixed. But I don’t see that problem currently.

@Jim I should have been more specific, but I was writing from my phone. Honestly, the IDs will come in handy, especially if you are writing long-form content, in which case Hugo’s built in {{.TableOfContents}} shortcode is going to make your templating (eg, with something like waypoints or smoothscroll) a breeze. IDs for headers are common enough, and as long as you aren’t targeting them directly with CSS, the IDs shouldn’t affect the presentation of your markup and don’t negatively affect your semantics either.

Anyway, there is a solution by the Blackfriday developers:

some very very long header some very very long header some very very long header some very very long header {#short-id}

this renders

<h2 id="short-id">