Piping the formatted $date through safeHTML, safeJS or safeJSStr doesn’t give me anything else here. If I use Z instead of -07:00, I get a Z as time zone in the ld+json stuff – but that’s not what I really want.
Is that expected behavior? If so, is there a way to have the formatted date appear in side the script element as it does outside?
Your desire to use the latter is a cosmetic preference, not a functional requirement.
Second, the idiomatic way to render JSON is to marshal a map using the jsonify function.
Third, rendering of quoted and unquoted pipelines is handled by Go’s html/template package, which uses Go’s encoding/json package when the pipeline is in a JavaScript context. Instead of digging into why these packages do what they do, I suggest you either (a) don’t worry about cosmetics, or (b) use the jsonify function.
Finally, if you want to bypass this aspect of Hugo’s security model, redefine the HTML output format, setting isPlainText to true. Note that this will effectively disable built-in templates; see #10922.
Which I actually do in other parts of the ld+json generation. But appending dict after dict to a dict is a bit tedious (compared to stinky setting a key to a value in JavaScript). Maybe a Scratch would be simpler to use in this context. I’ll explore that.