Remix.run Logo
alserio 3 days ago

I was wondering, are template elements a good place to store json data in the page to be consumed by js?

jfagnani 2 days ago | parent | next [-]

No. I would use <script type="-json">

<script> parses its contents as text, whereas <template> parses as DOM. This means you don't have to escape `<`, just `</script>`.

Myself and some browser engineers been working on proposals to allow for inline modules, including JSON, that are importable into other modules via regular import statements.

This is why I recommend the "-json" type - so it doesn't collide with a future native "json" type.

SahAssar 2 days ago | parent | next [-]

Why not use a somewhat proper mime type like `<script type="application/mytype+json">` or similar? Seems like your suggestion is not what the spec recommends: https://html.spec.whatwg.org/multipage/scripting.html#attr-s...

jfagnani 2 days ago | parent [-]

My understanding is that in implementations any unknown type creates a "data block", which is just unprocessed text.'

I wouldn't use application/json just in case browsers start supporting that and it has different semantics than whatever custom thing you might do, causing a webcompat issue when the native feature rolls out.

Although with JSON, it's pretty unlikely that there would be any differing semantics. JSON modules in JS are just JSON blocks with no special additions and no named exports. That's what inline versions would be as well.

SahAssar 2 days ago | parent [-]

But wouldn't a subtype like `mytype` in my example (`application/mytype+json`) still be be a valid mime-type and still avoid your concerns? I've used these before.

alserio 2 days ago | parent | prev [-]

Thank you. And that proposal seems really interesting. Can I ask for a link if you happen to have one publicly accessible?

bsmth 2 days ago | parent | prev | next [-]

You might be interested in data attributes for this use case https://developer.mozilla.org/en-US/docs/Web/HTML/How_to/Use... although it depends on the shape of the JSON data you had in mind.

alserio 2 days ago | parent [-]

What do you mean with shape? Are you concerned about escaping and such?

bsmth 2 days ago | parent [-]

I can imagine if it's deeply nested data, your markup might get complex, but the structure of the HTML doesn't have to mirror the JSON. There's other examples here which might illustrate more how this can look: https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...

alserio 2 days ago | parent [-]

Thank you. I was looking at a generic way to pass configuration data to custom elements where I cannot know the shape in advance, since another dev can have different requirements. I support data attributes for simple types but i was wondering if allowing arbitraty json objects via other means could be feasible.

hunter2_ 2 days ago | parent [-]

Since JSON is a subset of JavaScript, you can just use a script element, and including the json mime type certainly doesn't hurt:

    <script type="application/json" id="myJSONData">
      {
        "name": "John Doe",
        "age": 30
      }
    </script>

    <script>
      const data = JSON.parse(document.getElementById('myJSONData').textContent);
      console.log(data.name + " is " + data.age); // John Doe is 30
    </script>
Note: The JSON data must exist literally within the script element. If you try using a src attribute to request it from elsewhere, the response will not be available via textContent or any other mechanism [0], and at that point you just need to fetch/ajax/xhr it.

[0] https://stackoverflow.com/questions/17124713/read-response-o...

lioeters 2 days ago | parent [-]

About embedding JSON in a script tag, I recently read an article on the risk of a closing </script> tag within the JSON that could break it.

Safe JSON in script tags: How not to break a site - https://sirre.al/2025/08/06/safe-json-in-script-tags-how-not...

As with all untrusted content, depending on where the JSON string comes from, sanitizing the output is worth considering.

yencabulator 18 hours ago | parent | next [-]

That article was pretty complicated; I appreciate the historical understanding but frankly web legacy is too complex to bother with "why" too much, in the end so many things just don't make sense and are historical accidents.

Here's another take, just a short list of replacements. Interestingly, "&" is also escaped: https://pkg.go.dev/encoding/json#HTMLEscape

lioeters 16 hours ago | parent [-]

That's a helpful summary of what's necessary to make JSON safe to embed in script tags.

I agree the "why" is too long of a story, an accumulation of supposedly logical decisions that led up to the ball of quirks. It's too much to remember. Exactly the kind of thing that should be delegated to a specialized function made and maintained by experts.

hunter2_ a day ago | parent | prev [-]

Great article! I suppose a similar (yet different) precaution would be needed in data-* attributes or any other part of an HTML document.

yuchi 3 days ago | parent | prev | next [-]

As good as a script element with type application/json.

joeframbach 2 days ago | parent | next [-]

I wonder if the browser would attempt to validate the contents of a script tag with type json, versus treating it as a blob that would only be validated when parsed/used. And any performance overhead at load time for doing so. Not at a machine at the moment so I can't verify.

alserio 3 days ago | parent | prev [-]

well one difference is that application/json scripts are still subject to CSP policies

unilynx 2 days ago | parent [-]

How so? I don't remember ever having seen issues with this. If anything CSP steers you towards this (instead of inline scripts directly assigning to JS variables)

alserio 2 days ago | parent [-]

I thought I knew but it seems that the CSP story is unclear. I couldn't find an authoritative source for either position

SahAssar 2 days ago | parent [-]

CSP blocks execution/inclusion, but since json does not execute and any json mimetype will not do execution there is no problem.

Any CSP-allowed other script can read that application/json script tag and decode it, but it is no different than reading any other data it has access to like any other html element or attribute.

alserio 2 days ago | parent [-]

That makes sense, thank you

Gualdrapo 2 days ago | parent | prev [-]

For my portfolio (miler.codeberg.page) and the refactor&redesign I'm doing of it (that I hope to finish soon!), I feed some <template>s with data coming from a json that acts like kind of a database. I feel the process of querying nodes and setting their data is still a bit rudimentary in plain JS and it should be a pain in the ass for huge datasets or lots of nodes, but at least with modern JS it is not necessary to fetch the json with a XMLHTTPRequest or something - it can work importing it like a regular JS module, so at least there's that.