Skip to main content

sveltekit-advanced

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

インストールへ移動

ソース情報

リポジトリ
full-stack-skills/svelte-skills
ソースの最終更新活動
2026年9月11日 13:43
検出された SKILL.md の言語
英語
スター
3
フォーク
2

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
22 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
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?**
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る