Skip to main content

sveltekit-advanced

SvelteKit 高级功能指南 - 状态管理、远程函数(Remote Functions)、环境变量、Hooks、错误处理、链接选项、Service Workers、服务端模块、快照(快照/Shallow Routing)、$app/* 模块、$lib、$service-worker。

Zur Installation springen

Quellinformationen

Repository
full-stack-skills/svelte-skills
Letzte Quellaktivität
11. September 2026 um 13:43
Erkannte Sprache von SKILL.md
Englisch
Sterne
3
Forks
2

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
22 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
sveltekit-advanced
license
Apache-2.0
description
SvelteKit 高级功能指南 - 状态管理、远程函数(Remote Functions)、环境变量、Hooks、错误处理、链接选项、Service Workers、服务端模块、快照(快照/Shallow Routing)、$app/* 模块、$lib、$service-worker。
# SvelteKit Advanced Advanced SvelteKit features reference. Covers state management across server/client, the remote functions API, env vars (legacy and explicit), hooks (server/shared/universal), error handling, link options, service workers, server-only modules, snapshots, shallow routing, and the `$app/*` modules. Source: official SvelteKit llms.txt documentation. ## When to use this skill Use this skill when you need to: - Choose where state lives (server context, URL, snapshot, store). - Build type-safe client/server RPC with `query`/`form`/`command`/`prerender`. - Read env vars safely (private vs public, static vs dynamic). - Customize request handling via hooks (`handle`, `handleFetch`, `handleError`, `handleValidationError`, `reroute`, `transport`, `init`). - Throw expected/unexpected errors, customize the fallback error page, type error shape via `App.Error`. - Configure link behavior with `data-sveltekit-*` attributes. - Add a service worker for offline / precaching. - Prevent secret leak via `.server.*` or `$lib/server/`. - Persist ephemeral DOM state with snapshots or route history entries with shallow routing. - Use the `$app/*` modules (`forms`, `navigation`, `state`, `paths`, `server`, `environment`, `types`). Do NOT use this skill for routing, form actions (legacy), load, basic setup, adapters configuration beyond env vars, or CSS/styling. ## Critical sections ### 1. State management - **No shared server state** — module-level variables (`let user;`) leak across requests. Authenticate via cookies, persist to DB. - **Pure `load` functions** — no side effects (no global stores). Return data instead. - **Context for per-request state** — `setContext('user', () => data.user)` (pass a function so reactivity crosses boundaries). Reading context updated during SSR in a child does NOT propagate to the parent (it has already rendered). - **Component state is preserved across nav** — `const` derived from `data` only computes once. Use `$derived(...)` for values that should recompute when data changes. - **URL state** — search params for filters/sort; survives reload, affects SSR. - **Snapshots** — disposable UI state (e.g., "is accordion open?") bound to history entry. ### 2. Remote functions (since 2.27, experimental) Opt in via `svelte.config.js`: ```js kit: { experimental: { remoteFunctions: true } }, compilerOptions: { experimental: { async: true } } ``` Flavors exported from `*.remote.js`: | Flavor | Purpose | Key features | |---|---|---| | `query` | Read dynamic server data | Dedup, `refresh()`, `loading`/`error`/`current` | | `query.batch` | Batch n+1 queries in one call | Returns `(input, idx) => Output` | | `query.live` | Real-time async iterable | `connected`, `reconnect()`; first value serialized for SSR | | `form` | Progressive-enhanced `<form>` | `<form {...createPost}>`, `createPost.fields.x.as('text')`, `validate()`, `enhance()`, `for(id)`, `preflight(schema)` | | `command` | Imperative mutation from event handlers | Cannot be called during render | | `prerender` | Build-time data | `inputs`, `dynamic: true` | - Validate with any Standard Schema (Zod/Valibot). - Args/returns serialized via devalue. - `getRequestEvent()` works inside remote functions for cookies. - `redirect(...)` allowed in `query`/`form`/`prerender`, NOT in `command`. - Single-flight mutations: `getPosts().refresh()` or `getPost(id).set(...)` in server handler; `requested(getPosts, 1).refreshAll()` for client-requested refreshes (limit is DoS protection). ### 3. Environment variables **Legacy `$env/*` (default before SvelteKit 2.63):** | Module | Scope | Timing | |---|---|---| | `$env/dynamic/private` | Server only | Runtime (`process.env`-like) | | `$env/dynamic/public` | Public (`PUBLIC_*`) | Runtime | | `$env/static/private` | Server only | Build time (inlined) | | `$env/static/public` | Public | Build time (inlined) | **Explicit env vars (opt-in, default in v3):** Enable in `svelte.config.js`: `kit.experimental.explicitEnvironmentVariables = true`. Then create `src/env.ts`: ```ts import { defineEnvVars } from '@sveltejs/kit/hooks'; import * as v from 'valibot'; import { building } from '$app/env'; export const variables = defineEnvVars({ API_KEY: {}, // private GOOGLE_ANALYTICS_ID: { public: true }, // public SHOW_DEBUG_OVERLAY: { public: true, static: true }, // inlined, dead-code-eliminated SECRET: { schema: building ? v.optional(v.string()) : v.string() }, CACHE_TTL_SECONDS: { description: 'How long...' } }); ``` Import from `$app/env/private` or `$app/env/public`. `$app/environment` is renamed to `$app/env`. ### 4. Hooks Three optional files: `src/hooks.server.js`, `src/hooks.client.js`, `src/hooks.js`. **Server (`hooks.server.js`):** - `handle({ event, resolve })` — runs on every request; return Response or call `resolve(event, opts)`. `resolve` opts: `transformPageChunk`, `filterSerializedResponseHeaders`, `preload`. Use `sequence(...)` for multiple. - `handleFetch({ request, fetch, event })` — rewrite cross-origin requests to internal APIs; cookie forwarding for sibling subdomains. - `handleValidationError({ event, issues })` — customize 400 response for bad remote function args. **Shared (`hooks.server.js` AND `hooks.client.js`):** - `handleError({ error, event, status, message })` — for unexpected errors only. Return `{ message, ... }` -> becomes `page.error`. Must never throw. Server type: `HandleServerError`; client type: `HandleClientError`; client `event` is `NavigationEvent`. - `init()` — runs once at startup; useful for DB connections. **Universal (`hooks.js`):** - `reroute({ url, fetch })` — translate URL to a different route (e.g., i18n). Pure/idempotent. Can be async since 2.18. - `transport` — custom encoders/decoders for types crossing the server/client boundary (e.g., `Vector`). ### 5. Errors - **Expected errors** — `error(404, 'Not found')` (or `error(404, { message, code })`) from `@sveltejs/kit`. Renders nearest `+error.svelte`, sets status code. `page.error` = the object passed. - **Unexpected errors** — any other exception. Not exposed (generic `Internal Error`); routed through `handleError`. - **Rendering errors** — opt in via `experimental.handleRenderingErrors`. Error passed directly to `+error.svelte` as `error` prop (not via `page.error`). - **Responses** — custom `src/error.html` with `%sveltekit.status%` and `%sveltekit.error.message%`. Errors in root `+layout.server.js` use fallback page (root contains `+error.svelte`). - **Type safety** — declare `App.Error` interface in `src/app.d.ts`: ```ts declare global { namespace App { interface Error { message: string; code: string; id: string; } } } ``` ### 6. Link options `data-sveltekit-*` attributes on `<a>` (or parent). Also apply to `<form method="GET">`. | Attribute | Values | Effect | |---|---|---| | `preload-data` | `hover` (default), `tap` | Preload `load` data on hover/tap | | `preload-code` | `eager`, `viewport`, `hover`, `tap` | Preload route code only | | `reload` | boolean | Force full-page nav (also `rel="external"`) | | `replacestate` | boolean | Replace history entry instead of push | | `keepfocus` | boolean | Keep focus on the same element after nav | | `noscroll` | boolean | Disable scroll-to-top after nav | Disable in subtree with `data-sveltekit-preload-data="false"`. Respects `navigator.connection.saveData`. ### 7. Service workers Place `src/service-worker.js` (or `src/service-worker/index.js`) — bundled and auto-registered. Disable via config to register manually. Available from `$service-worker`: `base`, `build`, `files`, `prerendered`, `version`. Standard pattern: cache `build + files` on install, network-first with cache fallback on fetch. Skip responses with `Cache-Control: no-store` (live queries). `build`/`prerendered` are empty arrays in dev. ### 8. Server-only modules - `$env/static/private` and `$env/dynamic/private` — server-only. - `$app/server` — server-only. - Your modules — add `.server.js` suffix OR place under `$lib/server/`. Illegal imports from browser code error at build. Use `import type` for type-only. Detection is disabled in tests (`process.env.TEST === 'true'`). ### 9. Snapshots & shallow routing **Snapshots** — export `snapshot = { capture, restore }` from `+page.svelte` or `+layout.svelte`. Captured to `sessionStorage` before page updates; restored on history nav. Must be JSON-serializable. Don't return huge objects. **Shallow routing** — `pushState(url, state)` / `replaceState(url, state)` create history entries without navigating. Read via `page.state`. Use `preloadData(href)` to grab `load` data, then `pushState(href, { selected: result.data })` to render another `+page.svelte` inside a modal. `page.state` is always `{}` on first SSR and during first paint. ## Quick Fixes | Symptom | Fix | |---|---| | User data leaks between requests | Don't use module-level vars; use cookies + DB | | `load` data not updating on nav | Use `$derived(...)` not `const` for values derived from `data` | | `Cannot import $lib/server/...` | Move shared types to `import type` | | Live query stream stops | Reconnect with `.reconnect()`; don't cache `no-store` responses in SW | | `error(404, ...)` shows blank page | Add `+error.svelte` nearest to the route | | Server-only env leaked to client | Use `$env/static/private` or `.server` naming | | Validation 400 generic message | Implement `handleValidationError` | | Component state lost on nav | Wrap with `{#key page.url.pathname}<X/>{/key}` to force remount | ## Gotchas - **`load` must be pure** — no global store writes. Return the data instead. - **Context updates during SSR don't propagate up** — pass state down to avoid flash on hydration. - **`query.batch`** returns a single function that maps individual inputs to outputs; not a direct array of results. - **`query.live` on SSR** returns ONLY the first yielded value then closes. - **`command` cannot be called during render** — invoke from event handlers. - **`requested` requires a `limit`** — DoS protection; pass `Infinity` only if explicitly safe. - **`error()` no longer needs `throw`** in SvelteKit 2.x. - **`page.state` is `{}` on SSR and first paint** — don't rely on it for critical render. - **`reroute` must be pure/idempotent** — its result is cached per URL on the client. - **Service worker `build`/`prerendered` empty in dev** — test in production build. - **Cookie forwarding for sibling subdomains requires manual `handleFetch`** — SvelteKit can't tell which parent-domain cookie belongs to which subdomain. - **`handleError` must not throw** — wrap risky work in try/catch. ## FAQ **Q: $app/state vs $app/stores?** A: `$app/state` (since 2.12) is rune-based and reactive. `$app/stores` is the legacy store-based version. Use `$app/state` with Svelte 5. **Q: query vs prerender?** A: `query` for dynamic data; `prerender` for build-time-frozen data that can be served from a CDN. `query` cannot be used on a fully prerendered page. **Q: form vs command?** A: `form` is progressive-enhanced — works without JS, spreads onto `<form>`. `command` is JS-only, called from event handlers. Prefer `form`. **Q: $env/dynamic vs $env/static?** A: `dynamic` reads at runtime (e.g., `process.env`); `static` inlined at build time (enables dead-code elimination). Use `static` for build-time-known values. **Q: $env/static/private vs $env/dynamic/private?** A: Same access restriction; difference is when the value is read. Static gives DCE; dynamic allows runtime override (e.g., `MY_FLAG=1 npm run dev`). **Q: Can I use $lib/server modules from +page.svelte?** A: No — server-only modules cannot be imported by client code, transitively. SvelteKit errors at build. **Q: How do I keep focus on a search input after submit?** A: Add `data-sveltekit-keepfocus` to the `<form>`. **Q: How do I throw a 404 from a load?**
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen