1. The Include-Like Syntax
The custom element turns a familiar link tag into an inline include point.
Code:
<link rel="import" href="header.html" is="ui-import">
Result:
2. Extending the Built-In Link Element
This is the core implementation used by every showcase on this page.
Code:
class HtmlImport extends HTMLLinkElement {
constructor () {
super();
}
static get observedAttributes () {
return ['href'];
}
load () {
fetch(this.href).then(res => res.text()).then(html => {
this.style.display = 'block';
this.innerHTML = html;
});
}
attributeChangedCallback () {
this.load();
}
}
if (!customElements.get('ui-import')) {
customElements.define('ui-import', HtmlImport, {
extends: 'link'
});
}
Result:
3. Changing href Replaces the Included Fragment
Because href is observed, changing it triggers a new load.
Code:
<link rel="import" href="header.html" is="ui-import" id="switchImport">
switchImport.href = selectedFile;
Result:
4. Load and Error Events
A fuller helper can dispatch events so the host page can react to success or failure.
Code:
<link rel="import" id="eventImport" href="header.html" is="ui-import">
eventImport.addEventListener('load', function () {
statusBox.textContent = 'Loaded successfully';
});
eventImport.addEventListener('error', function (event) {
statusBox.textContent = event.detail.message;
});
Result:
Waiting for an import event.
5. Security: Inline Scripts Stay Inert with innerHTML
The imported HTML can render markup and styles, but scripts inserted by innerHTML do not run.
Code:
<link rel="import" href="unsafe.html" is="ui-import">
Result:
This demo imports a fragment containing an inline script. The visual HTML appears, but the script counter stays unchanged.
Inline script executions: 0
6. A Static Page Built from Includes
A page can be assembled from several small fragments without a build step.
Code:
<main>
<link rel="import" href="header.html" is="ui-import">
<link rel="import" href="card.html" is="ui-import">
<link rel="import" href="footer.html" is="ui-import">
</main>
Result: