Warning when mixing HTML and Markdown

This article assumes that you have not disabled content security.

On this page

Introduction
Background
Example 1 – HTML comments in Markdown
Example 2 – HTML elements in Markdown
Example 3 – HTML elements in a shortcode template
Disabling content security

Introduction

You may see this warning when building your site with v0.137.0 and later:

Raw HTML omitted from “/home/user/project/content/example.md”; see https://gohugo.io/getting-started/configuration-markup/#rendererunsafe
You can suppress this warning by adding the following to your site configuration:
ignoreLogs = [‘warning-goldmark-raw-html’]

Hugo now emits a warning for every Markdown page that includes HTML. This significant behavioral change resolves a long-standing data integrity issue and enhances the authoring experience for new users.

Background

In its default configuration, when you mix HTML and Markdown, Hugo replaces the HTML with this HTML comment when rendering a page:

<!-- raw HTML omitted -->

With HTML block elements Hugo replaces the entire element. With HTML inline elements Hugo replaces the opening and closing tags.

Hugo performs this replacement as an important component of its security model where, by default, content is not trusted. Hugo performed this replacement silently prior to the release of v0.137.0, potentially leading to discrepancies between the source content and the published page.

With v0.137.0 and later Hugo continues to perform this replacement, but warns you once for each affected page. Although you can suppress this behavior as noted in the warning message, doing so may lead to data integrity issues and user frustration.

The following examples depict common scenarios and the recommended way to address them.

Example 1 – HTML comments in Markdown

Content authors may include HTML comments in their Markdown. For example:

+++
title = 'Example'
date = 2024-11-04T09:56:36-08:00
draft = false
+++

This is paragraph one.

<!-- TODO: rewrite the paragraph below. -->

This is paragraph two.

Hugo will emit a warning about this page because the comment is HTML. Instead of using an HTML comment, use the embedded comment shortcode available in v0.137.1 and later:

+++
title = 'Example'
date = 2024-11-04T09:56:36-08:00
draft = false
+++ 

This is paragraph one.

{{% comment %}} TODO: rewrite the paragraph below. {{% /comment %}}

This is paragraph two.

Although you can call this shortcode using the {{< >}} notation, computationally it is more efficient to call it using the {{% %}} notation as shown above.

Example 2 – HTML elements in Markdown

Content authors may include HTML elements in their Markdown. For example:

+++
title = 'Example'
date = 2024-11-04T09:56:36-08:00
draft = false
+++ 

<div>This is a **bold** word.</div>

Prior to v0.137.0 Hugo silently omitted the div element when rendering the content. Hugo v0.137.0 addresses this data integrity issue by emitting a warning. Handle this scenario by creating a “div” shortcode:

<div>{{ .Inner | .Page.RenderString }}</div>

Then call the shortcode using the {{< >}} notation:

+++
title = 'Example'
date = 2024-11-04T09:56:36-08:00
draft = false
+++

{{< div >}}This is a **bold** word.{{< /div >}}

Example 3 – HTML elements in a shortcode template

Site and theme authors may create shortcode templates that are designed to be called using the {{% %}} notation. For example:

<div>

  {{ .Inner }}
</div>

The blank line above is intentional. It satisfies the end condition for the HTML block as described in the CommonMark specification.

You would then call that shortcode using the {{% %}} notation:

{{% div %}}This is a **bold** word.{{% /div %}}

Prior to v0.137.0 Hugo silently omitted the opening and closing div tags when rendering the content. Hugo v0.137.0 addresses this data integrity issue by emitting a warning. Handle this scenario by modifying the shortcode:

<div>{{ .Inner | .Page.RenderString }}</div>

Then call the shortcode using the {{< >}} notation:

+++
title = 'Example'
date = 2024-11-04T09:56:36-08:00
draft = false
+++

{{< div >}}This is a **bold** word.{{< /div >}}

In this scenario, if the shortcode must be fully rendered when the page is rendered in order to include headings in the table of contents or to include footnotes, you must:

  1. Use the unrevised version of the shortcode as shown above
  2. Call the shortcode using the {{% %}} notation
  3. Disable content security

Disabling content security

If you are unable to resolve a warning with one of the approaches described above, you may have to disable content security in your site configuration so that Hugo will trust HTML mixed with Markdown:

[markup.goldmark.renderer]
unsafe = true

This disables a key component of Hugo’s security model, so only make this change if you control and trust the content.

When authoring complex content such as large HTML tables with row and column spans, consider using the HTML content format instead of Markdown, eliminating the need to disable content security. As always, carefully review every HTML content file before publishing.

7 Likes

@jmooring

Just to clarify for Example 1, once tpl/tplimpl: Create an embedded comment shortcode · gohugoio/hugo@801035b · GitHub ships, we could just use the embedded comment shortcode instead of rolling our own, correct? Would that be the guidance then?

Thanks!

Yes, that’s correct. The embedded comment shortcode is available in v0.137.1 and later.

2 Likes