News for hackers. Stuff that matters.

Show HN: JavaScript-free (X)HTML Includes

https://github.com/Evidlo/xsl-website

(spoiler: its XSLT)

I've been working on a little demo for how to avoid copy-pasting header/footer boilerplate on a simple static webpage. My goal is to approximate the experience of Jekyll/Hugo but eliminate the need for a build step before publishing. This demo shows how to get basic templating features with XSL so you could write a blog post which looks like

  <?xml version="1.0"?>
  <?xml-stylesheet type="text/xsl" href="/template.xsl"?>
  <page>
      <title>My Article</title>
      <content>
          some content
          <ul>
              <li>hello</li>
              <li>hello</li>
          </ul>
      </content>
  </page>
Some properties which set this approach apart from other methods:

  - no build step (no need to setup Jekyll on the client or configure Github/Gitlab actions)
  - works on any webserver (e.g. as opposed to server-side includes, actions)
  - normal looking URLs (e.g. `example.com/foobar` as opposed to `example.com/#page=foobar`)
There's been some talk about removing XSLT support from the HTML spec [0], so I figured I would show this proof of concept while it still works.

[0]: https://news.ycombinator.com/item?id=44952185

See also: grug-brain XSLT https://news.ycombinator.com/item?id=44393817

( 113 comments | on HN )
Re:Show HN: JavaScript-free (X)HTML Includes by shakna on Friday August 22, 2025 @07:38PM (#44991280)
As of the next version of Chrome, XSLT will be gated behind a flag.

Google have also asked for it to be removed from the standard [0].

[0] https://github.com/WHATWG/html/issues/11523

Re:Show HN: JavaScript-free (X)HTML Includes by simpaticoder on Friday August 22, 2025 @08:03PM (#44991526)
It's kind of too bad XSLT didn't take off. It is quite complex, until you compare it to the complexity of what now solves this problem (e.g. a build step with React and webpack and javascript absolutely required on the client-side). As the OP ably demonstrates, XSLT provides a declarative, non-javascript, non-build way to solve the basic HTML component problem. Perhaps a devastating 0-day in V8 will make us really, really want an alternative to the current best practice.
Re:Show HN: JavaScript-free (X)HTML Includes by shakna on Friday August 22, 2025 @09:17PM (#44992022)
Whilst I can't be certain, I've been hearing that part of Google's want to move away from XSLT is two-fold - and relates to the idea of the security problem.

Partly, there's increasing attacks against XML.

And also, libxml2 has said "no" to security embargoes altogether. [0]

They might well consider there to be 0-days waiting in XSLT.

[0] https://news.ycombinator.com/item?id=44381093

Re:Show HN: JavaScript-free (X)HTML Includes by AgentME on Friday August 22, 2025 @11:14PM (#44992785)
React supports rendering to HTML ahead of time (SSR) which doesn't need any client-side javascript, and this is a prominent feature of most frameworks using React. This feature of React was one of its major innovations over many other front-end frameworks of the time.
Re:Show HN: JavaScript-free (X)HTML Includes by degamad on Saturday August 23, 2025 @01:51AM (#44993553)
> React supports rendering to HTML ahead of time (SSR)...

So does XSLT?

Re:Show HN: JavaScript-free (X)HTML Includes by throwaway290 on Saturday August 23, 2025 @04:41AM (#44994400)
Literally not one person said XSLT can't do it. But in case you missed it somebody did said React can't do it and so XSLT is better.

> build step with React and webpack and javascript absolutely required on the client-side

This was a false statement.

both XSLT and React can be used for this except React can additionally do a bunch of other stuff that does use JS and that XSLT can't do.

Re:Show HN: JavaScript-free (X)HTML Includes by MrJohz on Saturday August 23, 2025 @12:32AM (#44993179)
I think the big difference there is that browsers are only responsible for Javascript, which is a big general purpose solution that solves a lot of problems and not just templating/styling XML. Everything else either happens server-side (build steps and webpack) or is userland code that lives inside the sandbox. So there's one task for browsers to do (make a fast and secure Javascript sandbox), and if that works that developers can do whatever they want. Whereas XSLT is not a general purpose tool in the same way, and so needs to be maintained in addition to Javascript and anything else that exists.

If course XSLT can also be used server-side (which is probably a good idea if you want access to the latest features and not some ancient, frozen version of the spec), but browsers aren't the reason that that didn't take off. My guess there is that it's just not an intuitive way of manipulating and templating data in comparison to more traditional HTML templating libraries.

Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Saturday August 23, 2025 @12:57AM (#44993291)
I don't think react is comparable.

React's main thinh is client side reactivity, something that xslt doesn't offer.

A closer comparison would be a templating engine that does statuc conversion to html.

Re:Show HN: JavaScript-free (X)HTML Includes by notpushkin on Friday August 22, 2025 @07:59PM (#44991489)
Yeah, I think that was what prompted this submission.

All this has also reignited my idea for a compile-to-XSLT templating language, too – maybe I’ll get to it finally this time; definitely if XSLT 3.0 gets into web standards: https://github.com/whatwg/html/issues/11578, https://news.ycombinator.com/item?id=44987552

Also, I’ve put together a simple XSLT playgroung a while ago! https://xsltbin.ale.sh/

Re:Show HN: JavaScript-free (X)HTML Includes by Evidlo on Saturday August 23, 2025 @01:40AM (#44993514)
I was thinking it would be possible to compile a subset of Jinja2 (or your favorite equivalent) into XSL: https://chatgpt.com/share/68a95439-ad54-800a-919f-23caecce43...

Thanks for the playground! I'll check it out.

Re:Show HN: JavaScript-free (X)HTML Includes by bokchoi on Saturday August 23, 2025 @01:45PM (#44997703)
I haven't tried it yet, but I came across this alternate syntax for XSLT which is much more friendly:

https://github.com/Juniper/libslax/wiki/Intro

Re:Show HN: JavaScript-free (X)HTML Includes by SnuffBox on Friday August 22, 2025 @08:00PM (#44991500)
I find it bizarre that Google can just ask for a feature to be removed from standard and nobody bats an eye.
Re:Show HN: JavaScript-free (X)HTML Includes by notpushkin on Friday August 22, 2025 @08:05PM (#44991546)
If I understand correctly, Mozilla and Apple don’t really want to support it either. And the reason for that is, the spec is still at XSLT 1.0, which is super old, and current implementations are effectively abandonware. Catch-22?
Re:Show HN: JavaScript-free (X)HTML Includes by ekianjo on Friday August 22, 2025 @10:11PM (#44992390)
The spec is at XLST 3 right now.
Re:Show HN: JavaScript-free (X)HTML Includes by abraham on Friday August 22, 2025 @10:20PM (#44992447)
Re:Show HN: JavaScript-free (X)HTML Includes by ekianjo on Saturday August 23, 2025 @12:53AM (#44993269)
We were talking about the spec, not the implementation.
Re:Show HN: JavaScript-free (X)HTML Includes by JW_00000 on Saturday August 23, 2025 @09:10AM (#44995729)
When notpushkin said "the spec is still at XSLT 1.0", I think "the spec" is referring to the WHATWG HTML Living Standard spec, which only refers to XSLT 1.0. (It wouldn't make sense to say "the XSLT spec is at XSLT 1.0".)
Re:Show HN: JavaScript-free (X)HTML Includes by notpushkin on Tuesday August 26, 2025 @10:52PM (#45034947)
Exactly. Thanks!
Re:Show HN: JavaScript-free (X)HTML Includes by johncolanduoni on Friday August 22, 2025 @10:21PM (#44992457)
I believe the spec is at XSLT 3.0 but no browser actually implemented past XSLT 1.0 (not 100% sure - almost nobody cared about this feature last month so hard to find good docs on support). HTML5 and C++ are cut from the same cloth - massive and no reference implementation so full of features that have been “standard” for 10 years but never implemented by anyone.
Re:Show HN: JavaScript-free (X)HTML Includes by notpushkin on Friday August 22, 2025 @11:22PM (#44992835)
Yeah, sorry, the XSLT spec is at 3.0 right now of course, but the browsers don’t implement it, and the WHATWG HTML Living Standard only mentions XSLT 1.0.
Re:Show HN: JavaScript-free (X)HTML Includes by arccy on Friday August 22, 2025 @11:17PM (#44992805)
even outside of browsers barely anything supports XSLT newer than 1.0
Re:Show HN: JavaScript-free (X)HTML Includes by esrauch on Friday August 22, 2025 @09:23PM (#44992072)
It doesn't seem weird at all to me: standard is essentially the consensus of the major browser vendors; a spec which all of Chrome, Safari and Edge don't implement is really just a hypothetical.

The origin story of whatwg is that Apple, Mozilla and Opera decided that W3C wasn't making specs that they wanted to implement, so they created a new working group to make them.

Re:Show HN: JavaScript-free (X)HTML Includes by chrismorgan on Friday August 22, 2025 @09:44PM (#44992210)
> nobody bats an eye

I’ve seen a lot of eye-batting about this. Although Google, Mozilla and Apple are all in favour of removing it, there’s been a lot of backlash from developers.

Re:Show HN: JavaScript-free (X)HTML Includes by johncolanduoni on Friday August 22, 2025 @11:15PM (#44992793)
Most of whom had never heard of XSLT before today - some were likely born after it had faded into obscurity. I don’t blame people for hating Google for whatever reason, but this is a weird way to try to stick it to them.
Re:Show HN: JavaScript-free (X)HTML Includes by sunaookami on Saturday August 23, 2025 @06:17AM (#44994843)
XSLT is widely used, for example by the US congress: https://simonwillison.net/2025/Aug/19/xslt/
Re:Show HN: JavaScript-free (X)HTML Includes by lucumo on Saturday August 23, 2025 @08:28AM (#44995506)
Neither you nor the blog posts author had heard of that before that ridiculous GitHub issue from yesterday. You're all using the exact same link to the exact same page. This is intellectual dishonesty from you, the blog post author and the issue reporter.

Anyone who has read the response to the reporter knows that this is a cherry-picked alternative format. The normal format is an HTML5 page. Search engines just return that instead, so the only way to have found this page is by clicking through that.

Re:Show HN: JavaScript-free (X)HTML Includes by sunaookami on Saturday August 23, 2025 @09:06AM (#44995699)
So "it doesn't matter because other people already posted this example"?
Re:Show HN: JavaScript-free (X)HTML Includes by lucumo on Saturday August 23, 2025 @01:28PM (#44997557)
Is your intellectual dishonesty professional, or just a hobby?
Re:Show HN: JavaScript-free (X)HTML Includes by sunaookami on Sunday August 24, 2025 @08:49AM (#45003873)
So no arguments, got it.
Re:Show HN: JavaScript-free (X)HTML Includes by lucumo on Monday August 25, 2025 @02:28AM (#45010850)
Oh no, I have arguments. But you'd just pretend I said something else, so I see no point.
Re:Show HN: JavaScript-free (X)HTML Includes by johncolanduoni on Saturday August 23, 2025 @05:25PM (#44999267)
I think their point was that for everything the US congress makes available through client-rendered XSLT, they already also do the transformation on their side and serve the HTML under another page. Which I think is part of Google’s point - you can just compile the XSLT offline once (or during your release process) and provide the same experience without rewriting anything.
Re:Show HN: JavaScript-free (X)HTML Includes by lucumo on Monday August 25, 2025 @02:27AM (#45010844)
> I think their point was that for everything the US congress makes available through client-rendered XSLT, they already also do the transformation on their side and serve the HTML under another page.

More or less. I wasn't really about that argument, it was about the intellectual dishonesty of ignoring that it exists.

The original GitHub issue contained that link and was almost immediately answered. Everyone reading the issue report could have, should have and probably did read the answer.

The blog post doesn't mention the argument exists. To be fair to that author, it sounds like it was mostly "oh cool, this exists post", which doesn't need to go into pros and cons.

We can't extend that goodwill to sunaookami. They used it as an example that it's "widely used". Willfully ignoring that this example is pretty minor. (If this is the best example, it's not a good sign, BTW...)

I don't really care about XSLT support in browsers, but I do care about intellectual honesty in these debates. Nobody needs to agree with the argument. AFAIC, it's perfectly okay to believe that this page is of vital importance to the world. But that argument should then be made. That's how we go forward. How we get better decisions. That's how everybody learns.

If on the other hand people only repeat each other's most impressive sounding examples, then everybody gets dumber. We're no longer working to take a good decision through good arguments, but we'd be working to justify a made decision through bad arguments.

Re:Show HN: JavaScript-free (X)HTML Includes by ndriscoll on Saturday August 23, 2025 @07:14AM (#44995108)
More likely the people complaining are those who use it. I've been using it as the sane way to template my personal stuff for ~20 years. It works very well for "hand written" sites. I'm also not trying to be a top site or even visible to the wider world; my audience is my friends and family members. So to me it's a clear "that's not an important use case for the web now" signal.
Re:Show HN: JavaScript-free (X)HTML Includes by ekianjo on Friday August 22, 2025 @10:10PM (#44992387)
Even "champion of the web" Mozilla is on board. Tells you exactly what you need to know.
Re:Show HN: JavaScript-free (X)HTML Includes by johncolanduoni on Friday August 22, 2025 @10:17PM (#44992424)
To be fair, some things should be legitimately considered to be removed from the standard. O.G. XHTML basically mandated that you accept XML logic bombs and we got over that.

Also, while this is certainly Google throwing their weight around, I don’t think they are doing it for monetary advantage. I’m not sure how removing XSLT burnishes their ad empire the way things like nerfing ManifestV3 have. I think their stated reasons - that libxslt is a security disaster zone for an obscure 90s-era feature - is earnest even if its not actually in the broader web’s best interests. Now that Safari is publicly on board to go second, I suspect it’s an inevitability.

Re:Show HN: JavaScript-free (X)HTML Includes by Mikhail_Edoshin on Saturday August 23, 2025 @02:53AM (#44993872)
XML "logic bombs" happens when the parser expand entities eagerly. If a parser does that one can easily assemble an enormous entity that will eat up all the memory. But a more sophisticated parser won't expand entities right away and thus can merely reject oversized ones. It is really a minor issue.
Re:Show HN: JavaScript-free (X)HTML Includes by johncolanduoni on Saturday August 23, 2025 @05:28PM (#44999283)
There were other esoteric XML logic bomb inducing features is my recollection from all the stuff you used to have to change on the default XML Java parsers, but this was like 20 years ago so I may be misremembering.
Re:Show HN: JavaScript-free (X)HTML Includes by Mikhail_Edoshin on Sunday August 24, 2025 @03:39AM (#45002173)
I myself only remember the possible misuse of disk/URL reading features. These were indeed features and were added by design, but, of course, enabling them in non-trusted input could lead to all sorts of disasters.
Re:Show HN: JavaScript-free (X)HTML Includes by TiredOfLife on Saturday August 23, 2025 @06:51AM (#44994991)
Mozilla asked for removal. Google just filled the paperwork
Re:Show HN: JavaScript-free (X)HTML Includes by kome on Friday August 22, 2025 @07:57PM (#44991471)
so it's time to use XSLT more
Re:Show HN: JavaScript-free (X)HTML Includes by chrismorgan on Friday August 22, 2025 @09:21PM (#44992056)
> As of the next version of Chrome, XSLT will be gated behind a flag.

Citation? That would greatly surprise me in its abruptness and severity (they only just started talking about it this month, and acknowledge it’s particularly risky for enterprise) and https://chromestatus.com/feature/4709671889534976 gives no such indication.

Re:Show HN: JavaScript-free (X)HTML Includes by shakna on Friday August 22, 2025 @10:18PM (#44992433)
The meeting referenced there, from March not last month, also gives no indication that they'd go ahead and make any moves - "stick a pin in it". But they did anyway. [0]

panos: next item, removing XSLT. There are usage numbers.

stephen: I have concerns. I kept this up to date historically for Chromium, and I don't trust the use counters based on my experience. Total usage might be higher.

dan: even if the data were accurate, not enough zeros for the usage to be low enough.

mason: is XSLT supported officially?

simon: supported

mason: maybe we could just mark it deprecated in the spec, to make the statement that we're not actively working on it.

brian: we could do that on MDN too. This would be the first time we have something baseline widely available that we've marked as removed.

dan: maybe we could offer helpful pointers to alternatives that are better, and why they're better.

panos: maybe a question for olli. But I like brian's suggestion to mark it in all the places.

dan: it won't go far unless developers know what to use instead.

brian: talk about it in those terms also. Would anyone want to come on the podcast and talk about it? I'm guessing people will have objections.

emilio: we have a history of security bugs, etc.

stephen: yeah that was a big deal

mason: yeah we get bugs about it and have to basically ignore them, which sucks

brian: people do use it and some like it

panos: put a pin in it, and talk with olli next time?

panos: next thing is file upload control rendering

[0] https://github.com/whatwg/html/issues/11146#issuecomment-275...

Re:Show HN: JavaScript-free (X)HTML Includes by magicalist on Friday August 22, 2025 @11:01PM (#44992707)
> But they did anyway.

Did what? The GP asked for a citation for XSLT support going behind a flag in the next version of Chrome, but you forgot to add that. As best as I can tell, the GP is right and you're confused.

Re:Show HN: JavaScript-free (X)HTML Includes by troupo on Saturday August 23, 2025 @04:42AM (#44994409)
Tracking issue: https://issues.chromium.org/issues/435623334

Add flag to disable XSLT: https://chromium-review.googlesource.com/c/chromium/src/+/68...

It's approved, I don't know which release it will be.

Additionally, quote from the GitHub discussion:

--- start quote ---

Q: why has Chrome already started working on removing the feature from the browser?

A: To explore the effects of removal. It's hard to tell what will break without being able to turn it off and see.

https://github.com/whatwg/html/issues/11582#issuecomment-320...

--- end quote ---

Re:Show HN: JavaScript-free (X)HTML Includes by afavour on Saturday August 23, 2025 @05:46AM (#44994698)
> The GP asked for a citation for XSLT support going behind a flag in the next version of Chrome

> Add flag to disable XSLT

Two very different things. OP is talking about XSLT support going behind a flag, you’re citing XSLT deprecation going behind a flag. The default state matters (and the default state is undeprecated)

It makes sense that the Chrome team would do what they’re doing, otherwise it’s very difficult for anyone to assess the impact of XSLT deprecation.

Re:Show HN: JavaScript-free (X)HTML Includes by troupo on Saturday August 23, 2025 @07:02AM (#44995040)
> OP is talking about XSLT support going behind a flag, you’re citing XSLT deprecation going behind a flag.

Literally from my link:

--- start quote ---

Add a feature flag to disable XSLT

This adds a feature flag that disables:

- XSLTProcessor

- XSLT Processing Instructions

--- end quote ---

Re:Show HN: JavaScript-free (X)HTML Includes by afavour on Saturday August 23, 2025 @08:18AM (#44995443)
Literally from my comment:

> The default state matters (and the default state is undeprecated)

OP said “ But they did anyway”, and they did not

Re:Show HN: JavaScript-free (X)HTML Includes by chrismorgan on Saturday August 23, 2025 @11:32AM (#44996704)
I’d reword that: Google haven’t deprecated it (yet), they’ve added a flag whereby you can disable it (which, at this stage, is only being used by a test).

“Deprecate” has a specific meaning, largely unrelated to actual removal (though depending on the convention it may be expected to lead to it after some time).

Re:Show HN: JavaScript-free (X)HTML Includes by chrismorgan on Friday August 22, 2025 @11:13PM (#44992775)
By “started talking about it this month” I meant this specific advocation for removing it. Yes, it’s been talked about for years, but this time it’s specific.
Re:Show HN: JavaScript-free (X)HTML Includes by shakna on Friday August 22, 2025 @11:51PM (#44992983)
> brian: we could do that on MDN too. This would be the first time we have something baseline widely available that we've marked as removed.

They were advocating for removing it. And it was specific. And is labelled by the Chromium report you mentioned as the cause.

It wasn't "this month".

Re:Show HN: JavaScript-free (X)HTML Includes by chrismorgan on Saturday August 23, 2025 @02:24AM (#44993718)
Again, that’s prior discussion. It’s happened a few times over the last few years.

Then another few months pass, and one of the agitators goes about formally proposing removing it, so that finally it isn’t just murmurings more or less behind closed doors, but out in public for the developers to clamour about. That’s where we are this month.

Re:Show HN: JavaScript-free (X)HTML Includes by shakna on Saturday August 23, 2025 @06:54AM (#44995009)
Again, that prior discussion that you're dismissing as irrelevant - is the discussion the Chromium report links to! I don't think that can really get more definitive as cause and effect.
Re:Show HN: JavaScript-free (X)HTML Includes by chrismorgan on Saturday August 23, 2025 @01:01PM (#44997300)
I’m not calling it irrelevant, just not part of the actual proposal and ensuing furore, which began this month. We discover there have been mutterings of this for years, and certainly those things led up to it, but this was the first public intimation. They don’t ever say “hi public, we know this is the first you’ve heard about it, but we’re removing a major feature next month”, which is basically what you were claiming (or what it amounted to). Far simpler and less controversial changes have taken many months to be shipped.
Re:Show HN: JavaScript-free (X)HTML Includes by shakna on Saturday August 23, 2025 @09:50PM (#45000619)
Again, Google themselves say it was part of the discussion and where things started.

So why do you know better than the Chromium team?

Re:Show HN: JavaScript-free (X)HTML Includes by basscomm on Friday August 22, 2025 @07:41PM (#44991303)
Looks promising!

This looks like as good a place as any to show the XML/XSLT code that I've been tinkering with for the last couple of years: https://github.com/zmodemorg/wyrm.org

Re:Show HN: JavaScript-free (X)HTML Includes by raggi on Friday August 22, 2025 @08:04PM (#44991535)
I used to do this in the 2000's era, there was a lot to love about it. At the time though the IE engines were far more complete and less buggy than others with various XML features.
Re:Show HN: JavaScript-free (X)HTML Includes by b_e_n_t_o_n on Friday August 22, 2025 @08:05PM (#44991549)
This works client side right? So when a user navigates to this page, it recursively fetches content from the server? And if you have nested includes it would waterfall?

Even single page app frameworks have mostly solved this by doing the rendering on the server instead of making multiple round trips from the client. This feels like the no-JavaScript version of Spinnergeddon.

Does the browser wait for all the includes to resolve before showing the page or does it flicker in?

Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Friday August 22, 2025 @08:51PM (#44991846)
Looking at the xslt stylesheet , it doesn't look like there are nested includes, its just one stylesheet which doesn't include anything else. So its not that different in terms of requests than how css would work.
Re:Show HN: JavaScript-free (X)HTML Includes by magicalist on Friday August 22, 2025 @10:56PM (#44992671)
> Looking at the xslt stylesheet , it doesn't look like there are nested includes, its just one stylesheet which doesn't include anything else

At least the browser has to load template.xsl before it can know it has to load the css file though, right? And this is just a simple demo page.

Re:Show HN: JavaScript-free (X)HTML Includes by b_e_n_t_o_n on Saturday August 23, 2025 @12:43AM (#44993223)
It's making three round trips. The first is to get the original xml file, then it's to load the second xml file, then it's to load the stylesheet.

Now you can imagine with a real site, you will have many includes per page, each one perhaps using includes of it's own. You end up with a really bad waterfall where it can take a long time for a page to load because it's going back to the server constantly, whereas if you did it on the server it would be a single round trip.

Early SPA's did this, they would load a shell and then begin fetching from the client. Some still do but we know better than to do this for things that aren't web apps.

Re:Show HN: JavaScript-free (X)HTML Includes by lelanthran on Saturday August 23, 2025 @02:51AM (#44993867)
> You end up with a really bad waterfall where it can take a long time for a page to load because it's going back to the server constantly, whereas if you did it on the server it would be a single round trip.

These are all static file downloads, though. The first page load will take long, but if these are header/footer type includes, every subsequent page will use the cached file.

It's a trade-off between longer times for landing page and shorter times for every other page. The developer will decide whether or not to make the trade-off.

Re:Show HN: JavaScript-free (X)HTML Includes by Mikhail_Edoshin on Saturday August 23, 2025 @02:10AM (#44993650)
The stylistic includes and certain content (e. g. a site map) can be embedded in the XSLT itself.

It is not quite a templating engine. XSLT is a part of a semantic engine. Content is written in the way that fits the content. E. g. I write about some language and invent tags and notations that best fit what I am talking about: grammar, sounds, wrtiting. Or I write about chess and say something like (party id=abc move=15w). Then I make it available in HTML by providing a transform from my tags to HTML tags. My notation is rendered as a bunch of divs, ps and spans. This is merely a temporary rendering; other renderings may be possible.

A templating engine is the final document with placeholders for variable parts. XSLT can do that too, but this is less than its vision.

Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Saturday August 23, 2025 @03:21AM (#44994012)
I guess its ine extra layer, but its not like we've gone 14 layers deep or something.

I imagine preloading the css file using the http link header would solve this problem.

Re:Show HN: JavaScript-free (X)HTML Includes by dweinus on Friday August 22, 2025 @10:01PM (#44992318)
If you want server-side compilation, you could just run the xslt transform in ci/cd. It would still be a simpler solution than Jekyll in some regards, but I probably wouldn't do it for more than hobby projects
Re:Show HN: JavaScript-free (X)HTML Includes by xnx on Friday August 22, 2025 @08:21PM (#44991654)
Why didn't HTML imports stick around? https://web.dev/articles/imports
Re:Show HN: JavaScript-free (X)HTML Includes by lloydatkinson on Friday August 22, 2025 @09:38PM (#44992165)
The moronic Web Component cabal got their hands on it and trashed it by forcing it to rely on JavaScript, thus ensuring it would never get support.
Re:Show HN: JavaScript-free (X)HTML Includes by abraham on Friday August 22, 2025 @10:16PM (#44992418)
For a long time web components generally built on four standards:

  - Custom HTML elements
  - Shadow DOM
  - HTML imports
  - HTML templates
https://korban.net/posts/elm/2018-09-17-introduction-custom-...

Eventually it became clear some browsers were not going to implement and the design of HTML imports was better handled be ES modules.

https://webmasters.stackexchange.com/questions/127482/on-wha...

Re:Show HN: JavaScript-free (X)HTML Includes by bapak on Friday August 22, 2025 @11:04PM (#44992725)
Found this, it should answer your complaints:

> HTML Imports were redundant, since you need JavaScript to bring them alive anyways

Re:Show HN: JavaScript-free (X)HTML Includes by thayne on Friday August 22, 2025 @11:59PM (#44993016)
Exactly. I think the problem wasn't that browsers (specifically Firefox and Safari) were opposed to the idea of html includes in general, but they didn't like the specific proposal, in large part because it still required javascript, and added a lot of complexity for little to no benefit.

I think rejecting that proposal was the right thing to do. What disappoints me is that there hasn't been a more declaritive, simpler proposal that has gotten anywhere.

Re:Show HN: JavaScript-free (X)HTML Includes by xnx on Saturday August 23, 2025 @12:29AM (#44993165)
> What disappoints me is that there hasn't been a more declaritive, simpler proposal that has gotten anywhere.

Possible names: Client Side Includes (CSI): Like Server Side Includes (SSI) in Apache IHTML (inline html): Like the iframe tag, but for html instead of whole page.

Re:Show HN: JavaScript-free (X)HTML Includes by spankalee on Saturday August 23, 2025 @01:38AM (#44993500)
HTML Imports and HTML includes are two different ideas. HTML Imports was never like what people want from HTML includes.

HTML Imports were shelved because they didn't integrate with the JS module graph. HTML Modules will do that someday.

Re:Show HN: JavaScript-free (X)HTML Includes by spankalee on Saturday August 23, 2025 @01:36AM (#44993490)
I'm sorry, this a dumb comment that has no basis in reality.

HTML Imports was part of the initial set of the web components specs, there's no "cabal" or whatever that got its hands on it, and it didn't rely on JavaScript, not in the way you're probably referring to.

It was only opposed because it was separate from the JS module system, not because it relied on JS.

It's replacement: The HTML Modules proposal has general support from all vendors, just no one has put together a complete proposal yet.

Re:Show HN: JavaScript-free (X)HTML Includes by MortyWaves on Saturday August 23, 2025 @03:41AM (#44994097)
It was rejected because it needed JS to even work.
Re:Show HN: JavaScript-free (X)HTML Includes by spankalee on Saturday August 23, 2025 @04:25AM (#44994334)
This is simply not true, both in how it worked and why it was rejected.

HTML Imports didn't need JS to work: they used link tags and could transitively import HTML files without any JS.

You only needed JS because the wasn't anything you could do with the HTML yet because declarative custom elements don't exist yet.

HTML Imports were rejected because they created a parallel module graph to the JS module graph.

I think they could have been made to share the same graph, but that's basically what HTML modules are anyway.

Re:Show HN: JavaScript-free (X)HTML Includes by RebeccaTheDev on Friday August 22, 2025 @08:48PM (#44991822)
Three jobs ago I worked for a company that did e-learning systems for industrial clients. This was roughly 2004. One of the company owner's many ideas was a technical documentation system based on XML and XSLT. The "idea" being that technical writers or SMEs would rather write XML than, you know, use a word processor.

Unsurprisingly the idea did not take off, but I did find the XML/XSLT combination to be very interesting.

Re:Show HN: JavaScript-free (X)HTML Includes by the_other on Saturday August 23, 2025 @03:48AM (#44994123)
Between 2000 and 2003 I worked for a company that produced corporate training materials (initially on CDROM, later as learning-management-system units). We had a system which allowed the content authors to write in structured Word files. VBA would create XML of the Word files, and XSLT would create the HTML. I mostly worked in the XSLT and JS/CSS layers, not on the XML generation layer. It was my first job out of uni and I found XSLT fascinating and slightly psychedelic.
Re:Show HN: JavaScript-free (X)HTML Includes by Telemakhos on Saturday August 23, 2025 @03:59AM (#44994194)
Is this DITA? I always wondered who actually used that.

XSLT is also big in the TEI community in digital humanities. TEI gives a structured markup for reproducing printed volumes, which is important when you are dealing with variants of the same text, like revised editions of a text. XSLT lets you turn your TEI file into a web page for humans to read.

Re:Show HN: JavaScript-free (X)HTML Includes by OCTAGRAM on Friday August 22, 2025 @09:46PM (#44992220)
The most advanced usage of XSLT I've seen was in YBlog2, YML and YSLT, an alternative syntax for XML and XSLT. And IIUC they did not rely on browser-side although that may be still possible.
Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Friday August 22, 2025 @10:06PM (#44992355)
Since this seems to be about the recent proposal to remove xslt, i'd point out you can do the same thing with CSS

https://bawolff.net/css-website/index.xml is Evidlo's example but using a css stylesheet instead of xslt. I changed some of the text to explain what i was doing, but otherwise the XML is unchanged with one exception. Unfortunately you do have to put the <a> tags in the xhtml namespace to make them clickable. Other than that no changes to the xml.

Obviously there is a lot that xslt can do that css cannot, but when it comes to just display, CSS is an option here.

Re:Show HN: JavaScript-free (X)HTML Includes by 8organicbits on Friday August 22, 2025 @10:50PM (#44992644)
> there is a lot that xslt can do that css cannot

This latter part is why I've reached for XSLT in the past. Most recently was to convert an RSS feed into a styled page with instructions at the top. Templates and xpath can really transform a document.

Re:Show HN: JavaScript-free (X)HTML Includes by Evidlo on Saturday August 23, 2025 @01:34AM (#44993476)
Thanks for the CSS example.

By the way, the advanced/ folder has a slightly more complicated example that demonstrates template inheritance and "slots".

Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Saturday August 23, 2025 @03:23AM (#44994023)
Yeah, i saw. Unfortunately the advanced example wouldn't be doable in CSS. I suppose i'm being a bit intellectually dishonest to not explicitly point that out.
Re:Show HN: JavaScript-free (X)HTML Includes by Pxtl on Saturday August 23, 2025 @01:35AM (#44993479)
> i'd point out you can do the same thing with CSS

Cool when are they removing CSS from the standard?

Re:Show HN: JavaScript-free (X)HTML Includes by egeozcan on Saturday August 23, 2025 @01:39AM (#44993509)
This is really, definitely cool, but it's important to remember that content added via CSS is purely decorative. It can't be interacted with, which is a major issue for assistive technologies like screen readers.
Re:Show HN: JavaScript-free (X)HTML Includes by lelandfe on Saturday August 23, 2025 @10:37AM (#44996331)
I learned recently that you can provide accessible labels for content: https://www.stefanjudis.com/today-i-learned/css-content-acce...

I haven’t yet cracked open a screen reader to see how it fares, though.

Re:Show HN: JavaScript-free (X)HTML Includes by lenkite on Saturday August 23, 2025 @02:10AM (#44993652)
Umm..your CSS example doesn't show any template includes. No way to put header/footer in separate files.
Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Saturday August 23, 2025 @03:13AM (#44993974)
The original example didn't have that either.
Re:Show HN: JavaScript-free (X)HTML Includes by myfonj on Saturday August 23, 2025 @05:39AM (#44994658)
That's strange; the `head` and `footer` nodes were present in the XSL template this morning [1], last GH change was Feb 13 [2], what matches

    curl --head --silent --url https://xsl-website.widloski.com/template.xsl | grep modified
    last-modified: Thu, 13 Feb 2025 07:11:02 GMT
from here.

[1] at 09:11:48, according https://web.archive.org/web/*/http://xsl-website.widloski.co... [2] https://github.com/Evidlo/xsl-website/commits/master/templat...

Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Saturday August 23, 2025 @12:07PM (#44996917)
The footer is in the stylesheet in both my and Evidlo's example. In neither of our examples are these in separate files from the stylesheet.
Re:Show HN: JavaScript-free (X)HTML Includes by em-bee on Saturday August 23, 2025 @05:51AM (#44994722)
but they are in a separate file. the css file. you an load multiple css files if you want to break it out.
Re:Show HN: JavaScript-free (X)HTML Includes by em-bee on Saturday August 23, 2025 @05:50AM (#44994712)
that feels a bit to simplified. i'd like to see an example that includes at least some html, and maybe clickable links. it's maybe also worth showing that you can include images with css.
Re:Show HN: JavaScript-free (X)HTML Includes by mgr86 on Saturday August 23, 2025 @12:09AM (#44993067)
A small comment for anyone new to xslt. The author references a wildcard rule in the comments [0]. While that is true, they are calling an identity transformation [1]. Identity transformations are very common in xslt.

[0] https://github.com/Evidlo/xsl-website/blob/0dda1d82ce1eb01b7... [1] https://en.wikipedia.org/wiki/Identity_transform

Re:Show HN: JavaScript-free (X)HTML Includes by ulrischa on Saturday August 23, 2025 @02:25AM (#44993731)
To overcome the two problems here (client side loading the template and ending browser support) you could throw in php in the mix and have a wonderful solution for templating with bullet proof standards: // XML $xml_doc = new DOMDocument(); $xml_doc->load("file1.xml");

// XSL $xsl_doc = new DOMDocument(); $xsl_doc->load("file.xsl");

// Proc $proc = new XSLTProcessor(); $proc->importStylesheet($xsl_doc); $newdom = $proc->transformToDoc($xml_doc);

// Output print $newdom->saveXML();

XSLT lacks functionality? No problem, use php functions in xslt: https://www.php.net/manual/en/class.xsltprocessor.php

Re:Show HN: JavaScript-free (X)HTML Includes by Telemakhos on Saturday August 23, 2025 @11:59AM (#44996872)
What you're describing is basically Symphony, the CMS built around XSLT with some PHP and MySQL to glue things together: https://github.com/symphonycms/symphonycms

I don't think it's been updated since 2019. XSL was really powerful, but it had a steep learning curve, and I think server-side PHP and client-side JS were just more intuitive.

Re:Show HN: JavaScript-free (X)HTML Includes by ulrischa on Saturday August 23, 2025 @02:14PM (#44997930)
Cool project. Sadly it seems to be unmaintained
Re:Show HN: JavaScript-free (X)HTML Includes by tannhaeuser on Saturday August 23, 2025 @03:04AM (#44993928)
This is how the simplest variant of SGML (or XML) entities have worked since 1986:

    <!doctype html [
      <!entity e system "e.html">
    ]>
    <html>
      <title>Hello, world!</title>
      <p>The content of e is: &e;</p>
    </html>
HTML was envisioned as an SGML vocabulary from day one. That SGML's document composition and other facilities were used only at authoring time and not directly supported by browsers was merely due to the very early stage of the first browser software ([1]) which directly mentions SGML even, just as HTML specs have presented HTML as a language for authoring and not just delivery since at least version 4.

There really never had been a need or call for browser devs to come up with idiosyncratic and overcomplicated solutions relying on JavaScript for such a simple and uncontroversial facility as a text macro which was part of every document/markup language in existance since the 1960s.

[1]: https://info.cern.ch/hypertext/WWW/MarkUp/MarkUp.html

Re:Show HN: JavaScript-free (X)HTML Includes by myfonj on Saturday August 23, 2025 @05:08AM (#44994539)
I wish external entities were enabled in browsers (*), and not entirely disabled, like they are now.

In the OP scenario, it would provide possibility to have header/footer/stylesheet content in separate files and get system working that does not rely on absolute path of the CSS.

(*) Naturally, just with few minimal directory traversal precautions; basically anything like "no ../" and even restriction like "referenced resource filename must begin with referencing XSL filename" would be fine for me.

Re:Show HN: JavaScript-free (X)HTML Includes by DonHopkins on Saturday August 23, 2025 @06:17AM (#44994846)
XULRunner (Firefox, Thunderbird, Songbird, Miro, Joost, TomTom Home, etc) abused XML external entities in language specific DTDs for internationalization / localization.

https://www-archive.mozilla.org/projects/intl/iuc15/paper/iu...

https://en.wikipedia.org/wiki/XULRunner

Re:Show HN: JavaScript-free (X)HTML Includes by the_mitsuhiko on Saturday August 23, 2025 @07:22AM (#44995153)
> This is how the simplest variant of SGML (or XML) entities have worked since 1986:

In theory. In practice not a single browser had an actual SGML parser and that was never supported.

Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Saturday August 23, 2025 @12:12PM (#44996961)
Entities are also probably a significant reason for XML's bad reputation. Between using them to leak senditive files (XXE), and recursive expansion being a DoS vector (million laughs), it cemented XML's reputation as a security risk.

In the browser context though, i don't see why they couldn't just follow same origin rules.

Re:Show HN: JavaScript-free (X)HTML Includes by tannhaeuser on Saturday August 23, 2025 @01:27PM (#44997546)
I was surprised this wasn't brought up earlier, as it always is in these discussions. It's trivial to mitigate security risk arising out the use of entities. SGML even has the CAPACITY ENTLVL built-in entity nesting limit.

TBH, a browser has one million other potential leaks and exploits and denials to care about. Unlike a markup language with carefully crafted rules about what to expand in which context, a browser providing a Turing-complete language trivially runs into infinite loops or recursion and could at best heuristically terminate JS code, after using laborious best-efforts methods such as execution traces and watchdog timers. Moreover, JS syntax itself and how it's represented in markup unneccessarily gives rise to obfuscation and escaping attacks. And the browser in addition also plays fast and loose with an ever-expanding, potentially Turing-complete styling language with super complicated styling syntax and constraint-based layout models with a complete lack of formal semantics or any other formal reasoning. CSS itself can contain HTML literals at several places such as data URIs and the content property with questionable escaping, but I guess this is par for the course when CSS is basically just tunneling yet another syntax through HTML attributes and elements. Context Security Policy is just bolted on to limit this pointless and careless gratuitious syntax proliferation, and of course must invent its own little item-value microsyntax to be tunneled through HTTP headers and HTML header tags.

Considering these glaring and obvious deficits weren't discussed at the same time I assume those who brought up XXE and suggested SGML/XML could leak documents or smuggle executable instructions did so in bad faith or were repeating hearsay to sound clever or something.

Re:Show HN: JavaScript-free (X)HTML Includes by bawolff on Saturday August 23, 2025 @02:00PM (#44997823)
This is mostly not an issue in browsers so much as non browser implementations. Its not even really an issue in modern implementations with better defaults.

What it did do is create a perception that XML is insecure. This hastened its demise.

> It's trivial to mitigate security risk arising out the use of entities.

Obviously. However in practise, historically most implementations did not. At least not by default.

XML spec bears some responsibility for this for not being explicit about suggesting secure defaults.

Regardless, JSON won partially because it didnt have the attack surface, so people didn't have to worry. XML being theoretically easy to secure means nothing when practically implementations made it difficult.

Re:Show HN: JavaScript-free (X)HTML Includes by msylvest on Saturday August 23, 2025 @04:24AM (#44994328)
I remember admiring the intent of XSLT when it was born. And how difficult it turned out to be to write; using XML framing makes it terse/verbose/arcane, eg. when compared to the compactness of regex/subs.

It is 2025 and now we've got LLMs to write our code - that may actually be a strong argument in favor of keeping XSL(T): It is a useful browser mechanism and LLMs makes it easier to harvest.

Does anybody have experience with LLM-generated XSL(T)?

Re:Show HN: JavaScript-free (X)HTML Includes by reacweb on Saturday August 23, 2025 @06:24AM (#44994878)
I have 1 "big" xsl file in a project I maintain. I have fixed an issue this year. I have tried to use chatgpt prompt. The scope was perfect: I had the buggy xsl, the buggy result, the expected result and a clear explanation. It generated syntactically correct code (almost) that did not work because chatgpt does not understand. This was not a complete loss: a good refresher of the syntax, but I had to do the thinking fully alone and found alone how to use "node-set".

My previous change in this file was in 2017 when I replaced xalan by the xslt processor built in java. I was very surprised I had to make the following changes:

    -<xsl:if test="string(serverName)=$sName">
    +<xsl:if test="string(serverName)=string($sName)">

    -<xsl:for-each select="attributeList/attribute[self::attribute!='']">
    +<xsl:for-each select="attributeList/attribute[text()!='']">

    -<xsl:if test="preceding-sibling::Connection[featureType='Receptacle'][position() = 1]/@Name!=@Name or not(preceding-sibling::Connection[featureType='Receptacle'][position() = 1]/node()) ">
    +<xsl:if test="preceding-sibling::Connection[position() = 1]/@Name!=@Name or position()=1">
These incompatibility issues with something I considered to be standard greatly damaged my opinion on xslt.
Re:Show HN: JavaScript-free (X)HTML Includes by postepowanieadm on Saturday August 23, 2025 @04:39AM (#44994389)
Can we have xml/xhtml back? It makes perfect sense in the age of LLMs.
Re:Show HN: JavaScript-free (X)HTML Includes by cranberryturkey on Saturday August 23, 2025 @04:53AM (#44994463)
I'm bummed that w3c dropped xslt
Re:Show HN: JavaScript-free (X)HTML Includes by em-bee on Saturday August 23, 2025 @05:32AM (#44994630)
this is exactly how i built my site with help of a fellow HNer: https://news.ycombinator.com/item?id=44966886
Re:Show HN: JavaScript-free (X)HTML Includes by mjaniczek on Saturday August 23, 2025 @05:35AM (#44994640)
Reminds me of Symphony CMS, which is XSLT based. Cool concept but not entirely practical in my experience.
Re:Show HN: JavaScript-free (X)HTML Includes by ulrischa on Saturday August 23, 2025 @02:16PM (#44997938)
Cool project. Sadly it seems to be unmaintained
Re:Show HN: JavaScript-free (X)HTML Includes by DonHopkins on Saturday August 23, 2025 @06:28AM (#44994900)
What's the whole point of bending over backwards to be "JavaScript-free" when the chosen alternative is using something as half-assedly hamstrung and counterintuitively crippled and mind-bogglingly rube-goldbergesque as XSLT, that tries to be all things to all people, thus satisfying no-one?

My impression of XSLT's design is that there were partisan representatives from every popular programming language paradigm on the XSLT standard committee, and each one of them was able to get just enough to showcase what was special about their own paradigm into the standard, while strategically sabotaging all the other competing paradigms to undermine and beclown each other, but not enough for practical coherency, or lord forbid neatly dovetailing together into a synergistic design.

When the Lisp faction evals and applies their functional paradigm, the BASIC faction runs to goto their imperative paradigm, and the Prolog faction is horny and unified that its logical paradigm makes the cut, the result is dysfunctional emparitive illogical programming.

Jeff Atwood points out that "Martin Fowler hates XSLT too":

https://blog.codinghorror.com/martin-fowler-hates-xslt-too/

I have no problem with XML. It’s a fine way to store hierarchical data in a relatively simple, mostly human-readable format. But I’ve always disliked its companion technology, XSLT. While useful in theory – “using a simple XSLT transform, XML can be converted into anything!”– in practice, it takes painful contortions to do anything practical. Evidently I’m not alone; Martin Fowler hates XSLT too:

>All of this site is written in simple XML documents and transformed to HTML. I find this works really well, and means I never have to worry about dealing with HTML formats. (Not that fancy layout is my style, as you can tell.) I’ve even written a whole book that way.

>For most of this time I’ve used XSLT as my transformation language. I’ve got pretty good with slinging XSLT around and getting it to do what I want.

>But no more.

>When I wrote the software for this Bliki (on a long flight) I did it in Ruby. Prior to that I used Ruby to do a new version of my home page. My conclusion from this exercise was that using Ruby for XML transforms was much easier than using XSLT.

I’ve had almost the same exact argument with a few developers I used to work with. After working through a bit of the XSLT necessary to accomplish something, I concluded that it was easier and simpler to use procedural code to do the same thing. Not always, of course, but most of the time. As Fowler points out, this does beg the question: what good is XSLT?

I think this may raise some real questions about XSLT. There’s still much I like about the power of XSLT, but I hate the syntax and the walls you keep running into. I’m not going to convert my whole site over to Ruby tomorrow – most of the XSLT works fine - but I can certainly see my way to doing that at some point in the future. But the bigger question is whether you’re better off with scripting language for this kind of task than XSLT.

Maybe the idea of XSLT transforming XML into “anything” is fundamentally unrealistic – just more Write Once, Run Anywhere snake oil.

Re:Show HN: JavaScript-free (X)HTML Includes by Mikhail_Edoshin on Sunday August 24, 2025 @03:59AM (#45002290)
I worked with XSLT a lot and I like it, but agree that a general-purpose programming language, preferably procedural, is more convenient and more powerful.

The reason XSLT is this way may be similar to why SQL is this way. SQL is declarative primarily because it isolates the user from concurrency. It would be much easier to write a procedure to fetch the data the way you want, but to write a concurrent procedure that does this safely and nicely among other such procedures would be much harder. XSLT was meant to be used with XML documents of unknown quality, so the logic of what is going on should be traceable. And XSLT did this rather well, given the constraints.

Upd: The constraints, as I see them, were that: the code will be written mostly by non-professionals (there were no professionals yet) so it should not be easy for them to get into an endless loop or otherwise shoot themselves in the foot. CSS faced similar constraints and was always rather awkward; nowadays it is also too complex and is only a formatting engine, not a transformation engine.

E.g. if XSLT was the main engine of the web CSS stylesheets would be unnecessary. The attributes could be placed on the elements themselves as this happens in XSL-FO. This would remove a major source of complexity; look at Tailwind, how popular it is, and why? Exactly because it removes an indirection step and instead of providing an external formatting rule merely formats an element directly.

Re:Show HN: JavaScript-free (X)HTML Includes by Kuyawa on Saturday August 23, 2025 @11:35AM (#44996720)
20 years ago I saw the greatness of xml and xslt as I was coming from the painful inferno of an EDI shop. There is nothing more beautiful than sending plain data to a client and being able to see the whole document without any extra bloating, that's what XSLT was intended for:

  <?xml version="1.0"?>
  <?xml-stylesheet type="text/xsl" href="/invoice.xsl"?>
  <invoice>
    <date>2025-08-23</date>
    <customer>
      <name>John Doe</name>
      <address>
        <line>123 Sunny Boulevard</line>
        <city>Miami</city>
        <state>FL</state>
        <zip>33133</zip>
      </address>
    </customer>
    <items>
      <item>
        <code>123456</code>
        <description>Some Apple gadget</description>
        <quantity>1</quantity>
        <price>1234.56</price>
        <total>1234.56</total>
      </item>
      <item>more items...</item>
    </items>
  </invoice>
That piece of data would be sent to millions of customers and they could open it and the XML was transformed in an invoice perfectly formatted for human consumption. Both flesh and silicon were living happy in perfect harmony.

Then it came SOAP and all the corporate suits and messed it all up into an extra complicated bloatness of anguish and suffering, but XML/XSLT were beautiful on their own (for data transformation, not web pages)

Re:Show HN: JavaScript-free (X)HTML Includes by Kuyawa on Saturday August 23, 2025 @12:29PM (#44997055)
If we extrapolate it all to JSON, all we need to do is add two lines to the data file to reference the JSLT source and then use any templating system as default (ejs, mustache, handlebars) to do the transformation in the browser

  {
    "JSLT": "1.0",
    "style": "/invoice.jsl",
    "data": {
      "invoice":{
        "date": "2025-08-23",
        "customer": {
          "name": "John Doe",
          "address": {
            "line": "123 Sunny Boulevard",
            "city": "Miami",
            "state": "FL",
            "zip": "33133",
          },
        },
        "items": [
          {
            "code": "123456",
            "description": "Some Apple gadget",
            "quantity": "1",
            "price": "1234.56",
            "total": "1234.56",
          },
          {
            "code": "123457",
            "description": "Another Apple gadget",
            "quantity": "1",
            "price": "1234.57",
            "total": "1234.57",
          }
        ]
      }
    }
  }
Then the JSLT file:

  <html>
  <body>
    <h2>Invoice</h2>
    <p><label>Date</label> <span><%=data.invoice.date%></span></p>
    <div>
      <h3>Customer</h3>
      <p><%=data.invoice.customer.name%></p>
      <p>
        <%=data.invoice.customer.address.line%>
        <%=data.invoice.customer.address.city%>
        <%=data.invoice.customer.address.state%>
        <%=data.invoice.customer.address.zip%>
      </p>
    </div>
    <table>
      <tr>
        <th>Code</th>
        <th>Description</th>
        <th>Quantity</th>
        <th>Price</th>
        <th>Total</th>
      </tr>
      <% for(item of invoice.items) { %>
        <tr>
          <td><%=item.code%></td>
          <td><%=item.description%></td>
          <td><%=item.quantity%></td>
          <td><%=item.price%></td>
          <td><%=item.total%></td>
        </tr>
      <% } %>
    </table>
  </body>
  </html>
Then we could get rid of XSLT