HTML Imports are a way to include external HTML documents and web components on a page without making an Ajax request or loading an iframe. Because of this capability, HTML Imports may lead to better page load times, new opportunities to reuse code, and easier integrations with some popular services like Google Maps.
At the time of writing, the HTML Imports technology is a W3C working draft, meaning that it is not yet a web standard and is not yet supported in all browsers. HTML Imports, however, can be used safely on a web page today with a polyfill like the one in Polymer.
HTML Imports for Reuse, Syndication
Philosophically, software developers, including web developers, are taught not to repeat themselves, but rather to organize code in models, objects, functions, or similar so that there is a single point of truth and an easy way to reuse components. Thanks to developers Dave Thomas and Andrew Hunt, this approach is generally called DRY development or DRY programming, meaning “don’t repeat yourself.”
In a way, HTML Imports support DRY development. Here is an example. Imagine that you have three messages that are repeated on several web pages, perhaps even web pages on different domains. Rather than copying and pasting or retyping these messages for each page or project, they could be included using the HTML Imports feature.
Here is the HTML for a file called messages.html
:
<div class="message-success">
<h2>Success</h2>
<p>Whatever you just did worked.</p>
</div>
<div class="message-failure">
<h2>Failure</h2>
<p>What a disappointment.</p>
</div>
<div class="message-ego-boost">
<h2>You are amazing.</h2>
</div>
To reuse the content from messages.html
, first include the document via HTML Imports. This amounts to adding a <link>
element with its rel
attribute set to “import” and its href
pointed at messages.html
, like this:
<link rel="import" href="messages.html">
We can write a short bit of JavaScript that accesses the imported messages.html
document and loads the “success” message on the page. Each of the other messages could also be loaded in the same way or all together depending on how one wanted to use them. Here’s the code:
var htmlImport = document.querySelector('link[rel="import"]');
var htmlDoc = htmlImport.import;
var htmlMessage = htmlDoc.querySelector('.message-success');
document.body.appendChild(htmlMessage.cloneNode(true));
The script completes four tasks:
- Selecting the link element
- Importing the external HTML document
- Selecting a section (node) of the imported DOM
- Adding a duplicate of the selected node to the current page
Just like that, the success message is now included on the page, similar to how an Ajax request works.
This example is, of course, overly simplified and would not be a very practical use for HTML Imports in a live application given that the success message, as written, was four lines of HTML and using HTML Imports to load it took seven lines of code. But if the content in messages.html
had been significantly more complex with, perhaps, a few hundred lines of HTML with supporting JavaScript and CSS, it would have still taken HTML Imports just seven lines of code to load it.
As a second imports reuse example, consider how scripting languages are often used to load reusable content into a page. The example below comes from the single.php
file of the Underscores starter theme for WordPress:
<?php
/**
* The template for displaying all single posts.
*
* @package _s
*/
get_header(); ?>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<?php get_template_part( 'content', 'single' ); ?>
<?php _s_post_nav(); ?>
<?php
// If comments are open or we have at least one comment, load up the comment template
if ( comments_open() || '0' != get_comments_number() ) :
comments_template();
endif;
?>
<?php endwhile; // end of the loop. ?>
</main><!-- #main -->
</div><!-- #primary -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>
Notice, there are several places in the single.php
code example were external resources are referenced and used, including to get the page header, load a template, load post navigation, load a sidebar, and load the footer.
The way that the PHP script is calling outside resources is analogous to how HTML Imports might be used to add content and features to a page. This point may become more clear when one considers that HTML Imports are part of the HTML Web Components draft.
Web Components have four building blocks, if you will. Eric Bidelman, who works in developer relations at Google and presented the Web Components talk at Googio I/O in 2013 and 2014, described these blocks:
- Shadow DOM – provides DOM and style encapsulation.
- HTML Templates – are inert chunks of clonable DOM elements that serve as a scaffold or blueprint.
- Custom Elements – expand HTML’s existing vocabulary and extend DOM objects.
- HTML Imports – allow web components to be packaged, shared, distributed, and reused.
With web components in mind, you might be able to imagine how you could use HTML Imports to load significant features and functions to any HTML page. Here are some theoretical web components that HTML Imports could load for you.
- Checkout with PayPal – drop an
<x-paypal-express key="6827364828736" callback="some.html">
tag on the page, passing a nested HTML form, and you may be able to add secure checkout to any page. - Email Subscription Form – Using HTML Imports, adding an email subscription form might be as simple as importing an external HTML document and adding an
<email-subscribe>
tag. - Google Maps – a frequently used HTML Imports example is adding a Google Map with a simple custom element
<google-map lat="37.790" long="-122.390">. This works, of course, only after HTML Imports has loaded the document defining this custom tag.
All of these examples rely on HTML Imports for inclusion.
A third example of how HTML Imports might help web and app developers comes from Bidelman, who suggested that Imports might more effectively load some frameworks or other bundles of HTML and associated resources.
In his specific example, Bidleman loaded Bootstrap with its many files and dependencies in a single bundle.
<link rel="import" href="bootstrap.html">
The source called bootstrap.html
would look similar to what you would find in the <head>
of a Bootstrap-powered site:
<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="fonts.css">
<script src="jquery.js"></script>
<script src="bootstrap.js"></script>
<script src="bootstrap-tooltip.js"></script>
<script src="bootstrap-dropdown.js"></script>
Browser Support for HTML Imports
As mentioned above, there is presently little browser support for HTML Imports, with only Chrome 36+, Chrome 37+ for Android, and Opera 23+ offering native support by default. Firefox 32+ does support HTML Imports, but only if the user enables them in about:config
.
There are polyfills that will make the feature available in nearly any browser. Perhaps, the most robust is the aforementioned Polymer Imports polyfill.
Further Reading and Resources
- W3C HTML Imports Working Draft
- W3C HTML Imports Editor’s Draft
- Eric Bidelman’s HTML Imports Tutorial
- 2013 Google I/O Web Components Session on YouTube
- 2014 Google I/O Polymer and Web Components Session on YouTube
Frequently Asked Questions about HTML Imports
Why were HTML imports deprecated and removed?
HTML imports were deprecated and removed due to several reasons. Firstly, they were not widely adopted by major browsers except for Chrome and Opera. This lack of support made it difficult for developers to use HTML imports consistently across different platforms. Secondly, HTML imports had performance issues. They could cause a delay in rendering the main page because the browser had to wait for the imported HTML document to load fully. Lastly, the introduction of ES modules, which are more powerful and flexible, made HTML imports redundant.
What are the alternatives to HTML imports?
The main alternative to HTML imports is ES modules. ES modules allow you to import JavaScript, HTML, and CSS files into your project. They are more flexible and powerful than HTML imports, and they are supported by all major browsers. Other alternatives include using AJAX to load HTML content dynamically or using iframes to embed HTML documents.
How do I use ES modules as an alternative to HTML imports?
To use ES modules, you need to use the import
keyword followed by the path to the module you want to import. For example, import { myFunction } from './myModule.js';
. You can then use myFunction
in your code. Note that ES modules use a different syntax than HTML imports and require a server to work correctly.
Can I still use HTML imports in my project?
While HTML imports have been deprecated and removed from the HTML standard, they are still supported in some browsers like Chrome and Opera. However, it’s not recommended to use them in new projects because they may not work in all browsers and their support may be removed in the future.
What are the benefits of using ES modules over HTML imports?
ES modules have several benefits over HTML imports. They are supported by all major browsers, they allow you to import JavaScript, HTML, and CSS files, and they have better performance. ES modules also support features like dynamic imports and top-level await, which are not available in HTML imports.
How can I load HTML content dynamically without using HTML imports?
You can use AJAX to load HTML content dynamically. AJAX allows you to send and receive data from a server without refreshing the page. You can use the fetch
API or the XMLHttpRequest
object to send an AJAX request and then insert the received HTML content into your page.
What is the difference between HTML imports and iframes?
HTML imports and iframes both allow you to include HTML documents in your page, but they work differently. HTML imports merge the imported document into the main document, while iframes create a separate browsing context for the imported document. This means that scripts and styles in an imported document can affect the main document when using HTML imports, but not when using iframes.
Can I use HTML imports in combination with other technologies?
Yes, you can use HTML imports in combination with other technologies like AJAX and iframes. However, keep in mind that HTML imports are deprecated and may not work in all browsers.
How can I ensure that my code works in all browsers if I use HTML imports?
If you decide to use HTML imports, you should provide a fallback for browsers that do not support them. You can use feature detection to check if the browser supports HTML imports and then load the content using a different method if it does not.
What is the future of HTML imports?
The future of HTML imports is uncertain. They have been deprecated and removed from the HTML standard, and their support may be removed from browsers in the future. The focus has shifted towards ES modules, which are more powerful and flexible. Therefore, it’s recommended to use ES modules or other alternatives in new projects.
Armando Roggio is an experienced director of marketing, ecommerce expert, growth hacker, web developer and writer. When he is not analyzing data or writing (code or prose), Armando is also a high school wrestling coach.