title: The Simplest Ways to Handle HTML Includes
url: https://css-tricks.com/the-simplest-ways-to-handle-html-includes/
hash_url: 6bfc6bd7bc1d9158aa7f6591123e7f4b
archive_date: 2024-02-19
og_image: https://css-tricks.com/wp-json/social-image-generator/v1/image/286228
description: It's extremely surprising to me that HTML has never had any way to include other HTML files within it. Nor does there seem to be anything on the horizon that
favicon: https://css-tricks.com/favicon.svg
language: en_US
          
<p>It’s extremely surprising to me that HTML has never had any way to include other HTML files within it. Nor does there seem to be anything on the horizon that addresses it. I’m talking about straight up <em>includes</em>, like taking a chunk of HTML and plopping it right into another. For example the use case for much of the entire internet, an included header and footer for all pages:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">...
&lt;body&gt;
   &lt;include src="./header.html"&gt;&lt;/include&gt;

   Content

   &lt;include src="./footer.html"&gt;&lt;/include&gt;
&lt;/body&gt;
...</code></pre>



<p>That’s not real, by the way. I just wish it was.</p>



<span id="more-286228"></span>



<p>People have been looking to other languages to solve this problem for them forever. It’s HTML preprocessing, in a sense. Long before we were preprocessing our CSS, we were using tools to manipulate our HTML. And we still are, because the idea of includes is useful on pretty much every website in the world.</p>


<h3 class="wp-block-heading" id="h-use-php"><a href="#aa-use-php" aria-hidden="true" class="aal_anchor" id="aa-use-php"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use PHP</h3>


<p>Can you use PHP instead?</p>



<pre rel="PHP" class="wp-block-csstricks-code-block language-javascript" data-line=""><code markup="tt">...
&lt;body&gt;
   &lt;?php include "./header.html" ?&gt;

   Content

   &lt;?php include "./footer.html" ?&gt;
&lt;/body&gt;
...</code></pre>



<p>This will perform the include at the server level, making the request for it happen at the file system level on the server, so it should be far quicker than a client-side solution.</p>


<h3 class="wp-block-heading" id="h-use-gulp"><a href="#aa-use-gulp" aria-hidden="true" class="aal_anchor" id="aa-use-gulp"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use Gulp</h3>


<p>What’s even faster than a server-side include? If the include is preprocessed before it’s even on the server. <a href="https://gulpjs.com/" rel="noopener">Gulp</a> has a variety of processors that can do this. One is <a href="https://www.npmjs.com/package/gulp-file-include" rel="noopener">gulp-file-include</a>.</p>



<p>That would look like this:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">...
&lt;body&gt;
   @@include('./header.html')

   Content

   @@include('./footer.html')
&lt;/body&gt;
...</code></pre>



<p>And you’d process it like:</p>



<pre rel="JavaScript" class="wp-block-csstricks-code-block language-javascript" data-line=""><code markup="tt">var fileinclude = require('gulp-file-include'),
  gulp = require('gulp');
 
gulp.task('fileinclude', function() {
  gulp.src(['index.html'])
    .pipe(fileinclude({
      prefix: '@@',
      basepath: '@file'
    }))
    .pipe(gulp.dest('./'));
});</code></pre>



<p>Looks like this particular plugin has fancy features where you can pass in variables to the includes, making it possible to make little data-driven components.</p>


<h3 class="wp-block-heading" id="h-use-grunt"><a href="#aa-use-grunt" aria-hidden="true" class="aal_anchor" id="aa-use-grunt"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use Grunt</h3>


<p>This is what the <a href="https://www.npmjs.com/package/grunt-bake" rel="noopener">grunt-bake</a> plugin does. You’d configure Grunt to process your HTML:</p>



<pre rel="JavaScript" class="wp-block-csstricks-code-block language-javascript" data-line=""><code markup="tt">grunt.initConfig({
    bake: {
        your_target: {
            files: {
                "dist/index.html": "app/index.html",
            }
        }
    }
});</code></pre>



<p>Then your HTML can use this special syntax for includes:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">...
&lt;body&gt;
   &lt;!--(bake header.html)--&gt;

   Content

   &lt;!--(bake footer.html)--&gt;
&lt;/body&gt;
...</code></pre>


<h3 class="wp-block-heading" id="h-use-handlebars"><a href="#aa-use-handlebars" aria-hidden="true" class="aal_anchor" id="aa-use-handlebars"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use Handlebars</h3>


<p>Handlebars <a href="https://handlebarsjs.com/partials.html" rel="noopener">has partials</a>.</p>



<p>You register them:</p>



<pre rel="JavaScript" class="wp-block-csstricks-code-block language-javascript" data-line=""><code markup="tt">Handlebars.registerPartial('myPartial', '{{name}}')</code></pre>



<p>Then use them:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">{{&gt; myPartial }}</code></pre>



<p>There is also fancy features of this that allow for evaluation and passing data. You’ll still need a processor to run it, probably something like <a href="https://www.npmjs.com/package/gulp-handlebars" rel="noopener">gulp-handlebars</a>.</p>



<p>Speaking of templating languages which make use of curly braces… Mustache <a href="https://github.com/janl/mustache.js#include-templates" rel="noopener">has them, too</a>.</p>


<h3 class="wp-block-heading" id="h-use-pug"><a href="#aa-use-pug" aria-hidden="true" class="aal_anchor" id="aa-use-pug"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use Pug</h3>


<p><a href="https://pugjs.org/" rel="noopener">Pug</a> is an HTML preprocessor that has a whole new syntax for HTML that is a bit more terse. <a href="https://pugjs.org/language/includes.html" rel="noopener">It’s got includes though</a>.</p>



<pre rel="Pug" class="wp-block-csstricks-code-block language-none" data-line=""><code markup="tt">...
body
   include ./header.html"

   p Content

   include ./footer.html"

   ...</code></pre>



<p>Then you run it with something like <a href="https://www.npmjs.com/package/gulp-pug" rel="noopener">gulp-pug</a>.</p>


<h3 class="wp-block-heading" id="h-use-nunjucks"><a href="#aa-use-nunjucks" aria-hidden="true" class="aal_anchor" id="aa-use-nunjucks"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use Nunjucks</h3>


<p><a href="https://css-tricks.com/killer-features-of-nunjucks/">I love me some Nunjucks!</a> <a href="https://mozilla.github.io/nunjucks/" rel="noopener">Nunjucks</a> has <a href="https://mozilla.github.io/nunjucks/templating.html#include" rel="noopener">includes</a>. You’d do it like this:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">...
&lt;body&gt;
   {% include "./header.html" %}

   Content

   {% include "./footer.html" %}
&lt;/body&gt;
...</code></pre>



<p>If you put that in a file called <code>index.njk</code>, you could process it with a simple Node script into index.html like this:</p>



<pre rel="JavaScript" class="wp-block-csstricks-code-block language-javascript" data-line=""><code markup="tt">const nunjucks = require("nunjucks");
const fs = require("fs");

fs.writeFile("index.html", nunjucks.render("index.njk"), function(err, data) {
  if (err) console.log(err);
  console.log("Compiled the Nunjucks, captain.");
});</code></pre>



<p>Or process it with something like <a href="https://www.npmjs.com/package/gulp-nunjucks" rel="noopener">gulp-nunjucks</a>.</p>



<p>11ty has <a href="https://www.11ty.io/docs/languages/nunjucks/" rel="noopener">Nunjucks built-in</a>, along with many of the other mentioned so far. Might be good for you if you’re actually building a little site.</p>


<h3 class="wp-block-heading" id="h-use-ajax"><a href="#aa-use-ajax" aria-hidden="true" class="aal_anchor" id="aa-use-ajax"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use Ajax</h3>


<p>Say you had…</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">&lt;body&gt;
  
  &lt;header&gt;&lt;/header&gt;
  
  Content.
  
  &lt;footer&gt;&lt;/footer&gt;

&lt;/body&gt;</code></pre>



<p>You could fetch the contents for the header and footer from respective files and dump the contents in.</p>



<pre rel="JavaScript" class="wp-block-csstricks-code-block language-javascript" data-line=""><code markup="tt">fetch("./header.html")
  .then(response =&gt; {
    return response.text()
  })
  .then(data =&gt; {
    document.querySelector("header").innerHTML = data;
  });

fetch("./footer.html")
  .then(response =&gt; {
    return response.text()
  })
  .then(data =&gt; {
    document.querySelector("footer").innerHTML = data;
  });</code></pre>



<p>Speaking of JavaScript… If you’re building your site using a JavaScript framework of just about any kind, building through components is kind of the main deal there and breaking parts you want to include in other files should be no problem. Some kind of <code>import Header from "./header.js";</code> and <code>&lt;Header /&gt;</code> is the territory you’d be in in React land.</p>


<h3 class="wp-block-heading" id="h-use-iframes"><a href="#aa-use-iframes" aria-hidden="true" class="aal_anchor" id="aa-use-iframes"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use iframes</h3>


<p>You could do this:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">&lt;body&gt;
  
  &lt;iframe src="./header.html"&gt;&lt;/iframe&gt;
  
  Content.
  
  &lt;iframe src="./footer.html"&gt;&lt;/iframe&gt;
  
&lt;/body&gt;</code></pre>



<p>But the content in those iframes does not share the same DOM, so it’s a bit weird, not to mention slow and awkward to style (since iframes don’t know the heights of their contents).</p>



<p><a href="https://www.filamentgroup.com/lab/html-includes/" rel="noopener">Scott Jehl documented a cool idea</a> though: You can have the iframe inject the content of itself onto the parent page then remove itself.</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">&lt;body&gt;
  
  &lt;iframe src="header.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"&gt;&lt;/iframe&gt;
  
  Content.
  
  &lt;iframe src="footer.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"&gt;&lt;/iframe&gt;
  
&lt;/body&gt;</code></pre>



<p>Kolya Korruptis wrote in with this adaptation which will include more than the first child of the body in case your HTML file has that:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">&lt;iframe src="included.html" onload="this.insertAdjacentHTML('afterend', (this.contentDocument.body||this.contentDocument).innerHTML);this.remove()"&gt;&lt;/iframe&gt;</code></pre>


<h3 class="wp-block-heading" id="use-jekyll"><a href="#aa-use-jekyll" aria-hidden="true" class="aal_anchor" id="aa-use-jekyll"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Use Jekyll</h3>


<p><a href="https://jekyllrb.com/" rel="noopener">Jekyll</a> is a Ruby-based static site generator with <a href="https://jekyllrb.com/docs/includes/" rel="noopener">includes</a>. You keep your includes in the <code>/_includes/</code> folder, then:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">&lt;body&gt;
  {% include header.html %}
  
  Content.

  {% include footer.html %}
&lt;/body&gt;</code></pre>



<p>Jekyll is a big one, so I’m calling it out here, but there are <a href="https://www.staticgen.com/" rel="noopener">a ton of static site generators</a> and I’d wager any of them can do includes.</p>


<h3 class="wp-block-heading" id="use-sergey"><a href="#aa-use-sergey" aria-hidden="true" class="aal_anchor" id="aa-use-sergey"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://css-tricks.com/the-simplest-ways-to-handle-html-includes/#use-sergey"></a>Use Sergey</h3>


<p>OK, I’ll call out one more SSG because it’s new and super focused. <a href="https://sergey.cool/" rel="noopener">Sergey</a> has a web components style format:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">&lt;body&gt;
  &lt;sergey-import src="header" /&gt;

  Content.

  &lt;sergey-import src="footer" /&gt;
&lt;/body&gt;</code></pre>



<p>You’d name the files <code>header.html</code> and <code>footer.html</code> and put them in <code>/includes/</code> and then it’ll make a build with the includes processed when you run the npm script it has you do.</p>


<h3 class="wp-block-heading" id="use-apache-ssi"><a href="#aa-use-apache-ssi" aria-hidden="true" class="aal_anchor" id="aa-use-apache-ssi"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://css-tricks.com/the-simplest-ways-to-handle-html-includes/#use-apache-ssi"></a>Use Apache SSI</h3>


<p>Apache, a super duper common web server, can <a href="https://httpd.apache.org/docs/2.4/mod/mod_include.html" rel="noopener">do includes</a>. You do it like this:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">&lt;body&gt;
		
  &lt;!--#include file="./header.html" --&gt;
  
  Content
  
  &lt;!--#include file="./footer.html" --&gt;
  
&lt;/body&gt;</code></pre>



<p>But you need the right Apache configuration to allow stuff. I tried my best to get a working demo going but didn’t have much luck.</p>



<p>I tried using <code>.htaccess</code> within a folder on an Apache server and flipping on what I thought was the right stuff:</p>



<pre rel="HTAccess" class="wp-block-csstricks-code-block language-none" data-line=""><code markup="tt">Options +Includes

AddType text/html .html
AddOutputFilter INCLUDES .html</code></pre>



<p>I’m sure there is some way to get it working though, and if you do, it’s kinda neat that it needs zero other dependencies.</p>


<h3 class="wp-block-heading" id="use-codekit"><a href="#aa-use-codekit" aria-hidden="true" class="aal_anchor" id="aa-use-codekit"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://css-tricks.com/the-simplest-ways-to-handle-html-includes/#use-codekit"></a>Use CodeKit</h3>


<p>Mac only, but CodeKit has <a href="https://codekitapp.com/help/kit/" rel="noopener">a special language called Kit</a> it processes where 90% of the point of it is HTML includes. It uses special HTML comments:</p>



<pre rel="HTML" class="wp-block-csstricks-code-block language-markup" data-line=""><code markup="tt">...
&lt;body&gt;
   &lt;!-- @import "./header.html" --&gt;

   Content

   &lt;!-- @import "./footer.html" --&gt;
&lt;/body&gt;
...</code></pre>


<h3 class="wp-block-heading" id="use-dreamweaver"><a href="#aa-use-dreamweaver" aria-hidden="true" class="aal_anchor" id="aa-use-dreamweaver"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://css-tricks.com/the-simplest-ways-to-handle-html-includes/#use-dreamweaver"></a>Use Dreamweaver</h3>


<p>Lol jk. But it <a href="https://helpx.adobe.com/dreamweaver/using/server-side-includes.html" rel="noopener">really is a thing</a>. <a href="http://shop.pixelmill.com/support/al0/kb101502.htm" rel="noopener">DWTs</a>, baby.</p>


<h3 class="wp-block-heading" id="holy-crap"><a href="#aa-holy-crap" aria-hidden="true" class="aal_anchor" id="aa-holy-crap"><svg aria-hidden="true" class="aal_svg" version="1.1" viewbox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><a href="https://css-tricks.com/the-simplest-ways-to-handle-html-includes/#holy-crap"></a>Holy Crap</h3>


<p>That’s a lot of ways, isn’t it?</p>



<p>Like I said at the top, it’s very surprising to me that HTML itself hasn’t addressed this directly. Not that I think it would be a great idea for performance to have <code>&lt;include&gt;</code> statements that trigger network requests all over our code, but it seems in-line with the platform. Using ES6 imports directly without bundling isn’t a great idea always either, but we have them. <code>@import</code>ing CSS within CSS isn’t a great idea always, but we have it. If the platform had a native syntax, perhaps other tooling would key off that, much like JavaScript bundlers support the ES6 import format.</p>
