I’ve been working with my new HTMX.NET library, making it easier for ASP.NET Core developers to incorporate the frontend library into their web solutions. One of the features of HTMX is defining your configuration within a meta tag.

 <meta name="htmx-config" 
       content='{"indicatorClass":"htmx-indicator","historyCacheSize":20}' />

It’s a nice feature for HTMX, but it is tedious to get the values from C# into a JSON object and serialize it into HTML. So instead, I’ve written a TagHelper to allow you to set attributes on the meta element, but there’s an issue. You need to make sure the JSON object doesn’t break your HTML.

This post will show what it takes to render non-encoded JSON into an HTML element’s attribute without breaking the HTML syntax.

The Problem

HTML and JSON both use the double quote (“) to indicate values. In HTML, you also can use single quotes (‘) to denote values in attributes. Another issue you have to overcome is ASP.NET Core’s rightful insistence that all values be HTML encoded to prevent injection attacks. A first attempt to create a tag helper may end up with the following code.

output.Attributes.Add("content", config);

The output of the code is an encoded mess of HTML.

<meta name="htmx-config" 
      content="{&amp;quot;indicatorClass&amp;quot;:&amp;quot;htmx-indicator&amp;quot;,&amp;quot;historyCacheSize&amp;quot;:20}" />

Not what you likely want in your HTML. How do we fix these issues?

The Solution

Let’s walk through the problems we’re trying to solve one by one:

  1. We need the raw output of our JSON, double quotes, and all.
  2. We need the HTML attribute to use single quotes and not break the value that also uses double quotes.

We’ll be using the following .NET types:

  • TagHelperAttribute
  • HtmlString
  • HtmlAttributeValueStyle.SingleQuotes

Modifying the previous code, we’ll end up with the following C# fragment:

output.Attributes.Add(new TagHelperAttribute(
    "content",
    new HtmlString(config),
    HtmlAttributeValueStyle.SingleQuotes)
);

And now our output is correct.

<meta name="htmx-config" 
      content='{"indicatorClass":"htmx-indicator","historyCacheSize":20}' />

If you’re building a similar tag helper, you can check out that final implementation at the HTMX.NET repository. As always, thanks for reading.