Files
theater-ziefen-website/.agents/skills/sanity-best-practices/references/svelte.md
T
johannes.gasser 57af0b8386
Build and Deploy / build-and-deploy (push) Successful in 2m53s
add skills
2026-05-18 08:39:42 +02:00

156 lines
3.9 KiB
Markdown

---
title: "SvelteKit & Sanity Integration Rules"
description: Integration guide for SvelteKit with Sanity, including @sanity/svelte-loader, Visual Editing, and Preview Mode.
---
# SvelteKit & Sanity Integration Rules
## 1. Setup & Configuration
### Installation
```bash
npm install @sanity/svelte-loader @sanity/client @sanity/visual-editing
```
### Client Configuration (`src/lib/sanity.ts`)
Define the client with `stega` enabled for the studio URL.
```typescript
import { createClient } from '@sanity/client'
import { PUBLIC_SANITY_PROJECT_ID, PUBLIC_SANITY_DATASET, PUBLIC_SANITY_API_VERSION, PUBLIC_SANITY_STUDIO_URL } from '$env/static/public'
export const client = createClient({
projectId: PUBLIC_SANITY_PROJECT_ID,
dataset: PUBLIC_SANITY_DATASET,
apiVersion: PUBLIC_SANITY_API_VERSION,
useCdn: true,
stega: {
studioUrl: PUBLIC_SANITY_STUDIO_URL,
},
})
```
### Server Client (`src/lib/server/sanity.ts`)
Use the read token for fetching preview content.
```typescript
import { SANITY_API_READ_TOKEN } from '$env/static/private'
import { client } from '$lib/sanity'
export const serverClient = client.withConfig({
token: SANITY_API_READ_TOKEN,
stega: true, // Optional: enable stega on server too if needed
})
```
## 2. Hooks & Request Handler (Critical)
You **must** configure `createRequestHandler` in `src/hooks.server.ts` to handle preview sessions and inject `loadQuery` into locals.
```typescript
// src/hooks.server.ts
import { createRequestHandler, setServerClient } from '@sanity/svelte-loader'
import { serverClient } from '$lib/server/sanity'
setServerClient(serverClient)
export const handle = createRequestHandler()
```
**Update `app.d.ts` types:**
```typescript
import type { LoaderLocals } from '@sanity/svelte-loader'
declare global {
namespace App {
interface Locals extends LoaderLocals {}
}
}
```
## 3. Preview State Propagation
Pass the preview state from the server to the client via the root layout.
**Server Layout (`src/routes/+layout.server.ts`):**
```typescript
import type { LayoutServerLoad } from './$types'
export const load: LayoutServerLoad = ({ locals: { preview } }) => {
return { preview }
}
```
**Client Layout (`src/routes/+layout.ts`):**
```typescript
import { setPreviewing } from '@sanity/svelte-loader'
import type { LayoutLoad } from './$types'
export const load: LayoutLoad = ({ data: { preview } }) => {
setPreviewing(preview)
}
```
## 4. Data Fetching (Loaders)
Use `locals.loadQuery` in your page server loaders.
```typescript
// src/routes/[slug]/+page.server.ts
import type { PageServerLoad } from './$types'
export const load: PageServerLoad = async ({ locals: { loadQuery }, params }) => {
const initial = await loadQuery(QUERY, params)
return { initial }
}
```
## 5. Real-time Preview & Visual Editing
### Component Usage (`useQuery`)
Use `useQuery` in your Svelte component to handle real-time updates.
```svelte
<!-- src/routes/[slug]/+page.svelte -->
<script lang="ts">
import { useQuery } from '@sanity/svelte-loader'
import type { PageData } from './$types'
export let data: PageData
const { initial } = data
// Hydrate with initial data
const query = useQuery(initial)
// Reactive data access
$: ({ data: post, loading, encodeDataAttribute } = $query)
</script>
{#if !loading && post}
<!-- Use encodeDataAttribute for overlays -->
<h1 data-sanity={encodeDataAttribute('title')}>
{post.title}
</h1>
{/if}
```
### Enable Visual Editing (`+layout.svelte`)
Enable Visual Editing and Live Mode in your root layout.
```svelte
<script lang="ts">
import { useLiveMode } from '@sanity/svelte-loader'
import { enableVisualEditing } from '@sanity/visual-editing'
import { PUBLIC_SANITY_STUDIO_URL } from '$env/static/public'
import { onMount } from 'svelte'
onMount(() => enableVisualEditing())
onMount(() => useLiveMode({
studioUrl: PUBLIC_SANITY_STUDIO_URL
}))
</script>
<slot />
```