Async components and server data
A generated element renderer becomes asynchronous in either of these cases:
- The Svelte component awaits during server rendering.
- Its adjacent server preparation hook returns a promise.
Choose the source of the async work based on what the browser needs to repeat.
Await inside the component
Section titled “Await inside the component”Use Svelte’s async support when waiting belongs to the component’s render. The component code and its imports take part in both browser and server builds. The browser runs that work again during hydration because svebcomponents cannot serialize component-local state.
Enable compilerOptions.experimental.async in the component package’s Svelte
configuration and in a Svelte host. Non-Svelte hosts enable Svelte’s server
flag through @svebcomponents/ssr/enable-async.
Prepare data on the server
Section titled “Prepare data on the server”Add <entry>.ssr.ts next to a component entry when you need server-only code
or want to pass a prepared value into hydration. For src/ProfileCard.svelte,
create src/ProfileCard.ssr.ts:
import type { SsrPrepare } from "@svebcomponents/ssr";import { loadProfile } from "./profile.server.js";
const prepare: SsrPrepare = ({ props, setProperty }) => { if (props.profile !== undefined) return;
return loadProfile().then((profile) => { setProperty("profile", profile); });};
export default prepare;props contains the values the host supplied. setProperty() changes the
props before Svelte renders. In a hydratable build, the server renderer
serializes JSON-compatible rich values for the generated element extension, so
hydration starts with the same data. Functions, symbols, and cyclic objects
cannot cross this handoff.
Keep the synchronous return when the host already supplied the value. Hosts that cannot await can still render that request through their synchronous path.
@svebcomponents/build includes the adjacent hook in the server output and
keeps its dependencies out of the browser bundle.
Enable the host path
Section titled “Enable the host path”| Host | Async preparation hook | Component await |
|---|---|---|
| SvelteKit | Enable compilerOptions.experimental.async; the Vite plugin selects its async wrapper. | Use the same setting. |
| Vue | The default adapter awaits the hook. | Import @svebcomponents/ssr/enable-async in the server entry. |
| Astro | The default adapter awaits the hook. | Import @svebcomponents/ssr/enable-async before the component renderer. |
| React | Use @svebcomponents/ssr-react/rsc from a Server Component. | Use the RSC wrapper and import @svebcomponents/ssr/enable-async in the server entry. |
The SvelteKit, Vue, Astro, and React guides show each setup.
Svelte throws await_invalid if a non-Svelte host skips the opt-in and the
component reaches an await. React’s default wrapper catches the adapter’s async-renderer
signal and leaves the element for the browser; it does not hide component
render errors.