Astro
Astro integration that renders and hydrates Ilha components as Astro islands.
@ilha/astro is an Astro integration for Ilha. You register it once, then import any component into an .astro page and hydrate it with a client directive.
It is a separate package from ilha. Add it when you build with Astro.
Install
npm install @ilha/astropnpm add @ilha/astroyarn add @ilha/astrobun add @ilha/astronub add @ilha/astroaube add @ilha/astroastro and ilha are peer dependencies.
Quick start
// astro.config.mjs
import { function defineConfig<const TLocales extends Locales = never, const TDriver extends SessionDriverName | SessionDriverConfig = never, const TFontProviders extends Array<FontProvider> = never>(config: AstroUserConfig<TLocales, TDriver, TFontProviders>): AstroUserConfig<TLocales, TDriver, TFontProviders>See the full Astro Configuration API Documentation
https://astro.build/configdefineConfig } from "astro/config";
import function ilha(options?: IlhaIntegrationOptions): AstroIntegrationilha from "@ilha/astro";
export default defineConfig<never, never, never>(config: AstroUserConfig<never, never, never>): AstroUserConfig<never, never, never>See the full Astro Configuration API Documentation
https://astro.build/configdefineConfig({
AstroUserConfig<TLocales extends Locales = never, TDriver extends SessionDriverName | SessionDriverConfig | undefined = never, TFontProviders extends Array<FontProvider> = never>.integrations?: (false | AstroIntegration | (false | AstroIntegration | null | undefined)[] | null | undefined)[] | undefinedintegrations: [function ilha(options?: IlhaIntegrationOptions): AstroIntegrationilha()],
});
Set jsxImportSource to ilha — see Render and hydrate:
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "ilha"
}
}
// src/islands/counter.tsx
import { const atom: AtomFnatom } from "ilha";
export const const Counter: ({ start }: {
start?: number;
}) => View
Counter = ({ start: numberstart = 0 }: { start?: number | undefinedstart?: number }) => {
const const count: AtomHandle<number>count = atom<number>(init: number | Atom<number> | Effect<number, unknown, AtomRegistry> | Stream<number, unknown, AtomRegistry>, options?: AtomOptions<number> | undefined): AtomHandle<number>atom(start: numberstart);
return (
<JSX.IntrinsicElements.button: ButtonHTMLAttributesbutton type?: string | undefinedtype="button" EventProps<HTMLButtonElement>.onclick?: ((event: Targeted<HTMLButtonElement, MouseEvent>) => void) | undefinedonclick={() => const count: AtomHandle<number>count.AtomHandle<number>.update: (f: (current: number) => number) => voidupdate((value: numbervalue) => value: numbervalue + 1)}>
{const count: AtomHandle<number>count}
</JSX.IntrinsicElements.button: ButtonHTMLAttributesbutton>
);
};
---
import { Counter } from "../islands/counter";
---
<Counter client:load start={10} />
How it works
| Phase | What happens |
|---|---|
| Server | The renderer calls renderToString(), which wraps output in a [data-ilha] host with a state snapshot. |
| Client | The client entry finds that host inside Astro’s <astro-island> and calls mount(..., { hydrate: true }). |
server client
────────────────────────────────── ────────────────────────────────────
.renderToStaticMarkup(component) @ilha/astro/client
→ renderToString(component) → find [data-ilha] inside <astro-island>
→ data-ilha-state snapshot → mount(host, component, { hydrate: true })
→ astro:unmount → unmount()
Client directives
| Directive | Behavior |
|---|---|
client:load |
Hydrate as soon as the page loads. |
client:idle |
Hydrate when the browser is idle. |
client:visible |
Hydrate when the island enters the viewport. |
client:media |
Hydrate when a media query matches. |
client:only |
Skip SSR. Mount fresh in the browser. |
---
import { Counter } from "../islands/counter";
---
<Counter client:only="@ilha/astro" start={0} />
When you mix JSX frameworks, pass include globs:
ilha({ include: ["**/ilha/**"] });
Import paths
| Import path | Use it for |
|---|---|
@ilha/astro |
Integration (default export / getRenderer()). |
@ilha/astro/client |
Client hydration entry (registered by Astro). |
@ilha/astro/server |
Server renderer entry (registered by Astro). |
Notes
- Ilha components do not support Astro
<slot />forwarding. Pass data through props. client:onlymounts withmount(element, component)against an empty host.- Peer ranges:
astro^7.2.9,ilha^0.14.0.
Related
| Topic | Guide |
|---|---|
Core ilha API |
ilha |
| SSR and hydrate | Render and hydrate |
| Multi-page SPA routing | Router |