HTML includes

A zero-dependency Web Component for reusable HTML fragments.

Overview

Live Wires uses a custom <html-include> element to load HTML fragments at runtime. This enables you to share headers, footers, navigation, and other repeated content across pages without build-time processing.

Key features

  • Zero dependencies—Pure Web Components API, no libraries
  • Runtime loading—Fragments are fetched when the page loads
  • Script support—JavaScript in includes executes correctly
  • Error handling—Shows debug messages in development mode
  • Standard HTML—No special syntax or templating language

To top

Basic usage

1. Load the Web Component first

The <html-include> element must be defined before any instances appear in the document. Include the script in your <head>:

<head>
  <!-- Load Web Component first (required!) -->
  <script type="module" src="/src/js/main.js"></script>

  <!-- Now includes will work -->
  <html-include src="/_includes/head.html"></html-include>
</head>

2. Use the element anywhere

<body>
  <html-include src="/_includes/header.html"></html-include>

  <main>
    <!-- Your page content -->
  </main>

  <html-include src="/_includes/footer.html"></html-include>
</body>

3. Create your include files

Store reusable fragments in /public/_includes/:

<!-- /public/_includes/header.html -->
<header class="py-3 px-4">
  <nav class="cluster cluster-space-between">
    <a href="/" class="logo">
      <img src="/img/logo.svg" alt="Site Name">
    </a>
    <ul class="cluster">
      <li><a href="/">Home</a></li>
      <li><a href="/about/">About</a></li>
      <li><a href="/contact/">Contact</a></li>
    </ul>
  </nav>
</header>

To top

Path conventions

The src attribute accepts both absolute and relative paths:

Absolute paths (recommended)

<!-- Always works, regardless of page location -->
<html-include src="/_includes/header.html"></html-include>

Relative paths

<!-- From /docs/index.html -->
<html-include src="/_includes/header.html"></html-include>

Absolute paths starting with / are resolved from the site root, making them more portable. Use relative paths when the include is specific to a section.

To top

Passing classes

Classes on the <html-include> element are preserved:

<html-include class="bg-subtle" src="/_includes/nav.html"></html-include>

This lets you apply styling or layout to the include wrapper without modifying the include file itself.

To top

JavaScript in includes

Scripts inside include files are re-executed after loading. This works because the component explicitly creates new <script> elements:

<!-- /public/_includes/analytics.html -->
<script>
  console.log('Analytics loaded');
  // Your tracking code here
</script>

Both inline scripts and external scripts (with src) are supported.

To top

Error handling

If an include fails to load, the component logs an error to the console:

HtmlInclude: failed to load /_includes/missing.html

In development mode (Vite dev server), a visible error message is displayed in place of the include:

Failed to load include: /_includes/missing.html

This helps catch typos and missing files during development.

To top

Common includes

A typical Live Wires project uses these includes:

/_includes/head.html
Meta tags, title, favicon, additional CSS
/_includes/header.html
Site header with logo and navigation
/_includes/footer.html
Site footer with copyright, links
/_includes/nav-*.html
Section-specific navigation (e.g., nav-docs.html, nav-guide.html)

To top

SEO considerations

Content loaded via JavaScript is generally indexed by modern search engines. Google executes JavaScript and can see client-rendered content. However, there are practical considerations:

Best practice: Use includes for

  • Headers and footers (repeated across pages)
  • Navigation (links are crawlable)
  • Repeated UI elements

Keep in main HTML

  • Page titles and meta descriptions
  • Primary content unique to each page

For build-time includes

If you prefer pre-rendered HTML (faster initial paint, works without JavaScript), consider:

  • vite-plugin-handlebars for static site generation
  • 11ty, Astro, or similar static site generators

Live Wires' HTML and CSS patterns work with any build tool.

To top

How it works

The component is defined in src/js/html-include.js:

  1. When a <html-include> element connects to the DOM, connectedCallback() fires
  2. The src attribute is read
  3. The HTML is fetched via fetch()
  4. Content is parsed using a <template> element
  5. The parsed content replaces the element’s children
  6. Any <script> tags are re-created to execute

Total code: ~60 lines. No dependencies.

To top

Troubleshooting

Include not loading

  • Check that main.js is loaded before the include element
  • Verify the src path is correct (check browser console)
  • Ensure the include file exists at the specified path

Styles not applying

  • Include content inherits styles normally—no shadow DOM
  • Check that your CSS is loaded before the include renders

Scripts not running

  • Scripts execute after the include loads
  • If accessing DOM elements, ensure they exist (use DOMContentLoaded or put scripts at end)

To top