[HN Gopher] Why can't HTML alone do includes?
___________________________________________________________________
Why can't HTML alone do includes?
Author : susam
Score : 193 points
Date : 2025-05-03 12:50 UTC (10 hours ago)
(HTM) web link (frontendmasters.com)
(TXT) w3m dump (frontendmasters.com)
| axelfontaine wrote:
| Iframes, while not perfect, are pretty close though...
| lelandfe wrote:
| Making iframes be the right size is super awkward. I might
| actually use them more if they were easy to get responsive.
|
| This post does link to a technique (new to me) to extract
| iframe contents: <iframe src="/example.html"
| onload="this.before((this.contentDocument.body||this.contentDoc
| ument).children[0]);this.remove()"></iframe>
| dleeftink wrote:
| I've come across this technique here [0] to try it on
| <object> elements, but sizing is even more difficult there.
|
| [0]: https://www.filamentgroup.com/lab/html-includes/
| cratermoon wrote:
| Are we solving the information-centric transclusion problem,
| or the design-centric asset reuse problem? An iframe is fine
| for the former but is not geared towards design and layout
| solutions.
| lelandfe wrote:
| It kinda sucks for both! Dropping in a box of text that
| flatly does not resize to fit its contents does not fit the
| definition of "fine" for me, here.
|
| You can do some really silly maneuvers with
| `window.postMessage` to communicate an expected size
| between the parent and frame on resize, but that's
| expensive and fiddly.
| rendaw wrote:
| Interaction between elements in different iframes is very
| restricted.
| danans wrote:
| IIRC, you can communicate entire JSON objects between an
| iframe and it's host frame with PostMessage.
|
| The host can then act as a server for the iframe client, even
| updating it's state or DOM in response to a message from the
| iframe.
| webstrand wrote:
| Iframes fundamentally encapsulate html documents, not
| fragments.
| evrimoztamur wrote:
| If you want to include HTML sandboxes, we have iframes. If you
| want it served from the server, it's just text. Putting text A
| inside text B is a solved problem.
| zamadatix wrote:
| The article references both of these methods with explanations
| of why they don't feel they answer the question posed.
| esperent wrote:
| > Putting text A inside text B is a solved problem.
|
| Yes, but in regards to HTML it hasn't been solved in a standard
| way, it's been solved in hundreds, if not thousands of non
| standard ways. The point of the article is that having one
| standard way wlcould reduce a lot of complexity from the
| ecosystem, as ES6 imports did.
| bdcravens wrote:
| The simplest answer is that HTML wasn't designed as a
| presentation language, but a hypertext document language. CSS and
| Javascripts were add-ons after the fact. Images weren't even in
| the first version. Once usage of the web grew beyond the initial
| vision, solutions like server-side includes and server-side
| languages that rendered HTML were sufficient.
| skydhash wrote:
| I think the best examples of HTML in that regard is HTML-
| rendered info pages[0], for Emacs and its ecosystem. Then you
| have the same content presented in HTML [1]. Templates were
| enough in the first case. Includes are better in the second
| case due to common assets external to the content.
|
| [0]:
| https://www.gnu.org/software/emacs/manual/html_node/emacs/in...
|
| [1]: https://emacsdocs.org/docs/emacs/The-Emacs-Editor
| nico wrote:
| FTA
|
| > We've got <iframe>, which technically is a pure HTML solution,
| but
|
| And then on the following paragraph..
|
| > But none of the solutions is HTML
|
| > None of these are a straightforward HTML tag
|
| Not sure what the point is. Maybe just complaining
| pjc50 wrote:
| Iframe is stuck in a rectangular box. It's not really suitable
| for things like site wide headers, footers and menus.
| vlovich123 wrote:
| While I get your point, headers and footers and menus tend to
| all live within rectangular boxes.
| zamadatix wrote:
| Headers and their menus are often problematic for this
| approach, unless they are 100% static (e.g. HN would work
| but Reddit and Google wouldn't since they both put things
| in their header which can expand over the content). I.e.
| you can make it transparent but that doesn't solve eating
| the interactions. The code needed to work around that is
| more than just using JS to do the imports.
| teg4n_ wrote:
| Do a drop down list of links on a header in an iframe
| jefftk wrote:
| Headers and footers, yes. Menus generally need to expand
| when you interact with them, especially on mobile.
| ComplexSystems wrote:
| <iframe> is different from what the author is asking for, it
| has its own DOM and etc. He wants something like an SSI but
| client side. He explains some of the problems right after the
| part you cut off above
|
| "We've got <iframe>, which technically is a pure HTML solution,
| but they are bad for overall performance, accessibility, and
| generally extremely awkward here"
| tln wrote:
| There used to be a thing for this
|
| https://caniuse.com/imports
| tehbeard wrote:
| No HTML imports was an idea of using the HTML document format
| to encapsulate the 3 distinct data types needed for custom
| elements:
|
| - JS for functionality via the custom elements API - HTML for
| layout via <template> tags. - CSS for aesthetics via <style>
| tags.
|
| Not for just quickly and simply inserting the contents of
| header.html at a specific location in the DOM.
| HeavyStorm wrote:
| Says "superseded by ES modules". Not really the same thing,
| right?
| hilti wrote:
| Have you ever heard of Server Side Includes?
|
| https://en.wikipedia.org/wiki/Server_Side_Includes
| rendaw wrote:
| That's mentioned in TFA under "old school web server
| directives".
| rsolva wrote:
| After researching this very topic earlier; SSI is the most
| pragmatic solution. Check out Caddy's Template Language (based
| on Go), it is quite capable and quite similar to building
| themes in Hugo. Just much more bare bones.
|
| I have built several sites with pure HTML+CSS, sprinkled with
| some light SSI with Caddy, and it is rock solid and very
| performant!
| DJHenk wrote:
| My guess: no-one needs it.
|
| Originally, iframe were the solution, like the posts mentions. By
| the time iframes became unfashionable, nobody was writing HTML
| with their bare hands anymore. Since then, people use a myriad of
| other tools and, as also mentioned, they all have a way to fix
| this.
|
| So the only group who would benefit from a better iframe is the
| group of people who don't use any tools and write their HTML with
| their bare hands in 2025. That is an astonishing small group.
| Even if you use a script to convert markdown files to blog posts,
| you already fall outside of it.
|
| No-one needs it, so the iframe does not get reinvented.
| micromacrofoot wrote:
| what if it could be a larger group though? modern css has been
| advancing rather rapidly... I don't even need a preprocessing
| library any more... I've got nested rules, variables, even some
| light data handling... why not start beefing up html too? we've
| got some new features but includes would be killer
| Svip wrote:
| No, originally frameset[0] and frame[1] were the solution to
| this problem. I remember building a website in the late 1990s
| with frameset. iframe came later, and basically allowed you to
| do frames without the frameset. Anyway, frameset is also the
| reason every browser's user agent starts with "Mozilla".
|
| [0] https://developer.mozilla.org/en-
| US/docs/Web/HTML/Reference/...
|
| [1] https://developer.mozilla.org/en-
| US/docs/Web/HTML/Reference/...
| dimal wrote:
| 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.
| econ wrote:
| 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 wrote:
| 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 wrote:
| I couldn't agree more.
|
| <div src="foo.txt"></div>
| wizzwizz4 wrote:
| https://www.w3.org/TR/xhtml2/introduction.html
|
| > XHTML 2 takes a completely different approach, by
| taking the premise that all images have a long
| description and treating the image and the text as
| equivalents. In XHTML 2 _any_ element may have a @src
| attribute, which specifies a resource (such as an image)
| to load instead of the element.
| atoav wrote:
| 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.
| luotuoshangdui wrote:
| HTML is a markup language, not a programming language. It's
| like asking why Markdown can't handle includes. Some Markdown
| editors support them (just like some server-side tools do for
| HTML), but not all.
| paulddraper wrote:
| That's the Hyper part of HTML, and what makes it special.
|
| It's made to pull in external resources (as opposed to other
| document formats like PDF).
|
| Scripts, stylesheets, images, objects, favicons, etc. HTML is
| thematically similar.
| ummonk wrote:
| No, HTML is fundamentally different because (for a static
| site without any JS dom manipulation) it has all the
| semantic content, while stylesheets, images, objects, etc.
| are just about presentation.
| Aloisius wrote:
| Iframes exist.
| dimal wrote:
| This isn't programming. It's transclusion[0]. Essentially,
| iframes and images are already forms of transclusion, so why
| not transclude html and have the iframe expand to fit the
| content?
|
| As I wrote that, I realized there could be cumulative layout
| shift, so that's an argument against. To avoid that, the
| browser would have to download all transcluded content before
| rendering. In the past, this would have been a dealbreaker,
| but maybe it's more feasible now with http multiplexing.
|
| [0] https://en.m.wikipedia.org/wiki/Transclusion#Client-
| side_HTM...
| PoignardAzur wrote:
| With Early Hints (HTTP code 103), it seems especially
| feasible. You can start downloading the included content
| one round-trip after the first byte is sent.
| franga2000 wrote:
| Including another document is much closer to a markup
| operation than a programming operation. We already include
| styles, scripts, images, videos, fonts...why not document
| fragments?
|
| Markdown can't do most of those, so it makes more sense why
| it doesn't have includes, but I'd still argue it definitely
| should. I generally dislike LaTeX, but about the only thing I
| liked about it when writing my thesis was that I could have
| each chapter in its own file and just include all of them in
| the main file.
| crazygringo wrote:
| I think this is the most likely answer.
|
| I'm not defending it, because when I started web development
| this was one of the first problems I ran into as well -- how
| the heck do you include a common header.
|
| But the original concept of HTML was standalone documents,
| not websites with reusable components like headers and
| footers and navbars.
|
| That being said, I still don't understand why then the frames
| monstrosity was invented, rather than a basic include. To
| save on bandwidth or something?
| mattl wrote:
| A lot of early HTML was about taking the output of a
| different system such as a mainframe and putting that
| output into HTML.
|
| Lots of gateways between systems.
| giantrobot wrote:
| Frames were widely abused by early web apps to do dynamic
| interfaces before XHR was invented/widely supported. The
| "app" had a bunch of sub-frames with all the links and
| forms carefully pointing to different frames in the
| frameset.
|
| A link in a sidebar frame would open a link in the "editor"
| frame which loaded a page with a normal HTML form.
| Submitting the form reloaded it in that same frame. Often
| the form would have multiple submit buttons, one to save
| edits in progress and another to submit the completed form
| and move to the next step. The current app state was
| maintained server side and validation was often handled
| there save for some basic formatting client side JavaScript
| could handle.
|
| This setup allowed even the most primitive frame-supporting
| browsers to use CRUD web apps. IIRC early web frameworks
| like WebObjects leaned into that model of web app.
| crazygringo wrote:
| Oh my goodness, yes you're right, I'd forgotten
| _entirely_ about those.
|
| They were horrible -- you'd hit the back button and only
| one of the frames would go back and then the app would be
| in an inconsistent state... it was a mess!
| lenkite wrote:
| Well, asciidoc - a markup language supports includes, so the
| "markup languages" analogy doesn't hold.
|
| https://docs.asciidoctor.org/asciidoc/latest/directives/incl.
| ..
| actinium226 wrote:
| Markdown doesn't have this common HTML pattern of wanting to
| include a header/footer in all pages of a site.
| api wrote:
| The web seems like it was deliberately designed to make any
| form of composability impossible. It's one of the worst things
| about it as a platform.
|
| I'm sure some purist argument has driven this somewhere.
| giantrobot wrote:
| I look back longingly at the promise of XML services in the
| early days of Web 2.0. Before the term just meant JavaScript
| everywhere.
|
| All sorts of data could be linked together to display or
| remix by user agents.
| codr7 wrote:
| The optimal solution would be using a template engine to
| generate static documents.
| keeganpoppen wrote:
| macros!
| JadeNB wrote:
| > 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 wrote:
| 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.
| unilynx wrote:
| > Iframes don't expand to fit content
|
| Actually, that was part of the original plan -
| https://caniuse.com/iframe-seamless
| omneity wrote:
| 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.
| fooker wrote:
| > Why not have a simple client side method for this?
|
| Like writing a line of js?
| matchagaucho wrote:
| 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)
| jasoncartwright wrote:
| I made this to get around pages being cached at CDN level, but
| still needing to get live data...
|
| https://github.com/jasoncartwright/clientsideinclude
| Imustaskforhelp wrote:
| I think this is a genuinely good question that I was also
| wondering some time ago.
|
| And it is a genuinely good question!
|
| I think the answer of PD says feels the truest.
|
| JS/CSS with all its bureaucracy are nothing compared to HTML it
| seems. Maybe people don't find nothing wrong with Html, maybe if
| they do, they just reach out for js/css and try to fix html (ahem
| frontend frameworks).
|
| That being said, I have just regurgitated what PD says has said
| and I give him full credit of that but I am also genuinely
| confused as to why I have heard that JS / CSS are bureaucratic (I
| remember that there was this fireship video of types being added
| in JS and I think I had watched it atleast 1 year ago (can be
| wrong) but I haven't heard anything for it and I see a lot of JS
| proposals just stuck from my observation
|
| And yet HTML is such level of bureaucratic that the answer to why
| HTML doesn't have a feature is because of its bureaucracy. Maybe
| someone can explain the history of it and why?
| SJC_Hacker wrote:
| Initially HTML was less about the presentation layer and more
| about the "document" concept. Documents should be self-contained,
| outside of references to other documents.
| skydhash wrote:
| I still think this is the best web. Either you are a collection
| of interlinked documents and forms (manual pages, wiki,...), or
| you are a full application (figma, gmail, google docs). But a
| lot of sites are trying to be both. And somes are trying to be
| one while they are the other type.
| mmastrac wrote:
| Do remote entity references still work in XHTML? XML had its
| issues but did have a decent toolbox of powerful if not insecure
| primitives.
| rs186 wrote:
| I guess for the similar reason that Markdown does not have any
| "include" ability -- it is a feature not useful enough yet with
| too many issues to deal with. They are really intended to be used
| as "single" documents.
| uallo wrote:
| 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
|
| https://github.com/whatwg/html/issues/2791
| bambax wrote:
| > _We've got <iframe>, which technically is a pure HTML solution,
| but they are bad for overall performance, accessibility, and
| generally extremely awkward here_
|
| What does this mean? This is a pure HTML solution, not just
| "technically" but in reality. (And before iframe there were
| frames and frameset). Just because the author doesn't like them
| don't make them non-existent.
| ajkjk wrote:
| No way. You can't make a decent single web page by iframing a
| bunch of components together.
| jadamson wrote:
| What do you mean what does it mean?
|
| An iframe is a window into another webpage, and is bounded as
| such both visually and in terms of DOM interfaces. A simple
| example would be that an iframe header can't have drop-down
| menus that overlap content from the page hosting it.
|
| They are categorically not the same DX/UX as SSI et al. and
| it's absolutely bizarre to me that there's so many comments
| making this complaint.
| silvestrov wrote:
| The real problem with iframes is that their size is set by the
| parent document only.
|
| They would be a lot more useful if we could write e.g. <iframe
| src=abc.html height=auto width=100> so the height of the iframe
| element is set by the abc.html document instead of the parent
| document.
| baggy_trough wrote:
| You can achieve that with js in the parent document.
| teg4n_ wrote:
| You can achieve everything with JS in the parent document,
| it doesn't mean it should be required or even recommended
| jefftk wrote:
| You could do this with js in the child document, if its
| important to keep js out of the parent.
| rchaud wrote:
| "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.
| assimpleaspossi wrote:
| 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 wrote:
| 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.
| cantSpellSober wrote:
| 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 wrote:
| 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?
| cantSpellSober wrote:
| That's why I joked about flamebait, it's _hyper_ text
| 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?)
| Aloisius wrote:
| 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.
| mattl wrote:
| > What's the ML in HTML stand for?
|
| I always assumed it stood for my initials.
| naasking wrote:
| > "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 wrote:
| 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.
| amadeuspagel wrote:
| This argument applies just as much to CSS and JS. Why do they
| include "includes" when you can just bundle on the server?
| adregan wrote:
| For caching and sharing resources across the whole site, I
| suppose.
| Linux-Fan wrote:
| 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 wrote:
| 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 wrote:
| 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 :)
| austin-cheney wrote:
| 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 wrote:
| 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 wrote:
| 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 wrote:
| 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.
| LegionMammal978 wrote:
| > if resources were devoted to this
|
| You'd better not jinx it: XSL support seems like just the
| sort of thing browser devs would want to tear out in the
| name of reducing attack surface. They already dislike the
| better-known SVG and never add any new features to it. I
| often worry that the status quo persists only because
| they haven't really thought about it in the last 20
| years.
| o11c wrote:
| Fortunately, XSLT is used by far too many high-importance
| websites (e.g. official government legal sites) for
| removing it to be a real threat.
| mr_toad wrote:
| > I will never understand why it didn't take off.
|
| I've used XSLT in anger - I used it to build Excel
| worksheets (in XML format) using libXSLT. I found it very
| verbose and hard to read. And Xpath is pretty torturous.
|
| I wish I could have used Javascript. I wish Office
| objects were halfway as easy to compose as the DOM. I
| know a lot of people hate on Javascript and the DOM, but
| it's way easier to work with than the alternatives.
| Linux-Fan wrote:
| Nice, didn't think of that approach and It should work very
| well for the purposes of static headers and footers.
| johannes1234321 wrote:
| I would guess back in the days having extra requests was
| expensive, thus discouraged. Later there were attempts via
| xinclude, but by then PHP and similar took over or people
| tolerated frames.
| somethingsome wrote:
| I'm not an expert on this but IMO, from a language point of view,
| HTML is a markup language, it 'must' have no logic or processing.
| It is there to structure the information not to dynamically
| change it. Nor even to display it nicely.
|
| The logic is performed elsewhere. If you were to have includes
| directly in HTML, it means that browsers must implement logic for
| HTML. So it is not 'just' a parser anymore.
|
| Imagine for example that I create an infinite loop of includes,
| who is responsible to limit me? How to ensure that all other
| browsers implement it in the same way?
|
| What happens if I perform an injection from another website? Then
| we start to have cors policy management to write. (iframes were
| bad for this)
|
| Now imagine using Javascript I inject an include somewhere,
| should the website reload in some way? So we have a dynamic DOM
| in HTML?
| naasking wrote:
| > from a language point of view, HTML is a markup language, it
| 'must' have no logic or processing.
|
| Client-side includes are not "processing". HTML already has
| frames and iframes which do this, just in a worse way, so we'd
| be better off.
| somethingsome wrote:
| I understand your point, but I still think it is bad from the
| point of view of language paradigms[1]. Iframes should have
| not been created in the first place.. You are changing the
| purpose of the language while it was not made for it.
|
| (yes in my view I interpret includes as a basic procedure)
|
| [1] http://www.info.ucl.ac.be/people/PVR/paradigmsDIAGRAMeng2
| 01....
| lenkite wrote:
| There is a very, very broad line in that "no logic or
| processing". HTML/CSS already do a lot of logic and processing.
| And many "markup languages" have include support. Like wikitext
| used in wikipedia and includes in Asciidoc.
| omoikane wrote:
| > an infinite loop of includes
|
| We can probably copy the specs for <frameset> and deal with it
| the same way:
|
| https://www.w3.org/TR/WD-frames-970331#:~:text=Infinite%20Re...
| Any frame that attempts to assign as its SRC a URL used by any
| of its ancestors is treated as if it has no SRC URL at all
| (basically a blank frame).
|
| > How to ensure that all other browsers implement it in the
| same way?
|
| Browsers that don't implement the specs will eventually break:
|
| https://bugzilla.mozilla.org/show_bug.cgi?id=8065
| Null-Set wrote:
| 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.
| bufferoverflow wrote:
| iframe is html
| esprehn wrote:
| We discussed this back when creating web components, but the
| focus quickly became about SPA applications instead of MPAs and
| the demand for features like this was low in that space.
|
| I wish I would have advocated more for it though. I think it
| would be pretty easy to add using a new attribute on <script>
| since the parser already pauses there, so making something like
| <script transclude={url}> would likely not be too difficult.
| prkl wrote:
| honestly, html can include css and javascript via link and style
| tags. there's no reason for it to not have an <include src="" />
| tag, and let the browser parsing it fetch the content to replace
| it.
| hyperhello wrote:
| I think it's because it would be so easy to make a recursive page
| that includes itself forever. So you have to have rules when it's
| okay, and that's more complex and opaque than just programming it
| yourself.
| _heimdall wrote:
| If I really need HTML includes for some reason, I'd reach for
| XSLT. I know its old, and barely maintained at best, but that was
| the layer intentionally added to add programming language
| features to the markup language that is HTML.
| mark_and_sweep wrote:
| I believe XSLT 1 is still working in all major browsers today.
| Here's a simple HTML 5 example with two pages sharing a header
| template:
| https://gist.github.com/MarkTiedemann/0e6d36c337159a3e6d5072...
| _heimdall wrote:
| My main gripe is a decade(s?) old Firefox bug related to
| rendering an HTML string to the DOM.
|
| That may be a fairly specific use case though, and largely it
| still works great today. I've done a few side projects with
| XSLT and web components for interactivity, worked great.
| mark_and_sweep wrote:
| What bug specifically?
| SvenL wrote:
| I think XSLT is still a reasonable technology in itself - the
| lack of updated implementations is the bad part. I think modern
| browsers only support 1.0 (?). At least most modern programming
| languages should have 3.0 support.
| _heimdall wrote:
| Firefox has a very old bug related to rendering an HTML
| string to the DOM without escaping it, that one has bit me a
| few times. Nothing a tiny inline script can't fix, but its
| frustrating to have such a basic feature fail.
|
| Debugging is also pretty painful, or I at least haven't found
| a good dev setup for it.
|
| That said, I'm happy to reach for XSLT when it makes sense.
| Its pretty amazing what can be done with such an old tech,
| for the core use case of props and templates to HTML you
| really don't need react.
| ludwik wrote:
| We used to have this in the form of a pair of HTML tags:
| <frameset> and <frame> (not to be confused with the totally
| separate <iframe>!). <frameset> provided the scaffolding with
| slots for multiple frames, letting you easily create a page made
| up entirely of subpages. It was once popular and, in many ways,
| worked quite neatly. It let you define static elements once
| entirely client-side (and without JS!), and reload only the
| necessary parts of the page - long before AJAX was a thing. You
| could even update multiple frames at once when needed.
|
| From what I remember, the main problem was that it broke URLs:
| you could only link to the initial state of the page, and
| navigating around the site wouldn't update the address bar - so
| deep linking wasn't possible (early JavaScript SPA frameworks had
| the same issue, BTW). Another related problem was that each
| subframe had to be a full HTML document, so they did have their
| own individual URLs. These would get indexed by search engines,
| and users could end up on isolated subframe documents without the
| surrounding context the site creator intended - like just the
| footer, or the article content without any navigation.
| throwup238 wrote:
| 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.
|
| [1] https://www.w3.org/TR/html-imports/
| riedel wrote:
| https://caniuse.com/imports says FF even had it as a config
| flag
| AtlasBarfed wrote:
| Frames essentially could do html import
| xg15 wrote:
| 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-...
| uallo wrote:
| 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 wrote:
| 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">.
| djoldman wrote:
| > Our developer brains scream at us to ensure that we're not
| copying the exact code three times, we're creating the header
| once then "including" it on the three (or a thousand) other
| pages.
|
| Interesting, my brain is not this way: I want to send a minimum
| number of files per link requested. I don't care if I include the
| same text because the web is generally slow and it's generally
| caused by a zillion files sent and a ton of JS.
| drob518 wrote:
| Seems like this would help with caching, too.
| Lammy wrote:
| 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...
| blorto wrote:
| I always wondered why it was called ILAYER. Ty
| typedef_struct wrote:
| You could start with something like this:
| customElements.define('html-import', class extends HTMLElement {
| connectedCallback() { const href =
| this.getAttribute('href') const fetch = new
| XMLHttpRequest() fetch.responseType = 'document'
| fetch.addEventListener('readystatechange', (function onfetch(e) {
| if (fetch.readyState !== XMLHttpRequest.DONE) return
| const document = fetch.response.querySelector('body') ??
| fetch.response this.replaceWith(document)
| }).bind(this)) fetch.open('GET', href)
| fetch.send() } })
| johnfn wrote:
| Well, that's not "HTML alone".
| 1718627440 wrote:
| This is just my own understanding, but doesn't a webpage consist
| of a bunch of nodes, which can be combined in any way. And an
| html document is supposed to be a complete set of nodes, so a
| combination of those won't be a single document anymore.
|
| Nodes can be addressed individually, but a document is the
| proportion for transmission containing also metadata. You can
| combined nodes as you like, but you can't really combined two
| already packed and annotated documents of nodes.
|
| So I would say it is more due a semantic meaning. I think there
| was also the idea of requesting arbitrary sets of nodes, but that
| was never developed and with the shift away from a semantic
| document, it didn't make sense anymore.
| gugagore wrote:
| I think the quickest way to say it is that there is only one
| head on a page, and every HTML file needs a head. So if you
| include one into the other, you either have two heads, or the
| inner document didn't have a head.
| mattlondon wrote:
| See DofumentFragment - sounds a lot like this:
| https://developer.mozilla.org/en-
| US/docs/Web/API/DocumentFra...
| econ wrote:
| They can just be html chunks. No need to make sense on their
| own.
|
| Maybe a single tag that points at an url to load if someone
| attempts to load the chunk directly.
| mr_toad wrote:
| > a webpage consist of a bunch of nodes, which can be combined
| in any way
|
| More or less, but manipulating the nodes requires JavaScript,
| which some people would like to avoid.
| sreekotay wrote:
| This has always worked for me. Pretty much the ask?
| https://gist.github.com/sreekotay/08f9dfcd7553abb8f1bb17375d...
| alecsm wrote:
| But you need a server for that to work.
| sreekotay wrote:
| you need a server for HTML to work, as practical matter. But
| yes. There IS a workaround to that too, if you're REALLY
| determined, but you have to format your HTML a giant JS
| comment block (lol really :))
|
| [edit: I'm sure there are still some file:// workflows for
| docs - and yes this doesn't address that]
| mattl wrote:
| You don't need a server for HTML to work, I can just hand
| you a USB stick/floppy disk/MO disk for your NeXT with HTML
| files on it.
| CamouflagedKiwi wrote:
| That's the first thing listed in the article? "Javascript to go
| fetch the HTML and insert it". What they're after is something
| that's _just_ HTML and not another language.
| sreekotay wrote:
| While you do need a server i think this is the functional
| equivalent? The fetch JS and insert outlined (linked to) in
| the article is async. This blocks execution like you'd expect
| an HTML include to do. It's WAY easier to reason about -
| which is why the initial ask, I think...
| tiku wrote:
| iFrames have a src and includes other html.. We used to make
| sites with it way back.
| jsdwarf wrote:
| I'd say in 80% of the cases a pure, static html include is not
| enough. In a menu include, you want to disable the link to the
| currently shown page or show a page specific breadcrumb. In a
| footer include, you may want a dynamic "last updated" timestamp
| or the current year in the copyright notice. As all these use
| cases required a server-side scripting language anyway, there was
| no push behind an html include.
| steren wrote:
| in the meantime, you can use <html-include>
| https://www.npmjs.com/package/html-include-element
| franze wrote:
| Now you can include HTML in HTML, see
| https://include.franzai.com/ - a quick Chrome Polyfill based on
| the discussion here. MIT License
|
| Github: https://github.com/franzenzenhofer/html-include-polyfill-
| ext...
|
| SHOW HN: https://news.ycombinator.com/item?id=43881815
| dinkblam wrote:
| we had no problem using <object> for headers and footers
| neuroelectron wrote:
| So glad I decided early in my career to not do webpages. Look how
| much discussion this minor feature has generated. I did make
| infra tools that outputted basic html, get post cgi type of
| stuff. What's funny is this stuff was deployed right before AWS
| was launched and a year later the on prem infra was sold and the
| warehouse services were moved to the cloud.
| kyledrake wrote:
| At least some of the blame here is the bias towards HTML being
| something that is dynamic code generated, as opposed to something
| that is statically handwritten by many people.
|
| There are features that would be good for the latter that have
| been removed. For example, if you need to embed HTML code
| examples, you can use the <xmp> tag, which makes it so you don't
| need to encode escapes. Sadly, the HTML5 spec is trying to
| obsolete the <xmp> tag even though it's the only way to make this
| work. All browsers seem to be supporting it anyways, but once it
| is removed you will always have to encode the examples.
|
| HTML spec developers should be more careful to consider people
| hand coding HTML when designing specifications, or at least
| decisions that will require JavaScript to accomplish something it
| probably shouldn't be needed for.
| TZubiri wrote:
| It's the other way around, HTML was designed to be hand
| written, and the feature set was defined at that stage. If it
| ended up being dynamically generated, that happened after the
| feature set was defined.
| kmoser wrote:
| SHTML used to be a thing back in the 1990s:
| https://en.wiktionary.org/wiki/SHTML
| Telemakhos wrote:
| Or, better, "Server Side Includes" (SSI):
| https://en.wikipedia.org/wiki/Server_Side_Includes
|
| SSI is still a thing: I use it on my personal website. It isn't
| really part of the HTML, though: it's a server-dependent
| extension to HTML. It's supported by Apache and nginx, but not
| by every server, so you have to have control over the server
| stack, not just access to the documents.
| TZubiri wrote:
| Because it's HyperText, the main idea is that you link to other
| content, so this is not a weird feature that is being asked for,
| it's just a different way of doing the whole raison d'etre of the
| tech. In fact the tag to link stuff is the <a> tag. It just so
| happens that it makes you load the other "page", instead of
| transcluding content, the idea is that you load it.
|
| It wouldn't make sense to transclude the article about the United
| States in the article about Wyoming (and in fact modern wikipedia
| shows a pop up bubble doing a partial transclusion, but would
| benefit in no way from basic html transclusion.)
|
| It's a simple idea. But of course modern HTML is not at all what
| HTML was designed to be, but that's the canonical answer.
|
| The elders of HTML would just tell you to make an <a> link to
| whatever you wanted to transclude instead. Be it a
| "footer/header/table of contents" or another encylcopdic article,
| or whatever. Because that's how HTML works, and not the way you
| suggest.
|
| Think of what would happen if it were the case, you would
| transclude page A, which transcludes page B, and so with page C,
| possibly recursively transcluding page B and so. You would
| transform the User Agent (browser) into a whole WWW crawler!
|
| It's because HTML is pass by reference, not pass by copy.
| Evidlo wrote:
| You can get JS-free, client-side include functionality if you're
| willing to wrap your HTML in XML. Here is a demo:
|
| https://github.com/Evidlo/xsl-website
| imiric wrote:
| That's interesting, thanks.
|
| How well supported is XSLT in modern browsers? What would be
| the drawbacks of using this approach for a modern website?
| miragecraft wrote:
| I too lamented the loss of HTML imports and ended up coming up
| with my own JavaScript library for it.
|
| https://miragecraft.com/blog/replacing-html-imports
|
| At the end of the day it's not something trivial to implement at
| the HTML spec/parser level.
|
| For relative links, how should the page doing the import handle
| them?
|
| Do nothing and let it break, convert to absolute links, or remap
| it as a new relative link?
|
| Should the include be done synchronously or asynchronously?
|
| The big benefit of traditional server side includes is that its
| synchronous, thus simplifying logic for in-page JavaScript, but
| all browsers are trying to eliminate synchronous calls for speed,
| it's hard to see them agreeing to add a new synchronous
| bottleneck.
|
| Should it be CORS restricted? If it is then it blocks offline use
| (file:// protocol) which really kills its utility.
|
| There are a lot of hurdles to it and it's hard to get people to
| agree on the exact implementation, it might be best to leave it
| to JavaScript libraries.
| dwheeler wrote:
| 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. <!DOCTYPE html example [
| <!ENTITY myheader SYSTEM "myheader.html"> ]> ....
| &myheader;
|
| SGML is complex, so various efforts were made to simplify HTML,
| and that's one of the capabilities that was dropped along the
| way.
| daveac wrote:
| I desperately want to back to crafting sites by hand and not
| reach for react/vue as a default. I do a lot of static and
| tempory sites that do very little
| chipsrafferty wrote:
| Use HTMX.
| rorylaitila wrote:
| I'm a full stack developer. I do server side rendering. I agree
| that this is a 'solved problem' for that case. However there are
| many times I don't want to run a server or a static site
| generator. I manage a lot of projects. I don't want more build
| steps than necessary. I just want to put some HTML on the net
| with some basic includes, without JavaScript. But currently I
| would go the web component route and accept the extra JS.
| dietsche wrote:
| I think the authors of htmx have the same questions :)
| simonjgreen wrote:
| 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 wrote:
| 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
| Sesse__ wrote:
| 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).
| WhyNotHugo wrote:
| HTML frames solved this problems just fine, but they were
| deprecated in favour of using AJAX to replace portions of the
| body as you navigate (e.g.: SPAs).
|
| I still feel like frames were great for their use case.
| Devasta wrote:
| Honest answer: because any serious efforts to improve HTML died
| 20 years ago, and the web as it's envisaged today is not an
| infinite library of the worlds knowledge but instead a JavaScript
| based and platform.
|
| Asking for things that the W3C had specced out in 2006 for XML
| tech is just not reasonable if it doesn't facilitate clicks.
| simultsop wrote:
| It's a pity, of all web resources advancements, js, css,
| runtimes, web engines. HTML was the most stagnant aspect of it,
| despite the "HTML5" effing hype. My guess is they did not want to
| empower HTML and threaten SSR's, or solutions. I believe the
| bigest concern of not making a step is the damned backward
| compatibility. Some just wont budge to move.
| dheera wrote:
| Seems everyone forgot HTML-SSI which worked something like this.
| Many servers and hosting websites of the 90s supported it.
| <!--#include virtual="header.html" --> Some content here
| <!--#include virtual="footer.html" -->
| paulryanrogers wrote:
| HTML does have frames and iframes, which can accomplish some of
| the same goals.
| mirkodrummer wrote:
| it is mentioned in the article indeed; it's an awful solution
| that is poor in performance and break the accessibility
| socalgal2 wrote:
| 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.
___________________________________________________________________
(page generated 2025-05-03 23:00 UTC)