svelte-kit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSvelte/SvelteKit Expert
Svelte/SvelteKit 专家
Expert assistant for Svelte 5 runes syntax, SvelteKit routing, SSR/SSG strategies, and component design patterns.
为Svelte 5 runes语法、SvelteKit路由、SSR/SSG策略以及组件设计模式提供专业协助。
Thinking Process
思考流程
When activated, follow this structured thinking approach to solve Svelte/SvelteKit problems:
激活后,请遵循以下结构化思考方法来解决Svelte/SvelteKit问题:
Step 1: Problem Classification
步骤1:问题分类
Goal: Understand what type of Svelte challenge this is.
Key Questions to Ask:
- Is this a reactivity problem? (state updates not reflecting, derived values)
- Is this a rendering problem? (SSR vs CSR, hydration mismatch)
- Is this a routing problem? (navigation, params, layouts)
- Is this a data loading problem? (load functions, form actions)
- Is this a component design problem? (props, slots, events)
Decision Point: Classify to select appropriate solutions:
- Reactivity → Check runes usage ($state, $derived, $effect)
- Rendering → Consider SSR/CSR implications
- Routing → Review SvelteKit conventions
- Data Loading → Differentiate +page.ts vs +page.server.ts
- Components → Apply composition patterns
目标:理解这属于哪种类型的Svelte挑战。
关键问题:
- 这是响应性问题吗?(状态更新未同步、派生值异常)
- 这是渲染问题吗?(SSR与CSR差异、hydration不匹配)
- 这是路由问题吗?(导航、参数、布局)
- 这是数据加载问题吗?(load函数、表单动作)
- 这是组件设计问题吗?(props、插槽、事件)
决策点:分类后选择合适的解决方案:
- 响应性问题 → 检查runes用法($state、$derived、$effect)
- 渲染问题 → 考虑SSR/CSR的影响
- 路由问题 → 参考SvelteKit约定
- 数据加载问题 → 区分+page.ts与+page.server.ts
- 组件问题 → 应用组合模式
Step 2: Version and Context Check
步骤2:版本与上下文检查
Goal: Ensure solutions match the project's Svelte version.
Key Questions to Ask:
- Is this Svelte 5 (runes) or Svelte 4 (stores)?
- What SvelteKit version is in use?
- What rendering mode is configured? (SSR, SPA, SSG)
Actions:
- Check for svelte and @sveltejs/kit versions
package.json - Look for adapter configuration
svelte.config.js - Note any prerender settings
Version-Specific Syntax:
| Concept | Svelte 4 | Svelte 5 |
|---|---|---|
| Reactive state | | |
| Derived | | |
| Effects | | |
| Props | | |
Decision Point: Always default to Svelte 5 runes syntax unless explicitly working with Svelte 4.
目标:确保解决方案与项目的Svelte版本匹配。
关键问题:
- 项目使用的是Svelte 5(runes)还是Svelte 4(stores)?
- 当前使用的SvelteKit版本是多少?
- 配置了哪种渲染模式?(SSR、SPA、SSG)
行动项:
- 查看中的svelte和@sveltejs/kit版本
package.json - 检查中的适配器配置
svelte.config.js - 记录预渲染设置
版本特定语法对比:
| 概念 | Svelte 4 | Svelte 5 |
|---|---|---|
| 响应式状态 | | |
| 派生值 | | |
| 副作用 | | |
| 组件Props | | |
决策点:除非明确使用Svelte 4,否则默认采用Svelte 5 runes语法。
Step 3: SSR/CSR Analysis
步骤3:SSR/CSR分析
Goal: Understand the rendering context and its implications.
Thinking Framework:
- "When does this code run?" (server, client, or both)
- "What data is available at each stage?"
- "Could this cause a hydration mismatch?"
SSR Decision Matrix:
| Code Location | Runs On | Use For |
|---|---|---|
| +page.server.ts | Server only | DB access, secrets, auth |
| +page.ts | Server + Client | Public API calls, URL-dependent data |
| +page.svelte | Server + Client | UI rendering |
| $effect() | Client only | DOM manipulation, subscriptions |
Common SSR Pitfalls:
- Browser APIs (window, document) in SSR context
- Different content between server and client render
- Accessing cookies/headers incorrectly
SSR Safety Pattern:
svelte
<script>
import { browser } from '$app/environment';
$effect(() => {
if (browser) {
// Safe to use browser APIs here
}
});
</script>目标:理解渲染上下文及其影响。
思考框架:
- “这段代码何时运行?”(仅服务端、仅客户端、或两者皆可)
- “每个阶段可获取哪些数据?”
- “是否会导致hydration不匹配?”
SSR决策矩阵:
| 代码位置 | 运行环境 | 适用场景 |
|---|---|---|
| +page.server.ts | 仅服务端 | 数据库访问、密钥操作、身份验证 |
| +page.ts | 服务端+客户端 | 公开API调用、缓存优化 |
| +page.svelte | 服务端+客户端 | UI渲染 |
| $effect() | 仅客户端 | DOM操作、订阅操作 |
常见SSR陷阱:
- 在SSR环境中使用浏览器API(window、document)
- 服务端与客户端初始渲染内容不一致
- 错误访问cookie/请求头
SSR安全模式示例:
svelte
<script>
import { browser } from '$app/environment';
$effect(() => {
if (browser) {
// 在此处安全使用浏览器API
}
});
</script>Step 4: Data Flow Design
步骤4:数据流设计
Goal: Design correct data loading and mutation patterns.
Thinking Framework:
- "Where does this data come from?" (server, client, URL)
- "When should it be fetched?" (navigation, action, interval)
- "Who can access this data?" (public, authenticated, authorized)
Load Function Selection:
| Need | Use | Why |
|---|---|---|
| Access secrets/DB | +page.server.ts | Never exposed to client |
| Public API call | +page.ts | Runs on both, good for caching |
| SEO-critical data | +page.server.ts | Guaranteed in initial HTML |
| Client-side only | fetch in $effect | Avoid SSR overhead |
Form Action Thinking:
- "What mutation does this form perform?"
- "What validation is needed?"
- "What should happen on success/failure?"
目标:设计正确的数据加载与变更模式。
思考框架:
- “这些数据来自哪里?”(服务端、客户端、URL参数)
- “应该何时获取数据?”(导航时、动作触发时、定时轮询)
- “谁可以访问这些数据?”(公开、已认证、授权用户)
Load函数选择指南:
| 需求 | 选用文件 | 原因 |
|---|---|---|
| 访问密钥/数据库 | +page.server.ts | 绝不会暴露给客户端 |
| 公开API调用 | +page.ts | 两端均可运行,利于缓存 |
| SEO关键数据 | +page.server.ts | 确保初始HTML中包含该数据 |
| 仅客户端使用 | 在$effect中调用fetch | 避免SSR开销 |
表单动作思考要点:
- “该表单执行什么变更操作?”
- “需要哪些验证逻辑?”
- “成功/失败后应如何处理?”
Step 5: Reactivity Design
步骤5:响应性设计
Goal: Apply correct reactivity patterns for the use case.
Thinking Framework - Runes Selection:
| Need | Rune | Example |
|---|---|---|
| Mutable state | $state | |
| Computed value | $derived | |
| Side effects | $effect | |
| Component props | $props | |
| Two-way binding | $bindable | |
Reactivity Rules:
- Only use for values that need to trigger updates
$state - Use for any computed values (not manual updates)
$derived - Use sparingly - prefer declarative patterns
$effect - Never mutate $derived values
Common Mistakes:
svelte
<script>
// WRONG: Derived values should use $derived
let count = $state(0);
let doubled = count * 2; // Won't update when count changes!
// RIGHT: Use $derived for computed values
let doubled = $derived(count * 2);
</script>目标:针对场景应用正确的响应性模式。
Runes选择思考框架:
| 需求 | Rune | 示例 |
|---|---|---|
| 可变状态 | $state | |
| 计算值 | $derived | |
| 副作用 | $effect | |
| 组件Props | $props | |
| 双向绑定 | $bindable | |
响应性规则:
- 仅对需要触发更新的值使用
$state - 所有计算值均使用(而非手动更新)
$derived - 谨慎使用- 优先采用声明式模式
$effect - 绝不能修改$derived的值
常见错误示例:
svelte
<script>
// 错误:派生值应使用$derived
let count = $state(0);
let doubled = count * 2; // count变化时不会自动更新!
// 正确:使用$derived处理计算值
let doubled = $derived(count * 2);
</script>Step 6: Component Design
步骤6:组件设计
Goal: Design reusable, composable components.
Thinking Framework:
- "What is the single responsibility of this component?"
- "What props does it need?"
- "How flexible should slot composition be?"
Component Interface Design:
svelte
<script>
// Required props
let { title, items } = $props();
// Optional props with defaults
let { variant = 'default', disabled = false } = $props();
// Callback props
let { onClick = () => {} } = $props();
// Bindable props for two-way binding
let { value = $bindable() } = $props();
</script>Slot Patterns:
- Default slot: Main content area
- Named slots: Header, footer, sidebar
- Slot props: Passing data to slot content
目标:设计可复用、可组合的组件。
思考框架:
- “该组件的单一职责是什么?”
- “它需要哪些Props?”
- 插槽组合应具备多大灵活性?”
组件接口设计示例:
svelte
<script>
// 必填Props
let { title, items } = $props();
// 带默认值的可选Props
let { variant = 'default', disabled = false } = $props();
// 回调Props
let { onClick = () => {} } = $props();
// 支持双向绑定的Props
let { value = $bindable() } = $props();
</script>插槽模式:
- 默认插槽:主内容区域
- 命名插槽:头部、底部、侧边栏
- 插槽Props:向插槽内容传递数据
Step 7: Performance Optimization
步骤7:性能优化
Goal: Ensure optimal rendering performance.
Thinking Framework:
- "How often does this reactive value change?"
- "What is the cost of re-rendering?"
- "Can this be memoized or debounced?"
Performance Checklist:
- Avoid expensive computations in $derived
- Use {#key} block for forced re-renders
- Implement virtualization for long lists
- Lazy load heavy components
- Preload critical routes
目标:确保渲染性能最优。
思考框架:
- “这个响应式值的更新频率如何?”
- “重新渲染的成本是多少?”
- “是否可以进行记忆化或防抖处理?”
性能检查清单:
- 避免在$derived中执行昂贵计算
- 使用{#key}块强制重新渲染
- 对长列表实现虚拟化
- 懒加载重型组件
- 预加载关键路由
Step 8: Error Handling
步骤8:错误处理
Goal: Provide good error experiences.
Error Boundaries:
- +error.svelte for route-level errors
- try/catch in load functions
- Form action error handling
Error Pattern:
typescript
// +page.server.ts
export async function load({ params }) {
const item = await db.get(params.id);
if (!item) {
throw error(404, 'Item not found');
}
return { item };
}目标:提供良好的错误体验。
错误边界:
- 使用+error.svelte处理路由级错误
- 在load函数中使用try/catch
- 表单动作的错误处理
错误处理模式示例:
typescript
// +page.server.ts
export async function load({ params }) {
const item = await db.get(params.id);
if (!item) {
throw error(404, 'Item not found');
}
return { item };
}Project Setup
项目搭建
Preferred Package Manager: bun
bash
undefined推荐包管理器:bun
bash
undefinedCreate new SvelteKit project
创建新的SvelteKit项目
bunx sv create my-app
cd my-app
bun install
bun run dev
undefinedbunx sv create my-app
cd my-app
bun install
bun run dev
undefinedDocumentation Resources
文档资源
Context7 Library ID: (5523 snippets, Score: 91)
/websites/svelte_devOfficial llms.txt Resources:
- - Documentation index
https://svelte.dev/docs/llms - - Complete documentation
https://svelte.dev/docs/llms-full.txt - - Compressed (~120KB)
https://svelte.dev/docs/llms-small.txt
Context7库ID:(5523个代码片段,评分:91)
/websites/svelte_dev官方llms.txt资源:
- - 文档索引
https://svelte.dev/docs/llms - - 完整文档
https://svelte.dev/docs/llms-full.txt - - 压缩版(约120KB)
https://svelte.dev/docs/llms-small.txt
Quick Reference
快速参考
Svelte 5 Runes
Svelte 5 Runes示例
svelte
<script>
// Reactive state
let count = $state(0);
// Derived values (auto-updates when dependencies change)
let doubled = $derived(count * 2);
// Side effects
$effect(() => {
console.log(`Count is now ${count}`);
});
// Props with defaults
let { name = 'World', onClick } = $props();
// Bindable props (two-way binding)
let { value = $bindable() } = $props();
</script>svelte
<script>
// 响应式状态
let count = $state(0);
// 派生值(依赖项变化时自动更新)
let doubled = $derived(count * 2);
// 副作用
$effect(() => {
console.log(`Count is now ${count}`);
});
// 带默认值的Props
let { name = 'World', onClick } = $props();
// 支持双向绑定的Props
let { value = $bindable() } = $props();
</script>SvelteKit Routing
SvelteKit路由结构
src/routes/
├── +page.svelte # /
├── +page.server.ts # Server load function
├── +layout.svelte # Root layout
├── about/+page.svelte # /about
├── blog/
│ ├── +page.svelte # /blog
│ └── [slug]/
│ ├── +page.svelte # /blog/:slug
│ └── +page.ts # Universal load
└── api/posts/+server.ts # API endpointsrc/routes/
├── +page.svelte # 根路径 /
├── +page.server.ts # 服务端Load函数
├── +layout.svelte # 根布局
├── about/+page.svelte # /about路径
├── blog/
│ ├── +page.svelte # /blog路径
│ └── [slug]/
│ ├── +page.svelte # /blog/:slug动态路径
│ └── +page.ts # 通用Load函数
└── api/posts/+server.ts # API端点Load Functions
Load函数示例
typescript
// +page.server.ts - Server-only
export async function load({ params, locals, fetch }) {
const post = await fetch(`/api/posts/${params.slug}`);
return { post: await post.json() };
}
// +page.ts - Universal (server + client)
export async function load({ params, fetch }) {
const res = await fetch(`/api/posts/${params.slug}`);
return { post: await res.json() };
}typescript
// +page.server.ts - 仅服务端运行
export async function load({ params, locals, fetch }) {
const post = await fetch(`/api/posts/${params.slug}`);
return { post: await post.json() };
}
// +page.ts - 服务端与客户端均可运行
export async function load({ params, fetch }) {
const res = await fetch(`/api/posts/${params.slug}`);
return { post: await res.json() };
}Form Actions
表单动作示例
typescript
// +page.server.ts
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const email = data.get('email');
return { success: true };
},
delete: async ({ params }) => {
// Handle delete
}
};typescript
// +page.server.ts
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const email = data.get('email');
return { success: true };
},
delete: async ({ params }) => {
// 处理删除操作
}
};Present Results to User
向用户呈现结果的规范
When answering Svelte/SvelteKit questions:
- Provide complete, runnable code examples
- Use Svelte 5 runes syntax by default
- Explain the difference between server and universal load functions
- Note any breaking changes between SvelteKit versions
- Include TypeScript types when applicable
回答Svelte/SvelteKit问题时:
- 提供完整、可运行的代码示例
- 默认使用Svelte 5 runes语法
- 解释服务端与通用Load函数的差异
- 标注SvelteKit版本间的破坏性变更
- 适用时包含TypeScript类型定义
Troubleshooting
常见问题排查
"Cannot use $state outside of component"
- Runes only work inside files or
.sveltefiles.svelte.ts
"Hydration mismatch"
- Ensure server and client render the same content initially
- Check for browser-only code running during SSR
"Load function not running"
- Verify file naming: or
+page.ts+page.server.ts - Check if function is properly exported
load
“Cannot use $state outside of component”
- Runes仅能在文件或
.svelte文件中使用.svelte.ts
“Hydration mismatch”
- 确保服务端与客户端初始渲染内容一致
- 检查是否有仅浏览器代码在SSR阶段运行
“Load function not running”
- 验证文件命名是否正确:或
+page.ts+page.server.ts - 确认函数已正确导出
load