<is-land> Web Component
This web component originally shipped May 2022 but was conspicuously missing from my web site.
<is-land>
enables Islands Architecture* on any web site. It’s an HTML web component. It has zero dependencies. It doesn’t require any server-side or build integration.
*with credit to Katie Sylor-Miller.
I use this web component everywhere—it’s a good one. Astro’s has popularized Islands Architecture (great!) and this component serves as a build-independent decoupled alternative.
If you aren’t yet familiar, Islands Architecture (apologies for this oversimplification) is turbo-charged lazy loading. It’s a way to initialize components and resources for sections (islands) of your web site when certain conditions are met: the island becomes visible, the page is idle, the viewport is a certain size, on events (click, mouseover, etc), and respecting user preferences (save data, reduce motion, etc).
- An overwhelming number of Demos
- Source code
- Documentation on 11ty.dev
You can use this with JavaScript component frameworks but it’s primarily intended for use with Web Components.
Usage
Say you have a my-component.js
web component definition file with the following content:
// my-component.js
customElements.define("my-component", class extends HTMLElement {
// …
});
You can reference it on your web site like this:
<!-- Make sure is-land.js is first -->
<script type="module" src="is-land.js"></script>
<script type="module" src="my-component.js"></script>
<is-land on:visible on:idle>
<my-component>Fallback content.</my-component>
</is-land>
Now any web components inside the <is-land>
(that were not yet :defined
when is-land.js
loaded) will delay their initialization until the loading conditions are met.
Even lazier loading
If you want to lazily load the component definition when the island initializes, you can do that too.
<script type="module" src="is-land.js"></script>
<is-land on:visible on:idle>
<my-component>Fallback content.</my-component>
<template data-island>
<script type="module" src="my-component.js"></script>
</template>
</is-land>
- You could add a
<link rel="stylesheet" href="my-component.css">
in there too, if your component has separate styles too (any valid markup works). - Use
data-island="replace"
to replace the Island’s content with the new template content.
Loading conditions
When using multiple loading conditions, all of the loading conditions for an island must be true before the island initializes.
on:visible
on:idle
- using
requestIdleCallback
- using
on:interaction
- defaults to
touchstart,click
, but you can change this to any event withon:interaction="mouseenter,focusin"
- defaults to
on:media
on:media="(min-width: 64em)"
for Viewport size.on:media="(prefers-reduced-motion: no-preference)"
to only initialize when the user has no motion preference.
on:save-data="false"
to only initialize when the user has not requested to Save Data.
Related
Read the documentation on 11ty.dev or check out a few introductory videos below:
7 Comments
siggiarni
@zachleat Ís-land? ????????
Zach Leatherman
@siggiarni ????????????????
Tegan
@zachleat Side note: Whenever I see the preview share card thing for your articles I am tricked! Tricked I say! into thinking it’s going to be a youtube video because I see your little head poking out of the corner and that’s just how youtube videos thumbnails all are
Zach Leatherman
@rawrmonstar I have a few youtube videos on this at the bottom of the post ????
rem
@zachleat question, that I don't think quit think warrants a github issue/qusetion: why use the `on:x` attribute pattern over something like `data-on-condition`? Just curious.
Zach Leatherman
@rem I don’t believe `data-` is required for custom elements so just a style preference
Marc Khoury
@zachleat Can I untap it during my untap phase?