https://github.com/11ty/is-land
A new performance-focused way to add interactive client-side components to your web site.
https://github.com/11ty/is-land
Last synced: 8 days ago
JSON representation
A new performance-focused way to add interactive client-side components to your web site.
- Host: GitHub
- URL: https://github.com/11ty/is-land
- Owner: 11ty
- License: mit
- Created: 2022-05-25T22:23:02.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2025-03-24T20:05:29.000Z (27 days ago)
- Last Synced: 2025-04-06T05:13:37.052Z (15 days ago)
- Language: JavaScript
- Homepage: https://is-land.11ty.dev/
- Size: 224 KB
- Stars: 589
- Watchers: 6
- Forks: 20
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-islands - 11ty `is-land`
README
# ``
A new performance-focused way to add interactive client-side components to your web site.
Or, more technically: a framework independent partial hydration islands architecture implementation.
- View the [demos](https://is-land.11ty.dev/)
- Check out the [initial screencast on Eleventy’s YouTube channel](https://youtu.be/YYJpFdEaAuc?t=188) and [the follow up screencast with more framework examples](https://www.youtube.com/watch?v=V9hWgVV_5mg).
- [Learn more about Islands Architecture](https://jasonformat.com/islands-architecture/)Features:
- Easy to add to existing components
- Zero dependencies
- Not tightly coupled to a server framework or site generator tool.
- Small footprint (1.79 kB compressed)
- Server-rendered (SSR) component examples available for SSR-friendly frameworks (Lit, Svelte, Vue, Preact are provided)Examples for:
- [Web Components](https://is-land.11ty.dev/)
- [Web Components using Declarative Shadow DOM](https://is-land.11ty.dev/demo-declarative-shadow-dom) _(New in v3.0.0)_
- [Svelte](https://is-land.11ty.dev/demo-svelte) (and SSR)
- [Vue (and petite-vue)](https://is-land.11ty.dev/demo-vue) (and SSR)
- [Preact](https://is-land.11ty.dev/demo-preact) (and SSR)
- [Lit](https://is-land.11ty.dev/demo-lit) (and SSR)
- [Alpine.js](https://is-land.11ty.dev/demo-alpine)
- [Embedded in Markdown](https://is-land.11ty.dev/demo-markdown)
- [`defer-hydration` Component Attribute Support](https://is-land.11ty.dev/demo-defer-hydration) _(New in v3)_ ([Read more about `defer-hydration` at zachleat.com](https://www.zachleat.com/web/defer-hydration/))
- [Using import maps to simplify import URLs](https://is-land.11ty.dev/demo-importmaps).
- [Renaming `` tag name or the `on:` attribute prefix](https://is-land.11ty.dev/demo-rename)
- _Experimental:_ [Image Loading](https://is-land.11ty.dev/demo-image-loading)
- [Stress test of 10000 islands](https://is-land.11ty.dev/demo-stress-test)
- [Complex nested `is-land` test](https://is-land.11ty.dev/demo-stress-test-nest)Integrations in the wild: [Eleventy](https://is-land.11ty.dev/), [WebC](https://demo-webc-image-compare.netlify.app), [Slinkity](https://twitter.com/slinkitydotdev/status/1544322804774064133), [SvelteKit](https://twitter.com/geoffrich_/status/1576932300960342018), [Bridgetown](https://twitter.com/jaredcwhite/status/1585433466770173953), [Lit](https://twitter.com/techytacos/status/1590248099297259520)
## Installation
Available on [npm at `@11ty/is-land`](https://www.npmjs.com/package/@11ty/is-land).
```
npm install @11ty/is-land
``````html
```
Add `is-land.js` to your primary bundle.
It can be deferred and/or loaded asynchronously. When using with web components it must be loaded before any other custom elements (via `customElements.define`) on the page. Choose your style:
## Usage
```html
This is an island.
```Add any number of loading conditions to this tag to control how and when the island is initialized. You can mix and match. _All_ conditions be satisfied to initialize.
* `on:visible`
* `on:load` (new in v5)
* `on:idle`
* `on:interaction` (defaults to `touchstart,click`)
* Change events with `on:interaction="mouseenter,focusin"`
* `on:media`
* When Viewport size matches: `on:media="(min-width: 64em)"`
* Reduced motion:
* When user prefers reduced motion `on:media="(prefers-reduced-motion)"`
* When user has no preference on motion `on:media="(prefers-reduced-motion: no-preference)"`
* Save Data ([read about Save Data on MDN](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation/saveData))
* When Save Data is active `on:save-data`
* When Save Data is inactive `on:save-data="false"````html
```
### Controlling Fallback Content
#### Pre-JS
```html
Put your pre-JS fallback content in your web component.
```
#### Post-JS with ``
Place any post-JS content inside of one or more `` elements anywhere in the ``. These will be swapped with their template content. You can nest an `` in there if you want!
```html
This component is post-JS.
```
* Use `data-island="replace"` to replace the contents of the `` with the template.
* Use `data-island="once"` to run a template’s contents once per page (keyed from template contents). _(New in v2.0.1)_#### Run your own custom JavaScript, load your own CSS
Embed a script inside the template to run custom JS when the island’s loading conditions have been satisfied!
```html
/* My custom CSS */
console.log("Hydrating!");
```
You can also use the `ready` attribute for styling, added to the `` when the island has been hydrated.
```html
is-land[ready] {
background-color: lightgreen;
}```
### Framework Component Support
- `type`: initialize a framework initialization type, registered by you. Examples included for: `alpine`, `petite-vue`, `vue`, `vue-ssr`, `preact`, `preact-ssr`, `svelte`, or `svelte-ssr`.
[Demos, examples, and source code](https://is-land.11ty.dev/) are available for each framework listed here.
#### Petite Vue
* [Examples](https://is-land.11ty.dev/demo-vue)
* Small library (~9K)
* Rendering modes: Client
* Progressive-enhancement friendly (control fallback content)```html
// Define once for any number of Petite Vue islands.
Island.addInitType("petite-vue", async (target) => {
const { createApp } = await import("https://unpkg.com/[email protected]/dist/petite-vue.es.js");
createApp().mount(target);
});Hello from HTML
```
#### Vue
* [Examples](https://is-land.11ty.dev/demo-vue)
* Larger library (~73 kB)
* Rendering modes: Client (shown), Server, Server + Client (Hydration)```html
// Define once for any number of Vue islands.
Island.addInitType("vue", async (target) => {
const { createApp } = await import("https://unpkg.com/[email protected]/dist/vue.esm-browser.js");
createApp({
data: () => (target.dataset), // use <is-land data-> attributes as component data
}).mount(target);
});Hello from
```
#### Svelte
* [Examples](https://is-land.11ty.dev/demo-svelte) (using Import Maps)
* Medium-sized library
* Rendering modes: Client, Server, Server + Client (Hydration)
* Requires a compiler for client mode (uncommon)```html
// Define once for any number of Svelte islands.
Island.addInitType("svelte", async (target) => {
// requires an Import map and svelte is lazy loaded when island is ready
const { mount } = await import("svelte");
const component = await import(target.getAttribute("import"));mount(component.default, {
target: target,
props: {},
});
});{% assign component = "./lib/svelte/my-component-js-only.svelte" | svelte %}
```
Show sample Import Map
```html
{
"imports": {
"svelte": "https://unpkg.com/[email protected]/src/index-client.js",
"svelte/internal/client": "https://unpkg.com/[email protected]/src/internal/client/index.js",
"svelte/internal/flags/legacy": "https://unpkg.com/[email protected]/src/internal/flags/legacy.js"
},
"scopes": {
"https://unpkg.com/": {
"clsx": "https://unpkg.com/[email protected]/dist/clsx.mjs",
"esm-env": "https://unpkg.com/[email protected]/index.js",
"esm-env/browser": "https://unpkg.com/[email protected]/true.js",
"esm-env/development": "https://unpkg.com/[email protected]/false.js",
"esm-env/node": "https://unpkg.com/[email protected]/false.js"
}
}
}```
#### Preact
* [Examples](https://is-land.11ty.dev/demo-preact)
* Small library (~9 kB)
* Rendering modes: Client (shown), Server, Server + Client (Hydration)
* No compiler needed when using [`htm`](https://github.com/developit/htm) rather than JSX.```html
// Define once for any number of Preact islands.
Island.addInitType("preact", async (target) => {
const component = await import(target.getAttribute("import"));
component.default(target);
});```
Example component code for
preact-component.js
:```js
import { html, render } from 'https://unpkg.com/htm/preact/index.mjs?module'function App (props) {
return html`Hello ${props.name}!
`;
}export default function(el) {
render(html`<${App} name="from Preact" />`, el);
}
```#### Lit
* [Examples](https://is-land.11ty.dev/demo-lit) (using Import Maps)
* Small library (~10 kB)
* Rendering modes: Client, Server, Server + Client (Hydration)```html
Pre-JS Content
```
Show sample Import Map
```html
{
"imports": {
"lit": "https://unpkg.com/[email protected]/index.js"
},
"scopes": {
"https://unpkg.com/": {
"@lit/reactive-element": "https://unpkg.com/@lit/[email protected]/reactive-element.js",
"lit-element/lit-element.js": "https://unpkg.com/[email protected]/lit-element.js",
"lit-html": "https://unpkg.com/[email protected]/lit-html.js",
"lit-html/is-server.js": "https://unpkg.com/[email protected]/is-server.js"
}
}
}```
Example component code
lit-component.js
:```js
import {html, css, LitElement} from "lit";customElements.define('lit-component', class extends LitElement {
static properties = {
name: {type: String},
};render() {
return html`Hello, ${this.name || "Stranger"}!
`;
}
});
```#### Alpine.js
* [Examples](https://is-land.11ty.dev/demo-alpine)
* Smaller library (~20 kB)
* Rendering modes: Client
* Progressive-enhancement friendly (control fallback content)```html
// Define once for any number of Alpine islands.
Island.addInitType("alpine", async (target) => {
await import("https://unpkg.com/[email protected]/dist/cdn.min.js");
});// Workaround for Alpine global mount
Island.addFallback("[x-data]", (node) => {
if(node.hasAttribute("x-ignore")) {
return;
}node.setAttribute("x-ignore", "");
return () => {
node.removeAttribute("x-ignore");if(Alpine) {
Alpine.nextTick(() => Alpine.initTree(node));
}
};
});
Hello from HTML!
```
#### Solid.js
* [Examples](https://is-land.11ty.dev/demo-solid) (using Import Maps)
* Medium library (~40 kB)
* Rendering modes: Client