Ronalds Vilciņš

Enable raw HTML in Hugo

If HTML disappears from a Hugo Markdown file, check Goldmark’s unsafe setting. Raw HTML in Hugo is disabled by default; enabling it lets trusted markup pass through to the generated page.

For a personal site where the content is reviewed before publishing, that can be a reasonable choice. If the same component appears in several posts, I prefer keeping its markup in a shortcode instead.

Enable raw HTML in Hugo’s configuration

Add this to your existing YAML site configuration, usually hugo.yaml or config.yaml:

markup:
  goldmark:
    renderer:
      unsafe: true

If the file already contains a markup section, add the setting inside that section. Keep one markup key rather than pasting a second configuration tree below the first.

The setting belongs to the Goldmark renderer. Hugo’s markup configuration documents both its purpose and the default value of false.

Now put a small HTML block in a Markdown content file:

<details>
  <summary>Show the implementation note</summary>
  <p>This section uses native HTML inside a Markdown post.</p>
</details>

Build the site from the project root:

hugo

Open the generated page and check that the disclosure appears. Inspect the page source too: the output should contain the details, summary, and paragraph elements.

That gives you a small test case before you start investigating a larger embed or component.

Check omitted HTML separately from displayed code

With raw HTML disabled, the HTML block in this example is replaced by a <!-- raw HTML omitted --> comment in the generated source. Changing the renderer setting allows the block through.

HTML displayed as a code sample is a different case. If the markup sits inside triple backticks, remove the code fence when you want it to become part of the page. Keep the fence when readers need to copy the source.

This distinction matters because both situations can look like “Hugo is not rendering my HTML,” but the intended output is different. The configuration does not turn a fenced example into a live component.

If the small example works and your real markup does not, compare the generated source with the content file. You have narrowed the problem to the markup or its surrounding content rather than the renderer’s general HTML setting.

Choose the content boundary deliberately

unsafe: true allows raw HTML in Markdown processed with that configuration. It does not establish that the HTML is trustworthy. Hugo’s security model distinguishes trusted templates from content, so the source of the markup still matters.

Review HTML from imported files and outside contributors before allowing it onto a published page. I would not enable the setting merely to make an unfamiliar embed stop disappearing.

For an occasional trusted block, a custom shortcode makes the exception visible in the Markdown. For a repeated component, a dedicated shortcode keeps the structure in a template and exposes only the values the author needs to supply.

Those approaches solve different maintenance problems. Enabling raw HTML is convenient when markup belongs with the article; a shortcode is easier to change when the same structure belongs to many pages.

Filed under on

Last updated on

← Back to all articles