Why can't HTML alone do includes?
366 comments
·May 3, 2025dwheeler
int_19h
We also had a brief detour into XML with XHTML, and XML has XInclude, although it's not a required feature.
echelon
It's too bad we didn't go down the XHTML/semantic web route twenty years ago.
Strict documents, reusable types, microformats, etc. would have put search into the hands of the masses rather than kept it in Google's unique domain.
The web would have been more composible and P2P. We'd have been able to slurp first class article content, comments, contact details, factual information, addresses, etc., and built a wealth of tooling.
Google / WhatWG wanted easy to author pages (~="sloppy markup, nonstandard docs") because nobody else could "organize the web" like them if it was disorganized by default.
Once the late 2010's came to pass, Google's need for the web started to wane. They directly embed lifted facts into the search results, tried to push AMP to keep us from going to websites, etc.
Google's decisions and technologies have been designed to keep us in their funnel. Web tech has been nudged and mutated to accomplish that. It's especially easy to see when the tides change.
GuB-42
As a programmer, I really liked XHTML because it meant I could use a regular XML parser/writer to work with it. Such components can be made small and efficient if you don't need the more advanced features of XML (ex: schemas), on the level of JSON. I remember an app I wrote that had a "print" feature that worked by generating an HTML document. We made it XHTML, and used the XML library we already used elsewhere to generate the document. Much more reliable than concatenating strings (hello injections!) and no need for an additional dependency.
In addition, we used XSLT quite a bit too. It is nice being able to open your XML data files in a web browser and having it nicely formatted without any external software. All you needed was a link to the style sheet.
geoffmunn
The thing I liked the most about XHTML was how it enforced strict notation.
Elements had to be used in their pure form, and CSS was for all visual presentation.
It really helped me understand and be better at web development - getting the tick from the XHTML validator was always an achievement for complicated webpages.
kweingar
I don't think there was ever a sustainable route to a semantic web that would work for the masses.
People wanted to write and publish. Only a small portion of people/institutions would have had the resources or appetite to tag factual information on their pages. Most people would have ignored the semantic taxonomies (or just wouldn't have published at all). I guess a small and insular semantic web is better than no semantic web, but I doubt there was a scenario where the web would have been as rich as it actually became, but was also rigidly organized.
alabastervlog
I kinda bailed on being optimistic/enthusiastic about the Web when xhtml wasn't adopted as the way forward.
It was such a huge improvement. For some reason rather than just tolerating old tag-soup mess while forging the way for a brighter future, we went "nah, let's embrace the mess". WTF.
It was so cool to be able to apply XML tools to the Web and have it actually work. Like getting a big present for Christmas. That was promptly thrown in a dumpster.
tannhaeuser
The "semantic" part was what eventually became W3C's RDF stuff (a pet peeve of TBL's predating even the Web). When people squeeze poetry, threaded discussion, and other emergent text forms into a vocabulary for casual academic publishing and call that "semantic HTML", that still doesn't make it semantic.
The "strict markup" part can be (and always could be) had using SGML which is just a superset of XML that also supports HTML empty elements, tag inference, attribute shortforms, etc. HTML was invented as SGML vocabulary in the first place.
Agree though that Google derailed any meaningful standardization effort for the readins you stated. Actually, it started already with CSS and the idioticy to pile yet another item-value syntax over SGML/HTML, when it already has attributes for formatting. The "semantic HTML" postulate is kind of just an after-the-fact justification for insane CSS complexity that could grow because it wasn't part of HTML proper and the scrutinity that goes with introducing new elements or attributes with it.
riffraff
I kinda agree with you but I'd argue the "death" of microformats is unrelated to the death of XHTML (tho schema.org is still around).
You could still use e.g. hReview today, but nobody does. In the end the problem of microformats was that "I want my content to be used outside my web property" is something nobody wants, beyond search engines that are supposed to drive traffic to you.
The fediverse is the only chance of reviving that concept because it basically keeps attribution around.
tsimionescu
The semantic web is a silly dream of the 90s and 00s. It's not a realizabile technology, and Google basically showed exactly why: as soon as you have a fixed algorithm for finding pages on the web, people will start gaming that algorithm to prioritize their content over others'. And I'm not talking about malicious actors trying to publish malware, but about every single publisher that has theoney to invest in figuring out how and doing it.
So any kind of purely algorithmic, metadata based retrieval algorithm would very quickly return almost pure garbage. What makes actual search engines work is the constant human work to change the algorithm in response to the people who are gaming it. Which goes against the idea of the semantic web somewhat, and completely against the idea of a local-first web search engine for the masses.
int_19h
Me personally, I didn't even care that much about strict semantic web, but XML has the benefits of the entire ecosystem around it (like XPath and XSLT), composable extensibility in form of namespaces etc. It was very frustrating to see all that thrown out with HTML5, and the reasoning never made any sense to me (backwards compatibility with pre-XHTML pages would be best handled by defining a spec according to which they should be converted to XHTML).
tannhaeuser
The XML subset of SGML still includes most forms of entity usage SGML has, including external general entities as described by grandparent. XInclude can include any fragment not just a complete document, but apart from that was redundant, and what remains of XInclude in HTML today (<svg href=...>) doesnt't make use of fragments and also does away with the xinclude and other namespaces. For reusing fragments OTOH, SVG has the more specific <use href=...> construct. XInclude also really worked bad in the presence of XML Schema.
j45
Neat reference, going to look into that.
The <object> tag appears to include/embed other html pages.
An embedded HTML page:
<object data="snippet.html" width="500" height="200"></object>
nephyrin
<object> used like this is just a poor iframe in a much shakier spot in the standards, mostly for backwards compatibility.
Like iframe, it "includes" a full subdocument as a block element, which isn't quite what the OP is hinting at.
gpvos
Sound like it's good enough for headers and footers, which is 80% of what people need.
j45
It’s an option built into html.
The OP doesn’t need to hint.
jazzypants
Yeah, that is just a crappier version of HTML Frames [1]
j45
I don’t disagree, the premise of the article seems to be unaware, it’s entirely possible to us html alone to do includes. :)
Some might argue react is over abstracted or over engineered to do the same.
Interpretation and preference is different than if it’s possible
timewizard
Well, that is an entire attack surface, on it's own.
bawolff
https://en.wikipedia.org/wiki/XML_external_entity_attack would be the more relavent link.
lkuty
It existed also in DTD (Document Type Definition) used with HTML 4 and below, and XML. Came fromn SGML too I guess.
tannhaeuser
Yes it did, and there are HTML 5.x DTDs for HTML versions newer than HTML 4.x ar [1], including post-HTML 5.2 review drafts until 2023; see notes at [2].
dimal
This was the rabbit hole that I started down in the late 90s and still haven’t come out of. I was the webmaster of the Analog Science Fiction website and I was building tons of static pages, each with the same header and side bar. It drove me nuts. So I did some research and found out about Apache server side includes. Woo hoo! Keeping it DRY (before I knew DRY was a thing).
Yeah, we’ve been solving this over and over in different ways. For those saying that iframes are good enough, they’re not. Iframes don’t expand to fit content. And server side solutions require a server. Why not have a simple client side method for this? I think it’s a valid question. Now that we’re fixing a lot of the irritation in web development, it seems worth considering.
EvanAnderson
Server-side includes FTW! When a buddy and I started making "web stuff" back in the mid-90s the idea of DRY also just made sense to us.
My dialup ISP back then didn't disable using .htaccess files in the web space they provided to end users. That meant I could turn on server-side includes! Later I figured out how to enable CGI. (I even went so far as to code rudimentary webshells in Perl just so I could explore the webserver box...)
matchagaucho
I've become a fan of https://htmx.org for this reason.
A small 10KB lib that augments HTML with the essential good stuff (like dynamic imports of static HTML)
HumanOstrich
Seems like overkill to bring in a framework just for inlining some static html. If that's all you're doing, a self-replacing script tag is neat:
<script>
function includeHTML(url) {
const s = document.currentScript
fetch(url).then(r => r.text()).then(h => {
s.insertAdjacentHTML('beforebegin', h)
s.remove()
})
}
</script>
... <script>
includeHTML('/footer.html')
</script>
The `script` element is replaced with the html from `/footer.html`.librasteve
this here is the main idea of HTMX - extended to work for any tag p, div, content, aside …
there are many examples of HTMX (since it is a self contained and tiny) being used alongside existing frameworks
of course for some of us, since HTMX brings dynamic UX to back end frameworks, it is a way of life https://harcstack.org (warning - raku code may hurt your eyes)
johnisgood
But this requires JavaScript...
gforce_de
The minified version needs ~51 kilobytes (16 compressed):
$ curl --location --silent "https://unpkg.com/htmx.org@2.0.4" | wc -c
50917
$ curl --location --silent "https://unpkg.com/htmx.org@2.0.4" | gzip --best --stdout | wc -c
16314recursivedoubts
see fixi if you want bare-bones version of the same idea:
unilynx
> Iframes don’t expand to fit content
Actually, that was part of the original plan - https://caniuse.com/iframe-seamless
omneity
I used the seamless attribute extensively in the past, it still doesn't work the way GP intended, which is to fit in the layout flow, for example to take the full width provided by the parent, or automatically resize the height (the pain of years of my career)
It worked rather like a reverse shadow DOM, allowing CSS from the parent document to leak into the child, removing borders and other visual chrome that would make it distinguishable from the host, except you still had to use fixed CSS layouts and resize it with JS.
atoav
I mean in 1996s netscape you could do this (I run the server for a website that still uses this):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<frameset cols="1000, *">
<frame src="FRAMESET_navigation.html" name="navigation">
<frame src="FRAMESET_home.html" name="in">
</frameset>
</html>
The thing that always bugged me about frames is that they are too clever. I don't want to reload only the frame html when I rightclick and reload. Sure the idea was to cache those separately, but come on — frames and caching are meant to solve two different problems and by munching them together they somewhat sucked at solving either.To me includes for HTML should work in the dumbest way possible. And that means: Take the text from the include and paste it where the include was and give the browser the resulting text.
If you want to cache a nav section separately because it appears the same on every page lets add a cache attribute that solves the problem independently:
<nav cache-id="deadbeefnav666">
<some-content></etc>
</nav>
To tell the browser it should load the inner html or the src of that element from cache if it has it.Now you could convince me thst the include should allow for more, but it being dumb is a feature not a bug.
lodovic
Nitpick: the HTML4 spec was released in December 1997, and HTML4.01 only in December 1999 so it probably wouldn't have run in 1996s Netscape.
JimDabell
The doctype doesn’t matter in this context. Netscape Navigator 2 supported frames in 1995 and would render that page.
cobbaut
Back then it was common for Netscape to have features that (years) later became standard HTML.
codr7
The optimal solution would be using a template engine to generate static documents.
JadeNB
> The optimal solution would be using a template engine to generate static documents.
This helps the creator, but not the consumer, right? That is, if I visit 100 of your static documents created with a template engine, then I'll still be downloading some identical content 100 times.
giantrobot
XSLT solved this problem. But it had poor tool support (DreamWeaver etc) and a bunch of anti-XML sentiment I assume as blowback from capital-E Enterprise stacks going insane with XML for everything.
XSLT did exactly what HTML includes could do and more. The user agent could cache stylesheets or if it wanted override a linked stylesheet (like with CSS) and transform the raw data any way it wanted.
iainmerrick
I'll still be downloading some identical content 100 times.
That doesn't seem like a significant problem at all, on the consumer side.
What is this identical content across 100 different pages? Page header, footer, sidebar? The text content of those should be small relative to the unique page content, so who cares?
Usually most of the weight is images, scripts and CSS, and those don't need to be duplicated.
If the common text content is large for some reason, put the small dynamic part in an iframe, or swap it out with javascript.
If anyone has a genuine example of a site where redundant HTML content across multiple pages caused significant bloat, I'd be interested to hear about it.
Klaster_1
Compression Dictionary Transport [0] seems like something that can potentially address this. If you squint, this looks almost like XSLT.
[0] https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Com...
codr7
True for any server side solution, yes.
On the other hand it means less work for the client, which is a pretty big deal on mobile.
keeganpoppen
macros!
econ
You can message the page dimensions to the parent. To do it x domain you can load the same url into the parent with the height in the #location hash. It won't refresh that way.
dimal
I know it’s possible to work around it, but that’s not the point. This is such a common use case that it seems worthwhile to pave the cowpath. We’ve paved a lot of cowpaths that are far less trodden than this one. This is practically a cow superhighway.
We’ve built an industry around solving this problem. What if, for some basic web publishing use cases, we could replace a complex web framework with one new tag?
econ
I couldn't agree more.
<div src="foo.txt"></div>
lelanthran
> We’ve built an industry around solving this problem. What if, for some basic web publishing use cases, we could replace a complex web framework with one new tag?
I actually did that replacement, with a few enhancements (maybe 100 lines of code, total?). It's in arxiv pending at the moment. In about two days it will be done and I'll post a Show HN here.
rbanffy
> Woo hoo! Keeping it DRY (before I knew DRY was a thing)
I still remember the script I wrote to replace thousands (literally) slightly different headers and footers in some large websites of the 90s. How liberating to finally have that.
RenThraysk
Don't Service Workers API provide this now, essentially act like a in-browser proxy to the server.
https://developer.mozilla.org/en-US/docs/Web/API/Service_Wor...
bradly
Rational or not, some of us try very hard to avoid JavaScript based solutions.
RenThraysk
As a dev from the early 90s, I share the sentiment. Watching javascript become more and more complex and bloated for little to no benefit to the end user.
throwup238
The feature proposal was called HTML Imports [1], created as part of the Web Components effort.
> HTML Imports are a way to include and reuse HTML documents in other HTML documents
There were plans for <template> tag support and everything.
If I remember correctly, Google implemented the proposed spec in Blink but everyone else balked for various reasons. Mozilla was concerned with the complexity of the implementation and its security implications, as well as the overlap with ES6 modules. Without vendor support, the proposal was officially discontinued.
xg15
That matches with the comment [1] on the article, citing insufficient demand, no vendor enthusiasm, etc.
The thing is that all those are non-reasons that don't really explain anything: Low demand is hard to believe if this feature is requested for 20 years straight and there are all kinds of shim implementations using scripts, backend engines, etc. (And low demand didn't stop other features that the vendors were interested in for their own reasons)
Vendor refusal also doesn't explain why they refused it, even to the point of rolling back implementations that already existed.
So I'd be interested to understand the "various reasons" in more detail.
"Security implications" also seem odd as you already are perfectly able to import HTML cross origin using script tags. Why is importing a script that does document.write() fine, but a HTML tag that does exactly the same thing hugely problematic?
(I understand the security concern that you wouldn't want to allow something like "<import src=google.com>" and get an instant clone of the Google homepage. But that issue seems trivially solvable with CORS.)
[1] https://frontendmasters.com/blog/seeking-an-answer-why-cant-...
athrowaway3z
That is a bit of a large ask.
There are various specs/semantics you can choose, which prescribe the implementation & required cross-cutting complexity. Security is only relevant in some of them.
To give you some idea:
- HTML load ordering is a pretty deeply held assumption. People understand JS can change those assumptions (document.write). Adding an obscure HTML tags that does so is going to be an endless parade of bugs & edge cases.
- To keep top-to-bottom fast we could define preload semantics (Dropping the linear req-reply, define client-cache update policy when the template changes, etc). Is that added complexity truly simpler than having the server combine templates?
- <iframe> exists
In other words, to do the simplest thing 75% of people want, requires a few lines of code. Either client side or server side.
To fit the other 25% (even to 'deny' it) is endlessly complex in ways few if any can oversee.
NoahZuniga
Maybe something that adds to this low demand is that: 1. Web pages that are developed from the viewpoint of the user having JS, makes it trivial to implement something that provides the same results. 2. Web pages that are developed for user agents that don't run js, probably want to have some interaction, so already have a server runtime that can provide this feature. 2b. And if it doesn't have any user interaction, its probably a static content site, and nobody is writing content in HTML, so there already is a build step that provides this feature.
mildred593
HTML imports could not include markup within the body, it could only be used to reference template elements for custom elements
brundolf
JS-first developers want something that works the same way client-side and server-side, and the mainstream front-end dev community shifted to JS-first, for better or worse
uallo
HTML Imports went in a similar direction but they do not do what the blog post is about. HTML should be imported and displayed in a specific place of the document. HTML Imports could not do this without JavaScript.
See https://github.com/whatwg/html/issues/2791#issuecomment-3112... for details.
thayne
To be fair, it was pretty complicated. IIRC, using it required using Javascript to instantiate the template after importing it, rather than just having something like <include src="myinclude.html">.
riedel
https://caniuse.com/imports says FF even had it as a config flag
paulddraper
Tbf, HTML Imports were significantly more complex than includes, which this article requests.
AtlasBarfed
Frames essentially could do html import
Lammy
Netscape 4 has this with inflow layers — `<ILAYER SRC=included.html></ILAYER>`
https://web.archive.org/web/19970630074729fw_/http://develop...
https://web.archive.org/web/19970630094813fw_/http://develop...
masswerk
As far as I'm aware of it, changing the SRC-attribute was quite crash-y and the functionality was stripped soon. (I remember playing with this in beta, and then it was gone in the production version.)
blorto
I always wondered why it was called ILAYER. Ty
Null-Set
The name of this feature is transclusion.
https://en.wikipedia.org/wiki/Transclusion
It was part of Project Xanadu, and originally considered to be an important feature of hypertext.
Notably, mediawiki uses transclusion extensively. It sometimes feels like the wiki is the truest form of hypertext.
jes5199
Ward Cunningham (inventor of the Wiki) spent some time trying to invent a transclusion-first wiki, where everyone had their own wiki-space and used transclusion socially https://en.wikipedia.org/wiki/Federated_Wiki
it never quite took off
PaulHoule
I think true transclusion would be more than that.
In Xanadu you could transclude just an excerpt from one document into another document.
If you wanted to do this with HTML you need an answer for the CSS. In any particular case you can solve it, making judgements about which attributes should be consistent between the host document, the guest document and the guest-embedded-in-host. The general case, however, is unclear.
For a straightforward <include ...> tag the guest document is engineered to live inside the CSS environment (descendant of the 3rd div child of a p that has class ".rodney") that the host puts it in.
Another straightforward answer is the Shadow DOM which, for the most part, lets the guest style itself without affecting the rest of the document. I think in that case the host can still put some styles in to patch the guest.
Linux-Fan
Isn't this what proper framesets (not iframes) were supposed to do a long time ago (HTML 4?). At least they autoexpanded just fine and the user could even adjust the size to their preference.
There was a lot of criticism for frames [1] but still they were successfully deployed for useful stuff like Java API documentation [2].
In my opinion the whole thing didn't stay mostly because of too little flexibility for designer: Framesets were probably well enough for useful information pages but didn't account for all the designers' needs with their bulky scrollbars and limited number of subspaces on the screen. Today it is too late to revive them because framesets as-is wouldn't probably work well on mobile...
[1] <https://www.nngroup.com/articles/why-frames-suck-most-of-the...> - I love how much of it is not applicable anymore and all of these problems mentioned with frames are present in today's web in an even nastier way?
[2] <https://www.eeng.dcu.ie/~ee553/ee402notes/html/figures/JavaD...>
johannes1234321
Issue with frame set was way more fundamental: No deep linking, thus people coming via bookmarks or Google (or predecessor) were left on a page without navigation, which people then tried working around with JavaScript, which never gave it a good experience.
Linux-Fan
Nowdays it is sometimes the other way around: Pages are all JavaScript so no good experience in the first place. I have encountered difficulty trying to get a proper “link” to something multiple times. Also, given that Browsers love to reduce/hide the address bar I wonder if it is really still that important a feature.
Of course "back then" this was an important feature and one of the reasons for getting rid of frames :)
rchaud
"Includes" functionality is considered to be server-side, i.e. handled outside of the web browser. HTML is client-side, and really just a markup syntax, not a programming language.
As the article says, the problem is a solved one. The "includes" issue is how every web design student learns about PHP. In most CMSes, "includes" become "template partials" and are one of the first things explained in the documentation.
There really isn't any need to make includes available through just HTML. HTML is a presentation format and doesn't do anything interesting without CSS and JS anyway.
naasking
> "Includes" functionality is considered to be server-side, i.e. handled outside of the web browser. HTML is client-side, and really just a markup syntax, not a programming language.
That's not an argument that client-side includes shouldn't happen. In fact HTML already has worse versions of this via frames and iframes. A client-side equivalent of a server-side include fits naturally into what people do with HTML.
tgv
I think it feels off because an HTML file can include scripts, fonts, images, videos, styles, and probably a few other things. But not HTML. It can probably be coded with a custom element (<include src=.../>). I would be surprised if there wasn't a github repo with something similar.
benstigsen
I created something like this relatively recently. The downside is of course that it requires JavaScript.
mildred593
I also improved an existing custom component for this : https://amc.melanie-de-la-salette.fr/polyfill.js
cantSpellSober
Well said this is many students' intro to PHP. Why not `<include src=header.html/>` though?
Some content is already loaded asynchronously such as images, content below the fold etc.
> HTML is really just a markup syntax, not a programming language
flamebait detected :) It's a declarative language, interpreted by each browser engine separately.
gyesxnuibh
What's the ML in HTML stand for? I think that's probably the crux of the argument. Are we gonna evolve it past its name?
Aloisius
If the issue is that "include" somehow makes it sound like it's not markup, the solution seems obvious. Just use the src attribute on other tags:
<html src="/some/page.html">, <div src="/some/div.html">, <span src="/some/span.html">, etc.
Or create a new tag that's a noun like fragment, page, document, subdoc or something.
Surely that's no less markup than svg, img, script, video, iframe, and what not.
int_19h
It stands for "markup language", and was inherited from SGML, which had includes. Strictly speaking, so did early HTML (since it was just an SGML subset), it's just that browsers didn't bother implementing it, for the most part. So it's not that it didn't evolve, but rather it devolved.
Nor is this something unique to SGML. XML is also a "markup language", yet XInclude is a thing.
cantSpellSober
That's why I joked about flamebait, it's hypertext though, aren't anchors essentially a goToURL() click handler in some ways? Template partials seem like a basic part of this system.
> considered to be server-side
Good point! Wouldn't fetching a template partial happen the same way (like fetching an image?)
mattl
> What's the ML in HTML stand for?
I always assumed it stood for my initials.
assimpleaspossi
Agree with what you said, however, HTML is a document description language and not a presentation format. CSS is for presentation (assuming you meant styling).
PaulDavisThe1st
They didn't mean styling.
HTML is a markup language that identifies the functional role of bits of text. In that sense, it is there to provide information about how to present the text, and is thus a presentation format.
It is also a document description language, because almost all document description languages are also a presentation format.
c-smile
> "Includes" functionality is considered to be server-side
Exactly! Include makes perfect sense on server-side.
But client-side include means that the client should be able to modify original DOM at unknown moment of time. Options are
1. at HTML parse time (before even DOM is generated). This requires synchronous request to server for the inclusion. Not desirable.
2. after DOM creation: <include src=""> (or whatever) needs to appear in the DOM, chunk loaded asynchronously and then the <include> DOM element(sic!) needs to be replaced(or how?) by external fragment. This disables any existing DOM structure validation mechanism.
Having said that...
I've implemented <include> in my Sciter engine using strategy #1. It works there as HTML in Sciter usually comes from local app resources / file system where price of issuing additional "get chunk" request is negligible.
amadeuspagel
This argument applies just as much to CSS and JS. Why do they include "includes" when you can just bundle on the server?
adregan
For caching and sharing resources across the whole site, I suppose.
john_the_writer
But that would apply to <header> and <footer> and <nav> too. We could cache them.
lelanthran
> As the article says, the problem is a solved one.
It's "solved" only in the sense that you need to use a programming language on the server to "solve" it. If all you are doing is static pages, it's most definitely not solved.
NorwegianDude
Then you just pre-build the page before publishing it. It's way cheaper as you do the work once, instead of every client being much slower because they have to do additional requests.
lelanthran
> Then you just pre-build the page before publishing it.
That's "using a programming language to solve the problem", isn't it?
> It's way cheaper as you do the work once, instead of every client being much slower because they have to do additional requests.
What work do client-side includes have to do other than fetching the page (which will get cached anyway)? It's less work to have a `<include-remote ...>` builtin than even a simple Makefile on the server.
mikeg8
An additional requests for html isn’t slow, and now I have to have a whole “build” process for something that is basically static. Not ideal
DemocracyFTW2
hearing someone assert that
> the problem is a solved one
is a sure-fire way to know that a problem is not solved
socalgal2
There are all kind of issues with HTML include as others have pointed out
If main.html includes child/include1.html and child/include1.html has a link src="include2.html" then when the user clicks the link where does it go? If it goes to "include2.html", which by the name was meant to be included, then that page is going to be missing everything else. If it goes to main.html, how does it specify this time, use include2.html, not include1.html?
You could do the opposite, you can have article1.html, article2.html, article3.html etc, each include header.html, footer.html, navi.html. Ok, that works, but now you've make it so making a global change to the structure of your articles requires editing all articles. In other words, if you want to add comments.html to every article you have to edit all articles and you're back to wanting to generate pages from articles based on some template at which point you don't need the browser to support include.
I also suspect there would be other issues, like the header wants to know the title, or the footer wants a next/prev link, which now require some way to communicate this info between includes and you're basically back to generate the pages and include not being a solution
I think if you work though the issues you'll find an HTML include would be practically useless for most use cases.
int_19h
These are all solvable issues with fairly obvious solutions. For example:
> If main.html includes child/include1.html and child/include1.html has a link src="include2.html" then when the user clicks the link where does it go? If it goes to "include2.html", which by the name was meant to be included, then that page is going to be missing everything else. If it goes to main.html, how does it specify this time, use include2.html, not include1.html?
There are two distinct use cases here: snippet reuse and embeddable self-contained islands. But the latter is already handled by iframes (the behavior being your latter case). So we only need to do the former.
socalgal2
> These are all solvable issues with fairly obvious solutions.
No, they are a can of worms and decades of arguments and incompatibilities and versioning
> But the latter is already handled by iframes
iframes don't handle this case because the page can not adjust to the iframe's content. There have been proposals to fix this but they always run into issues.
https://github.com/domenic/cooperatively-sized-iframes/issue...
john_the_writer
The include logic of include2.html missing everything else would also apply to all other includes.
If a user clicked a link with src="include.css" then it'll be rubbish.
It would be good for static data.. images, css, and static html content.
null
uallo
There is an open issue about this at WHATWG (also mentioned in the comment section of the blog post):
Client side include feature for HTML
austin-cheney
So, HTML did have includes and they fell out of favor.
The actual term include is an XML feature and it’s that feature the article is hoping for. HTML had an alternate approach that came into existence before XML. That approach was frames. Frames did much more than XML includes and so HTML never gained that feature. Frames lost favor due to misuse, security, accessibility, and variety of other concerns.
Linux-Fan
Unlike Framesets I think XML includes were never really supported in many browsers (or even any major browsers)?
I still like to use them occasionally but it incurs a "compilation" step to evaluate them prior to handing the result of this compilation to the users/browsers.
LegionMammal978
As it happens, the major browsers still can do XML 'includes' to some extent, since by some miracle they haven't torn out their support for XSLT 1.0. E.g. this outputs "FizzBuzz" on Firefox:
<!-- fizz.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="application/xslt+xml" href="style.xslt"?>
<fizz>Fizz<buzz/></fizz>
<!-- style.xslt -->
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="buzz">
<xsl:value-of select="document('buzz.xml')"/>
</xsl:template>
</xsl:stylesheet>
<!-- buzz.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<buzz>Buzz</buzz>
You can even use XSLT for HTML5 output, if you're careful. But YMMV with which XML processors will support stylesheets.ndriscoll
Yep, and this can be used to e.g. make a basically static site template and then do an include for `userdata.xml` to decorate your page with the logged in user's info (e.g. on HN, adding your username in the top right, highlighting your comments and showing the edit/delete buttons, etc.). You can for example include into a variable `<xsl:variable name="myinfo" select="document('userdata.xml')"/>` and then use it in xpath expressions like `$myinfo/user/@id`. Extremely simple, good for caching, lightweight, very high performance. Easy to fail gracefully to the logged out template. You basically get your data "API" for free since you're returning XML in your data model. I will never understand why it didn't take off.
XML includes are blocking because XSL support hasn't been updated for 25 years, but there's no reason why we couldn't have it async by now if resources were devoted to this instead of webusb etc.
Linux-Fan
Nice, didn't think of that approach and It should work very well for the purposes of static headers and footers.
simonjgreen
I know it’s not straight HTML, but SSI (server side includes) helped with this and back in the day made for some incredibly powerful caching solutions. You could write out chunks of your site statically and periodically refresh them in the server side, while benefitting from serving static content to your users. (This was in the pre varnish era, and before everyone was using memcached)
I personally used this to great success on a couple of Premier League football club websites around the mid 2000s.
thayne
One benefit of doing it on the client is the client can cache the result of an include. So for example, instead of having to download the content of a header and footer for every page, it is just downloaded once and re-usef for future pages
msie
It’s amazing how people vociferously argue against this. If it was implemented we would be arguing over something else.
Sesse__
How big are your headers and footers, really? If caching them is worth the extra complexity on the client plus all the pain of cache invalidation (and the two extra requests in the non-cached case).
youngtaff
I’m willing to bet the runtime overhead of assembly on the client is going to be larger than the download cost of the fragments being included server or edge side and cached
john_the_writer
If you measure download cost in time then sure.. If you measure download cost in terms of bytes downloaded, or server costs, then nope. The cost would be smaller to cache.
Kuyawa
This is the closest we can do today:
-- index.html
<html>
<body>
<script src="header.js"></script>
<main>
<h1>Hello includes</h1>
</main>
<script src="footer.js"></script>
</body>
</html>
-- header.js
document.currentScript.outerHTML = `
<header>
<h1>Header</h1>
</header>`
-- footer.js
document.currentScript.outerHTML = `
<footer>
<h1>Footer</h1>
</footer>`
Scripts will replace their tags with html producing a clean source, not pretty but it works on the clientKuyawa
Or this:
<body>
<include src="header.html"></include>
<main>
<h1>Hello includes</h1>
</main>
<include src="footer.html"></include>
</body>
<script>
(async function include(){
const objs = document.getElementsByTagName('include')
const tags = Array.from(objs)
for(tag of tags){
const src = tag.getAttribute('src')
const data = await fetch(src)
const html = await data.text()
tag.outerHTML = html
}
})()
</script>
* beware autoclosing tags won't workBjartr
You could even have a server wrap static html resources in that js if you request them a certain way, like
<script src="/include/footer.html">
For /footer.html
But then you probably might as well use server side includes
johnisgood
Pretty sure it is possible without JavaScript, too.
HTML was historically an application of SGML, and SGML could do includes. You could define a new "entity", and if you created a "system" entity, you could refer to it later and have it substituted in.
SGML is complex, so various efforts were made to simplify HTML, and that's one of the capabilities that was dropped along the way.