{"id":5713,"date":"2025-04-29T17:13:49","date_gmt":"2025-04-29T22:13:49","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=5713"},"modified":"2025-06-12T09:26:24","modified_gmt":"2025-06-12T14:26:24","slug":"seeking-an-answer-why-cant-html-alone-do-includes","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/seeking-an-answer-why-cant-html-alone-do-includes\/","title":{"rendered":"Seeking an Answer: Why can&#8217;t HTML alone do includes?"},"content":{"rendered":"\n<p>I&#8217;m obsessed with this basic web need. <\/p>\n\n\n\n<p>You&#8217;ve got three pages:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>index.html<\/li>\n\n\n\n<li>about.html<\/li>\n\n\n\n<li>contact.html<\/li>\n<\/ul>\n\n\n\n<p>You need to put <strong>the same<\/strong> header on all three pages. <\/p>\n\n\n\n<p>Our developer brains scream at us to ensure that we&#8217;re not copying the exact code three times, we&#8217;re creating the header <strong>once<em> <\/em><\/strong>then &#8220;including&#8221; it on the three (or a thousand) other pages.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"551\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-29-at-11.34.15%E2%80%AFAM.png?resize=1024%2C551&#038;ssl=1\" alt=\"\" class=\"wp-image-5722\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-29-at-11.34.15%E2%80%AFAM-scaled.png?resize=1024%2C551&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-29-at-11.34.15%E2%80%AFAM-scaled.png?resize=300%2C162&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-29-at-11.34.15%E2%80%AFAM-scaled.png?resize=768%2C414&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-29-at-11.34.15%E2%80%AFAM-scaled.png?resize=1536%2C827&amp;ssl=1 1536w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/04\/Screenshot-2025-04-29-at-11.34.15%E2%80%AFAM-scaled.png?resize=2048%2C1103&amp;ssl=1 2048w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">There are so many solutions to this problem<\/h2>\n\n\n\n<p>We don&#8217;t need to list them all here. I <a href=\"https:\/\/css-tricks.com\/the-simplest-ways-to-handle-html-includes\/\">documented <em>some<\/em> of them<\/a> one time, but there are many more. <\/p>\n\n\n\n<p>We&#8217;ve got JavaScript to go <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Fetch_API\/Using_Fetch\">fetch<\/a> the HTML and <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Element\/insertAdjacentElement\">insert<\/a> it. We&#8217;ve got <a href=\"https:\/\/httpd.apache.org\/docs\/2.4\/howto\/ssi.html\">old school web server directives<\/a>. Any <a href=\"https:\/\/jekyllrb.com\/docs\/includes\/\">static site generator<\/a> can do it. <a href=\"https:\/\/www.npmjs.com\/package\/gulp-include\">Task runners<\/a> can do it. <a href=\"https:\/\/handlebarsjs.com\/guide\/partials.html\">Templating languages<\/a> tend to have include functionality. Any <a href=\"https:\/\/www.php.net\/manual\/en\/function.include.php\">backend language<\/a> can generate HTML on the fly. I&#8217;ve seen several <a href=\"https:\/\/www.keithcirkel.co.uk\/i-html\/\">Web Components<\/a> purpose-built for this. We&#8217;ve got <code>&lt;iframe&gt;<\/code>, which technically is a pure HTML solution, but they are bad for overall performance, accessibility, and generally extremely awkward here, but we <a href=\"https:\/\/www.filamentgroup.com\/lab\/html-includes\/#another-demo%3A-including-another-html-file\">can extract them<\/a>. We can just not worry about includes at all and trust our code editors powerful find and replace tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">But none of the solutions is HTML<\/h2>\n\n\n\n<p>None of these are a straightforward HTML tag. None of these are just some HTML way of saying &#8220;go get this HTML and put it here&#8221;, like <code>&lt;img&gt;<\/code> is for &#8220;go get this image and put it here. <\/p>\n\n\n\n<p class=\"learn-more\"><a href=\"https:\/\/shoptalkshow.com\/668\/\">I had a discussion about all this<\/a> with Jake Archibald and Dave Rupert on ShopTalk Show that was very interesting and enlightening.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why?<\/h2>\n\n\n\n<p>No, really, <em>why?<\/em><\/p>\n\n\n\n<p>CSS can import CSS. JavaScript can import JavaScript. HTML cannot import HTML.<\/p>\n\n\n\n<p>I&#8217;m sure there are reasons. Normally, web standards and browsers are all about &#8220;paving the cowpaths&#8221;, that is, providing solutions around what developers are already doing. We were reaching for third-party JavaScript to help with dates, so <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Temporal\">the web platform stepped in<\/a>. We were using frameworks for page transitions, so <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/View_Transition_API\">the web platform stepped in<\/a>. We used libraries for positioning elements next to each other safely, so <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/CSS_anchor_positioning\">the web platform stepped in<\/a>. There are countless examples like this.<\/p>\n\n\n\n<p>I&#8217;d wager (counts fingers) pretty much <em>all<\/em> websites need this ability, and all of them reach for different additional non-web-standard tooling to get it done. That&#8217;s <em>weird<\/em>.<\/p>\n\n\n\n<p>So what are those reasons?<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Does it wreck the <a href=\"https:\/\/web.dev\/articles\/preload-scanner\">preload scanner<\/a>? As in, it could have very bad web performance issues?<\/li>\n\n\n\n<li>Would it have to be async and thus have issues with jerky\/shifty loading experiences?<\/li>\n\n\n\n<li>Does it introduce some kind of complexity that harms the purity of HTML or something?<\/li>\n\n\n\n<li>Is it the difficulty of handling nested includes? Circular includes?<\/li>\n\n\n\n<li>Is it pushback from web hosting that a feature like this would increase web requests dramatically?<\/li>\n\n\n\n<li>Would the restrictions be too strict to make it useful? Like for whatever reason it&#8217;s cool to load images and CSS and JS from other domains, but HTML would likely be restricted.<\/li>\n\n\n\n<li>Is there something problematic about the idea that I haven&#8217;t listed here?<\/li>\n\n\n\n<li>Is there actually no real desire for this and I&#8217;m just a weirdo thinking there is?<\/li>\n<\/ul>\n\n\n\n<p>If anyone has been a part of these discussions or knows exactly why this is, or you just have general thoughts, leave a comment!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Is there a perfectly clear and reasonable answer? Or could we get this someday?<\/p>\n","protected":false},"author":1,"featured_media":5726,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[31,331],"class_list":["post-5713","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-html","tag-includes"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/04\/includes.jpg?fit=1140%2C676&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=5713"}],"version-history":[{"count":10,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5713\/revisions"}],"predecessor-version":[{"id":6113,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/5713\/revisions\/6113"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/5726"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=5713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=5713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=5713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}