Hugo's behavior in script tag

When in script tag, Hugo automatically adds quotes around the tag.

For example:

<script type="application/ld+json">
  { 
    "@context": "http://schema.org", 
    "@type": "WebSite", 
    "url": {{ .Permalink }}, {{/* When in a script tag, Hugo automatically adds quotes around all Hugo tags, eg, {{ }}. However, if quotes are added manually (like "{{ .Permalink }}"), Hugo adds back-slashes in neighborhood of forward slashes. safeHTML tag doesn't work either as of v0.57.2 see: https://discourse.gohugo.io/t/x26rsquo-bad-escape-sequence-in-string-for-json-ld */}}
    "name": {{ site.Title }},
      "author": {
        "@type": "Person",
        "name": {{ site.Params.author }}
      },
    "description": {{ site.Params.description }},
  }
  </script>

would result in:

<script type="application/ld+json">
  { 
    "@context": "http://schema.org", 
    "@type": "WebSite", 
    "url": "https://example.com",
    "name": "Example",
      "author": {
        "@type": "Person",
        "name": "Author Example"
      },
    "description": "A very good description",
  }
  </script>

Although it fits well with above use case, I wanted to make sure whether it is intended behavior and is it safe to use it? If not, there appear to be problems in rendering a JSON-LD friendly output when tag is inside of quotes.

For example (see this question, the question is around 3 years old but I have checked and similar behavior is still present):

My json+ld is:

<script type="application/ld+json">
{
  "@context" : "http://schema.org",
  "@type" : "Webpage",
  "name": "{{ .Title }}"
}
</script>

.Title contains the value “My & Company”. What it becomes is:

<script type="application/ld+json">
{
  "@context" : "http://schema.org",
  "@type" : "Webpage",
  "name": "My \x26 Company"
}
</script>

Even use of safeJS, safeHTML, htmlUnescape has no effect in above example. See this newer thread, from where I found out about Hugo’s current behavior when tags are quoted.

The behaviour you see is security related; so the security model in Go templates is sound, but can be painful to work with. Note that this only applies to HTML (and AMP etc.) output formats (the other are treated as plain text) and that it is possible to redefine HTML … albeit at your own risk.

@ju52 Thanks, would check if it works and post an update.

@bep So current behavior is intended, right? Is it safe to use it the way I have in first example (that is, tags without quotes)? Also, just out of curiosity, as Hugo outputs different code when inside and outside of quotes, is Hugo aware of quotes surrounding the tags?

A tip relevant to this topic:

In case you want to combine 2 variable’s values in a script tag:

What one would try:

<script type="application/ld+json">
  { 
   "url": {{ .Permalink }}{{ $anotherVarDefinedAboveInPage }}
  }
</script>

Hugo would automatically add quotes around both, and result in,

<script type="application/ld+json">
  { 
   "url": "https://perma.link""/anotherVariableValue"
  }
</script>

One could use printf in this case:

<script type="application/ld+json">
  { 
   "url": {{ printf "%s%s" .Permalink $anotherVarDefinedAboveInPage }}
  }
</script>


Sorry for bump. Hope it helps someone!

1 Like