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.
Features:
Integrations in the wild:
Examples:
defer-hydration
Component Attribute Support (New in v3.0.0) Read more about `defer-hydration` at zachleat.comThis is a control to make sure the component initializes as expected without an island.
These islands are eagerly loaded and initialized.
Gnarly nesting
Testing A
Testing B
on:visible
on:visible
nested groupParent island has on:visible
but none of the child components have an explicit loading condition. They will inherit the loading conditions of all of the ancestors.
on:idle
on:interaction
Requires one of: touchstart, click.
Note here that we used one parent island to group both of these components, and interacting with either initializes the whole group.
Use on:interaction="mouseenter,focusin"
to override the events.
In this example we use a third party web component (<details-utils>) without any code changes made to the component. Note that children here are maintained before and after initialization (e.g. click the summary to expand before init and it keeps that state after init).
Note that interacting with content inside of the menu works without closing the menu.
Note that interacting with content inside of the menu works without closing the menu.
on:media
on:media="(min-width: 64em)"
This only runs when the viewport is greater than or equal to 1024px wide: on:media="(min-width: 64em)"
This only runs when the viewport is less than 1024px wide: on:media="(max-width: 63.9375em)"
This runs when the user prefers reduced motion: on:media="(prefers-reduced-motion)"
This runs when does not have a reduced motion preference: on:media="(prefers-reduced-motion: no-preference)"
on:save-data
This runs when the user has Save Data enabled:
on:save-data="false"
This runs when the user does not have Save Data enabled:
If you put child content in a <template> it will be JavaScript-only (no fallback). Use this to your advantage! You can mix and match <template> with other progressively enhanced content in the island.
Use the ready
attribute on <is-land>
(added when the island is hydrated) for additional styling!
Use data-island="replace"
to replace the island content with the template. If more than one of these exists in an island, only the first is used.
This content is pre-JS. This is where your loading spinner goes 😈
Do you know the aspect ratio of the hydrated content? On my personal web site I use this to hydrate a <lite-youtube> component. Works great with CSS aspect-ratio
!
Nest any inline <script>
, <script src>
, <style>
, <link rel="stylesheet">
inside a <template data-island>
to execute when conditions are met. The text will turn red when the inline CSS loads and bold when the external stylesheet loads.