include HTML code inside HTML pages using a custom tag load-html to load content dynamically

Features | Usage | API | Annotated source | License



See usage example folder or read below.

Start with your index.html

<!doctype html>
    <title>load-html usage example</title>
    <load-html src="helloWorld.html">Loading...</load-html>

Content inside <load-html> custom HTML tag is optional.

Create files helloWorld.html and linkToHomepage.html in the same folder.

<!-- helloWorld.html -->

<h1>Hello World</h1>

<load-html src="linkToHomepage.html"></load-html>
<!-- linkToHomepage.html -->

  This content was loaded by <a href="https://g14n.info/load-html">load-html</a>.

Import loadHtml function some how, for example, add the following tag to your index.html:

<script src="https://unpkg.com/load-html"></script>

Then invoke it on window load, for instance add the following snippet to your index.html:

  window.addEventListener('load', function () {



You can pass an optional callback function as argument:

  window.addEventListener('load', function () {
    loadHtml(function (nodes) {
      console.log('load-html nodes loaded: ' + nodes.length)

NOTA BENE The nodes argument passed to callback is a NodeList.

Although NodeList is not an Array, it is possible to iterate over it with forEach()

For example, using something like nodes.filter(node => !node.getAttribute('error')) will fail.

However you may want to filter those nodes that did not loaded correctly. Do something like

  window.addEventListener('load', function () {
    loadHtml(function (nodes) {
      nodes.forEach(node => {
        if (node.getAttribute('error')) {

        // Do something with your node...

Annotated source

Start with attribution comment: web site and license.

// https://g14n.info/load-html
// License: MIT

Just define a global loadHtml function.

function loadHtml (callback) {

Select all <load-html /> tags. Note the loaded attribute is used to achieve recursive loading.

  var nodes = document.querySelectorAll('load-html:not([loaded])');
  var toBeLoaded = nodes.length;

Fetch the HTML content for each node.

  nodes.forEach(function (node) {
    try {
      var loader = new XMLHttpRequest();
      loader.addEventListener('load', function loadHtml () {
        if (loader.status == 200) {
          node.innerHTML = loader.responseText;

Keep track of number of DOM nodes loaded, then try to repeat recursively. When done, invoke callback, if any.

        node.setAttribute('data-loaded', true);

        if (toBeLoaded == 0) {
          if (typeof callback == 'function') {


Send request to fetch content.

      loader.open('GET', node.getAttribute('src'), true);

Store error, mark node as loaded.

    } catch (error) {
      node.setAttribute('data-error', error.message);
      node.setAttribute('data-loaded', true);

Export it as a global function.

window.loadHtml = loadHtml;