hydrate function for interactive SSR
The hydrate function is similar to mount but will reuse HTML rendered by Svelte's SSR output from the render function inside the target element and make it interactive. It takes two parameters: the component and an options object accepting target (a DOM element) and props (an object of properties). Like mount, effects will not run during hydrate, but can be forced to run using flushSync() immediately afterwards.
import render from svelte/server
The render function is imported from the 'svelte/server' package path.
render function for server-side rendering
The render function is only available on the server and when compiling with the server option. It takes a component and an options object containing props. It returns an object with body and head properties. The body property contains HTML for the document body tag and the head property contains HTML for the document head tag.
import hydrate from svelte
The hydrate function is imported from the 'svelte' package.
unmount function signature and behavior
The unmount function removes a component that was previously created with mount or hydrate. It takes the component instance and an options object. The options object accepts an outro property (boolean). If options.outro is true, transitions will play before the component is removed from the DOM. The function returns a Promise that resolves after transitions have completed if outro is true, or immediately otherwise.
import unmount from svelte
The unmount function is imported from the 'svelte' package.
import mount from svelte
The mount function is imported from the 'svelte' package.
mount function signature and behavior
The mount function instantiates a component and mounts it to a given target element. It takes two parameters: the component and an options object. The options object accepts target (a DOM element) and props (an object of properties). Multiple components can be mounted per page. Unlike Svelte 4's 'new App(...)', effects including onMount callbacks and action functions will not run during mount. Effects can be forced to run using flushSync().
Runtime documentation file
The Runtime documentation is located in apps/svelte.dev/content/docs/svelte/06-runtime/index.md. This file is generated automatically by apps/svelte.dev/scripts/sync-docs/index.ts and should not be edited manually.
Prefer nonce over hash for CSP with hydratable
Use nonce instead of hash when possible with hydratable, as hash will interfere with streaming SSR in the future.
hydratable API prevents re-fetching data on client
The hydratable API prevents asynchronous work from being redone during client-side hydration. When data is fetched on the server, hydratable serializes and stashes the result, associated with a provided key and baked into the head content. During hydration, it returns the serialized version instead of running the function again. After hydration, subsequent calls invoke the function normally.
hydratable with promises example
Promises returned from hydratable can be awaited in the template. Example: const promises = hydratable('random', () => ({ one: Promise.resolve(1), two: Promise.resolve(2) })); then use {await promises.one} and {await promises.two} in markup.
hydratable CSP hash configuration for static HTML
For static HTML generated ahead of time (not dynamic server rendering), use hash instead of nonce: await render(App, { csp: { hash: true } }). This returns hashes.script as an array of strings like ['sha256-abcd123']. Add these hashes to the CSP header: Content-Security-Policy: script-src ${hashes.script.map((hash) => `'${hash}'`).join(' ')}.
hydratable nonce must be used once per response
A nonce (number used once) must only be used when dynamically server rendering an individual response, not reused across multiple requests.
hydratable CSP nonce configuration
hydratable adds an inline script block to the head, which can fail under Content Security Policy. To fix this, pass a nonce to the render function: await render(App, { csp: { nonce } }). The nonce is added to the script block and must match the nonce in the CSP header: Content-Security-Policy: script-src 'nonce-${nonce}'.
hydratable syntax and usage
hydratable is imported from 'svelte' and called with two arguments: a key string and a function that returns the data. Example: const user = await hydratable('user', () => getUser()). The key is used to associate the serialized result and should be prefixed with your library name to avoid conflicts.
hydratable enables stable random and time-based values
hydratable can be used to provide random or time-based values that remain stable between server rendering and hydration. For example, const rand = hydratable('random', () => Math.random()) will generate a random number on the server that stays the same during hydration instead of generating a new value.
hydratable supports devalue serialization plus promises
All data returned from hydratable must be serializable. Svelte uses devalue for serialization, which supports Map, Set, URL, BigInt, and JSON types. Additionally, thanks to Svelte's implementation, promises can be used and awaited in the serialized data structure.
flip animation browser support
The flip animation from svelte/animate is supported in Firefox 126 and above. Safari and Chrome/Edge support status is not specified.
Async Svelte requires version 5.36+ and experimental.async option
If using version 5.36 or higher, you can use await expressions and hydratable to use promises directly inside components. Note that these require the experimental.async option to be enabled in svelte.config.js as they are not yet considered fully stable.
Use context instead of shared module state
Consider using context instead of declaring state in a shared module. This will scope the state to the part of the app that needs it, and eliminate the possibility of it leaking between users when server-side rendering. Use createContext rather than setContext and getContext, as it provides type safety.
flip animate directive requires higher browser version
The flip directive from svelte/animate requires Firefox 126 or later. It is not supported in Chrome/Edge or Safari.
Custom elements compiler option and tag name
Svelte components can be compiled to custom elements using the `customElement: true` compiler option. A tag name must be specified for the component using the `<svelte:options>` element.
Polyfills required for older browser support
Polyfills are required to support older browsers when using custom elements.
Slotted content in custom elements renders eagerly
In custom elements, slotted content renders eagerly, not lazily like in regular Svelte components. Content will always be created even if the `<slot>` element is inside an `{#if ...}` block. Including a `<slot>` in an `{#each ...}` block will not cause the slotted content to be rendered multiple times.
Inner components without customElement tag name
You can leave out the tag name for any inner components which you do not want to expose and use them like regular Svelte components. Consumers can still name them afterwards if needed using the static `element` property when the `customElement` compiler option is true.
Property names starting with 'on' interpreted as event listeners
Do not declare properties or attributes starting with 'on' in custom elements, as their usage will be interpreted as an event listener. For example, `<custom-element oneworld={true}></custom-element>` is treated as `customElement.addEventListener('eworld', true)` rather than `customElement.oneworld = true`.
Context feature limitations in custom elements
Svelte's context feature can be used between regular Svelte components within a custom element, but not across custom elements. You cannot use `setContext` on a parent custom element and read it with `getContext` in a child custom element.
let: directive deprecated in custom elements
The deprecated `let:` directive has no effect in custom elements because custom elements do not have a way to pass data to the parent component that fills the slot.
Custom elements and server-side rendering
Custom elements are not generally suitable for server-side rendering because the shadow DOM is invisible until JavaScript loads.
TypeScript in extend function limitations
TypeScript is supported in the `extend` function but with limitations: you must set `lang='ts'` on one of the scripts, and you can only use erasable syntax in the extend function. Script preprocessors do not process the extend function.
customElement extend option function signature
The `extend` property expects a function that receives the custom element class generated by Svelte and returns a custom element class. This allows customization of the lifecycle or enhancement with features like ElementInternals.
customElement shadow option values
The `shadow` property accepts three types of values: 'none' (no shadow root, styles not encapsulated, slots not available), 'open' (shadow root with mode 'open'), or a ShadowRootInit object (passed to attachShadow()).
customElement object configuration options
When constructing a custom element, you can define `customElement` as an object within `<svelte:options>` with the following properties: `tag` (string, optional tag name for the custom element), `shadow` (optional, can be 'none', 'open', or a ShadowRootInit object), `props` (optional, object for modifying property behaviors), and `extend` (optional, function to extend the custom element class).
Custom element exported functions availability
Exported functions on a custom element are only available after the element has mounted. If you need to invoke functions before component creation, use the `extend` option.
Custom element shadow DOM update batching
When a custom element written with Svelte is created or updated, the shadow DOM reflects the value in the next tick, not immediately. This batches updates and prevents DOM moves that temporarily detach the element from unmounting the inner component.
Custom element props as DOM properties and attributes
Props are exposed as properties of the DOM element and are readable/writable as attributes. All props must be listed out explicitly; using `let props = $props()` without declaring props in component options means Svelte cannot expose them as properties on the DOM element.
customElement props configuration details
The `props` object configures property behaviors with per-property settings: `attribute` (string, custom attribute name, defaults to lowercase property name), `reflect` (boolean, default false, enables reflecting prop changes back to DOM), and `type` ('String', 'Boolean', 'Number', 'Array', or 'Object', defaults to 'String' for attribute conversion). Not all properties need to be listed; unlisted ones use default settings.
Exposing custom element constructor via static element property
When `customElement: true` compiler option is set, components have a static `element` property containing the custom element constructor. This can be used to define the custom element with `customElements.define()`.
CustomEvent constructor in Svelte 4
The runtime now uses the CustomEvent constructor which may not work in very old browsers. Consider using a polyfill if you need to support very old browsers.
DOM node removal batching in Svelte 4
Removal of DOM nodes is now batched in Svelte 4, which slightly changes the order of removal. This might affect the order of events fired if using MutationObserver on these elements.
classList.toggle usage in Svelte 4
The runtime now uses classList.toggle(name, boolean) which may not work in very old browsers. Consider using a polyfill if you need to support very old browsers.
onMount with async function returns type error in Svelte 4
onMount now shows a type error if you return a function asynchronously from it. This prevents bugs where the cleanup callback would not be called on destroy. Only synchronously returned functions from onMount are called on destroy.
walk is not exported from svelte/compiler
In Svelte 5, svelte/compiler no longer reexports walk from estree-walker. Import it directly from 'estree-walker' if needed.
img src and @html hydration mismatches not repaired
In Svelte 5, hydration mismatches in img src attributes or {@html ...} tags are not automatically repaired. In development, warnings are shown if mismatches occur.
Valid namespace options reduced to html, mathml, svg
In Svelte 5, the namespace compiler option accepts only 'html' (default), 'mathml', and 'svg'. The 'foreign' namespace was removed.
Error and warning codes use underscores instead of dashes
In Svelte 5, error and warning codes use underscores to separate words instead of dashes. For example, foo-bar becomes foo_bar.
Svelte 5 requires modern browsers
Svelte 5 requires a modern browser (not Internet Explorer) due to use of Proxies, ResizeObserver, and other modern APIs. The legacy compiler option no longer exists.
Svelte 5 uses comments for server-side rendering
Svelte 5 uses comments during server-side rendering for robust and efficient client-side hydration. Do not remove comments from HTML output if you intend to hydrate it.
hydration_failed error
Failed to hydrate the application. Hydration is the process of attaching Svelte components to server-rendered HTML.
fork_discarded error
A fork that was already discarded cannot be committed.
lifecycle_legacy_only error: legacy lifecycle in runes mode
Legacy lifecycle functions (like beforeUpdate, afterUpdate, etc.) cannot be used in runes mode. Use $effect instead.
await_invalid error
This error occurs when you call render() with a component containing an await expression without properly handling it. To fix it, either await the result of render, or wrap the await (or the component containing it) in a <svelte:boundary> with a pending snippet.
html property deprecated on server render results
The html property of server render results has been deprecated. Use the body property instead.
lifecycle_function_unavailable error
Certain lifecycle methods such as mount cannot be invoked while running in a server context. Avoid calling them eagerly, for example not during render.
invalid_id_prefix error
The idPrefix option cannot include the string --.
server_context_required error
Certain functions such as hydratable cannot be invoked outside of a render() call, such as at the top level of a module. This error occurs when you try to call render context dependent functions in the wrong context.
unresolved_hydratable warning message and cause
The 'unresolved_hydratable' warning occurs when a hydratable value with a given key was created, but at least part of it was not used during the render. This typically happens when creating a hydratable in the script block of a component and then awaiting the result inside a svelte:boundary with a pending snippet. It can also occur when a hydratable contains multiple promises and some but not all of them have been used.
hydratable unresolved_hydratable example with svelte:boundary
An example that triggers the unresolved_hydratable warning: importing hydratable from 'svelte', importing getUser, creating a hydratable with hydratable('user', getUser) in the script block, and then awaiting the result inside a svelte:boundary with a pending snippet. The fix is to inline the hydratable call inside the boundary so it's not called on the server.
hydratable function overview
hydratable is a function imported from 'svelte' that creates values for hydration. It takes parameters including a key and a function that returns a promise. It is used in conjunction with svelte:boundary and can have pending snippets.