Skip to content

Start

Overview

SSR islands for SvelteKit. Pages ship as server HTML with no Kit client bootstrap. JavaScript loads only for the components you mark, on a runtime of about 7.6 KB.

On this page

ogygia is an islands architecture for SvelteKit. A page ships as server HTML with no framework on it. Only two things load: a small shared runtime, and the code for the components you mark as interactive.

<script>
  import Cart from './Cart.svelte' with { wake: 'visible' };
</script>

<h1>Everything here is static HTML.</h1>
<Cart />   <!-- hydrates only when it scrolls into view -->

That is the full idea. Set csr = false to remove the Kit client from the route. Then mark the imports that you want interactive. The heading ships zero JS. Cart ships its own JS, and only when the page needs it.

When to use

Use ogygia on content pages that have small interactive parts: marketing, docs, blogs, dashboards, storefronts. Use it when you ship a full framework to run one widget. If your page is one large interactive application, plain SvelteKit with csr = true is the simpler tool. ogygia operates together with those pages, route by route.

The island below is real. It lives on this page with the mark wake: 'load'. The text around it stays HTML:

A live island
10

Everything else on this page is static HTML.

Why you want this

  • Ship much less JavaScript. There is no hydration of the full page. A static page stays static. Most pages cost only the runtime.
  • Write normal Svelte. Islands are ordinary components. The import attribute is the only new syntax. There is no special island API.
  • It is still SvelteKit. Remote functions, form actions, the router, and content operate inside islands. There is no forked framework and no patched Kit.
  • One vocabulary. Client islands, server islands, lakes, and held regions are the same small set of ideas. They are not four unrelated systems.

How it operates

A normal SvelteKit page starts the Kit client. The client hydrates the full tree. Thus each page carries the framework. ogygia inverts this. You set csr = false, and the page is only HTML. There is no Kit client and no hydration of the full page.

// the whole page opts out of the Kit client
export const csr = false;

A runtime of about 7.6 KB ships instead. It is a custom element (<ogygia-region>) plus an optional router. It waits. JS loads only for the components you mark. The JS attaches to the HTML that is already there. It does not replace that HTML.

When events occur

You mark an import with two attributes. wake says if the component ships client JS, and when the JS runs. render says where the HTML comes from, and when. The wake schedule is one small set of words:

ValueMeaning
loadImmediately
idleWhen the browser becomes idle
visibleWhen the component scrolls into view
'(max-width: 600px)'When the media query matches

On an island, the word says when the JS runs. On a server island, it says when the HTML arrives. The words are the same. The axes are different. For the full schedule, visible margins, and nested regions, see Timing & nesting.

One primitive, four kinds

Islands, server islands, lakes, and held regions are not four features. They are four settings of one <Region> envelope. The canonical table and the two dials are on the Regions page.

How the docs are organized

The sections build on each other. Read them in this sequence:

  1. Regions. Mark a component, and a part of the page becomes interactive. Islands, server islands, lakes, and held regions are four settings of one primitive.
  2. Data and state. Remote functions give islands a server. Shared state lets one live object span many islands.
  3. Content. A collection changes markdown, JSON, or a CMS into typed entries. site() arranges collections into a nav tree, search, emissions, and a shell. These docs use it.
  4. The app layer. The router swaps pages without a reload. It sends all server islands in one request. It prerenders the page you will click next.
  5. Macros. import.meta.og.* calculates at compile time each value that does not change between requests.
  6. Constraints. The rules that keep all of this correct.

Start here

  • Install: add the package and the plugin.
  • Quickstart: your first island, complete.
  • Regions: the primitive that all marks compile to.