Advanced Features
Explore islands architecture, selective hydration, and nested layouts.
Hydration Strategies
Avalon supports multiple hydration strategies to optimize performance:
- on:client — Hydrate immediately on page load
- on:visible — Hydrate when scrolled into view
- on:interaction — Hydrate on click or hover
- on:idle — Hydrate during browser idle time
- media: — Hydrate based on a CSS media query
// Hydrate when visible in viewport
<Chart island={{ condition: 'on:visible' }} />
// Hydrate on first click or hover
<Feed island={{ condition: 'on:interaction' }} />
// Hydrate only on wide screens
<Sidebar island={{ condition: 'media:(min-width: 1024px)' }} />Multi-Framework Support
Use React, Preact, Vue, Svelte, Solid, or Lit components in the same project. Each framework's islands are bundled separately for optimal code splitting.
import ReactCounter from '../islands/ReactCounter.tsx';
import VueChart from '../islands/VueChart.vue';
import SvelteFeed from '../islands/SvelteFeed.svelte';
export default async function Page() {
return (
<div>
<ReactCounter island={{ condition: 'on:interaction' }} />
<VueChart island={{ condition: 'on:visible' }} />
<SvelteFeed island={{ condition: 'on:idle' }} />
</div>
);
}Nested Layouts
Layouts compose automatically based on directory structure. A layout in src/layouts/blog/_layout.tsx wraps all pages in src/pages/blog/, and the root src/layouts/_layout.tsx wraps everything.
src/layouts/
├── _layout.tsx # wraps all pages
└── blog/
└── _layout.tsx # wraps /blog/* pages onlyUse layoutConfig.skipLayouts to opt out of specific layouts when needed:
export const layoutConfig = {
skipLayouts: ['_layout'],
};API Routes
Drop a file in routes/api/ to create a server-side API endpoint. Handlers receive an H3 event and can return any serializable value.
// routes/api/hello.ts
export default defineEventHandler((event) => {
return { message: 'Hello from Avalon!' };
});