Resumable: async data
The page loader fetches the initial data on the server; it lands in a signal, serializes into the island, and resumes on the client — the list shows without the component running. The Refresh button is an async handler that await fetch()s: it lifts verbatim, so on click it reloads data and updates the signal — still without re-running the component.
Tip
The list below is server-rendered and resumed (no component execution on load). Click "Refresh" — the async handler fetches new data from /api/resumable-feed and the count + list update. Each fetch returns an increasing number to prove the round-trip.
Live demo
3 items · server (SSR)
• Server-rendered item 1
• Server-rendered item 2
• Server-rendered item 3
"use resumable";
import { signal } from "@bext-stack/framework/signals";
// The page loader fetches the initial data and passes it as props →
// it lands in a signal, serializes into the island, and RESUMES on the
// client (the component never runs).
export default function Feed(props) {
const items = signal(props.items ?? []);
return (
<div>
{/* an ASYNC handler — lifts verbatim into __rh, awaits fetch on the
client, and updates the signal. No component re-run. */}
<button onClick={async () => {
const r = await fetch("/api/resumable-feed");
items.value = (await r.json()).items;
}}>Refresh</button>
<div>{items.value.length} items</div>
</div>
);
}