AvalonAvalon
GitHub

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 only

Use 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!' };
});