vike-svelte
v1.1.0
Published
<p align="center"> <a href="https://vike.dev"> <img src="./logo.svg" width="120" alt="vike-svelte logo" /> </a> </p>
Readme
Svelte renderer integration for Vike. It provides the Vike V1 renderer hooks, Svelte server rendering, client hydration, client-side routing, layout configuration, and a small client-only component for browser-only UI.
This package targets Svelte 5, Vike 0.4, and Vite 5 or newer.
✨ Why This Package
- Use Vike's file-based routing and data lifecycle with Svelte components.
- Render pages on the server with
svelte/server, then hydrate on the client. - Configure layouts, document metadata, SSR mode, and client-only islands through Vike config.
- Keep the package small while Svelte parity work continues in public GitHub issues.
📦 Installation
pnpm add vike-svelte vike svelte viteUse vike-svelte/config in your Vike config:
// pages/+config.js
import vikeSvelte from 'vike-svelte/config'
import Layout from './Layout.svelte'
export default {
extends: [vikeSvelte],
Layout,
title: 'My Svelte app',
description: 'A Vike app rendered with Svelte'
}🚀 Basic Page
<!-- pages/index/+Page.svelte -->
<h1>Vike + Svelte</h1>
<p>This page is server-rendered and hydrated by vike-svelte.</p>Use Svelte's native head support for component-local metadata:
<svelte:head>
<title>Dashboard</title>
<meta name="description" content="Dashboard page" />
</svelte:head>🧭 Reading Page Context
vike-svelte exposes public hooks for reading Vike data from Svelte components.
<script>
import { usePageContext } from 'vike-svelte/usePageContext'
const pageContext = usePageContext()
</script>
<p>{pageContext.urlPathname}</p>Use useData() when a page only needs pageContext.data.
<script>
import { useData } from 'vike-svelte/useData'
const data = useData()
</script>🏷️ Dynamic Page Config
Use useConfig() when a Svelte component needs to set Vike-backed document metadata during SSR and client navigation.
<script>
import { useConfig } from 'vike-svelte/useConfig'
useConfig({
title: 'Dashboard',
description: 'Team dashboard',
lang: 'en',
viewport: 'width=device-width, initial-scale=1',
htmlAttributes: {
'data-section': 'dashboard'
}
})
</script>For declarative component usage, import vike-svelte/Config.
<script>
import Config from 'vike-svelte/Config'
</script>
<Config title="Dashboard" description="Team dashboard" />Use Svelte's <svelte:head> for component-local tags that do not need to flow through Vike config. Use useConfig() or <Config /> for title, description, language, favicon, viewport, and document attribute values that should be visible to the renderer.
🧩 Client-Only Components
Use vike-svelte/clientOnly when a component depends on browser APIs and should not render during SSR.
<script>
import ClientOnly from 'vike-svelte/clientOnly'
import BrowserChart from './BrowserChart.svelte'
import ChartFallback from './ChartFallback.svelte'
</script>
<ClientOnly
target={BrowserChart}
componentProps={{ theme: 'dark' }}
fallback={ChartFallback}
/>The current API uses target, componentProps, and fallback. Client-only parity with vike-react is tracked in issue #22.
On the server, ClientOnly renders only the fallback component. If no fallback is provided, it renders nothing. The browser-only target component is mounted on the client, which avoids rendering browser API usage during SSR. vike-svelte does not currently implement React-style static replacement or compile-time tree-shaking for the target component.
⚙️ Supported Config
The renderer currently declares these Vike config entries:
| Config | Status |
| --- | --- |
| Layout | Supported with cumulative composition |
| Head | Declared, dynamic head/config API tracked in #18 |
| Wrapper | Supported with cumulative composition |
| title | Supported through renderer title output |
| description | Supported through renderer description output |
| favicon | Supported through renderer favicon output |
| lang | Supported through <html lang> |
| ssr | Supported through the renderer config effect |
| stream | Not supported yet; the renderer returns full Svelte render() output. See #21 |
| viewport | Supported through renderer and runtime config output |
| htmlAttributes | Supported on <html> through renderer and runtime config output |
| bodyAttributes | Supported on <body> through renderer and runtime config output |
| onAfterRenderClient | Declared for client runtime hooks |
Example:
export default {
viewport: 'width=device-width, initial-scale=1',
htmlAttributes: {
'data-renderer': 'vike-svelte'
},
bodyAttributes: {
'data-app-shell': 'default'
}
}Wrapper entries render outside Layout entries. Cumulative entries compose in their resolved config order, then the page component renders at the center of the stack.
🧱 Parity With vike-react
vike-svelte is not yet feature-equivalent with vike-react. The current work is split into executable issues:
| Area | Issue |
| --- | --- |
| Public runtime hooks | usePageContext() and useData() are supported. See #17 |
| Dynamic head and config APIs | useConfig() and <Config /> are supported. See #18 |
| Renderer output for declared config | viewport, htmlAttributes, and bodyAttributes are supported. See #19 |
| Cumulative Layout and Wrapper behavior | Cumulative composition is supported. See #20 |
| Streaming support decision | Streaming is intentionally deferred. See #21 |
| Client-only static removal behavior | Runtime fallback behavior is documented; static replacement is not supported. See #22 |
| Parity matrix and ecosystem examples | #23 |
The original audit is available in issue #16.
For a fuller feature matrix and Svelte ecosystem plan, see docs/parity.md.
🧪 Examples
Run an example locally:
cd examples/minimal
pnpm install
pnpm run dev🛠️ Development
pnpm install
pnpm run buildThe package source lives in packages/vike-svelte. Examples use the local package through the workspace override in the root package.json.
