mcpField
S
sveltekit

sveltekit

github.com/joshuadavidthomas开发6043 次安装15 周前更新
代码仓库

关于 sveltekit

面向开发者和编码 Agent 的 SvelteKit 应用级开发指南,聚焦服务端边界、数据归属、安全与渐进增强。

主要功能

  1. 01路由与运行时边界
  2. 02服务端数据加载
  3. 03原生表单与 actions
  4. 04明确的身份验证检查
  5. 05SSR 与水合指导

适用场景

  1. 01选择合适的 SvelteKit 路由文件
  2. 02检查服务端数据与机密的流向
  3. 03构建无 JavaScript 也可用的表单
  4. 04检查页面和端点的身份验证

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/joshuadavidthomas/agent-skills --skill sveltekit

安装后在 Claude Code 中输入/sveltekit确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
references/
auth.md
better-auth.md
cloudflare.md
errors-and-redirects.md
file-naming.md
form-actions.md
forms-validation.md
layout-patterns.md
load-functions.md
remote-functions.md
serialization.md
ssr-hydration.md

详细介绍

在 SvelteKit 中思考

SvelteKit 不只是带有文件夹的 Svelte。它是一套应用边界系统:路由文件决定数据的归属,服务端代码留在服务端,表单提交支持渐进式增强,重定向和错误都是控制流的一部分。

核心失败模式:把 SvelteKit 写成带有零散服务端辅助代码的客户端 SPA。从组件中获取服务端负责的数据。把身份验证藏在钩子中,并假设布局能保护端点。从 load 返回类实例。调用 redirect() 却不抛出。明明原生表单配合 actions 就能实现,却构建只能依赖 JavaScript 的表单。这些做法在 SSR、渐进式增强、缓存或安全边界变得重要之前都行得通。

将此技能用于应用级 SvelteKit 决策。组件内部细节请使用 svelte5:runes、snippets、组件 props、DOM 事件、无障碍性、过渡和组件状态。

SvelteKit 的思考方式

路由负责应用边界

1. 文件名决定行为。 +page.svelte、+layout.server.ts、+page.server.ts 和 +server.ts 并非只是组织代码的细节;它们决定代码在哪里运行,以及谁可以调用它。参见 references/file-naming.md。

2. 路由组组织策略,而非 URL。 (app) 和 (auth) 用于划分布局、身份验证和数据边界,而不会改变路径。将受保护的路由放在受保护的布局下;登录和注册页面则放在该组之外。参见 references/layout-patterns.md。

3. 布局保护页面,不保护端点。 受保护的 +layout.server.ts 会限制对子页面的访问,但不会保护同级或子级的 +server.ts 端点;每个端点都必须自行执行身份验证。参见 references/auth.md。

数据流应体现归属

4. 服务端负责的数据应在服务端加载。 数据库查询、密钥、私有 API 和基于会话的数据应放在 +page.server.ts / +layout.server.ts 中,而不是组件的 onMount 或浏览器端 fetch 中。参见 references/load-functions.md。

// ❌ component fetches server-owned data after mount
onMount(async () => { user = await (await fetch('/api/me')).json(); });

// ✅ +page.server.ts — server owns it, page receives data
export const load = async ({ locals }) => ({ user: await locals.getUser() });

5. 通用 load 只用于通用任务。 仅当代码能在浏览器和服务端安全运行时,才使用 +page.ts。如果代码需要密钥或受信任的身份验证,它就不是通用代码。

6. Load 返回数据,而非行为。 服务端 load 应返回可序列化的数据。不要返回类实例、函数、数据库句柄或依赖对象身份的复杂对象。参见 references/serialization.md。

7. 重定向和错误是通过抛出实现的控制流。 在 SvelteKit 2 中,redirect() 和 error() 会返回对象;要抛出这些对象。只调用而不抛出是 bug。参见 references/errors-and-redirects.md。

// ❌ bare call — execution continues, the redirect never happens
if (!locals.user) redirect(303, '/login');

// ✅ throw it
if (!locals.user) throw redirect(303, '/login');
表单优先考虑服务端

8. 表单 actions 是默认的变更边界。 如果用户提交的是表单格式的数据,应优先使用原生表单和 +page.server.ts action,而不是另行设计仅客户端的变更路径。参见 references/form-actions.md。

9. 渐进式增强是增强,而非前提。 表单应能在没有 JavaScript 的情况下正常工作;use:enhance 用于改善等待状态、焦点、失效处理和用户体验。它不应成为变更操作唯一的生效方式。

10. 在边界处进行验证。 在服务端验证,使用 fail 返回字段形式的错误,并让组件显示这些错误。如果项目使用 shadcn-svelte 或 bits-ui,应通过 Field.* 组件呈现这些错误,而不是使用临时拼凑的封装。参见 references/forms-validation.md。

// +page.server.ts action — validate server-side, return field-shaped errors
if (!email) return fail(400, { errors: { email: 'Email is required' } });
认证明确而简单

11. Hook 填充上下文;路由执行策略。 hooks.server.ts 应解析会话并填充 locals。布局/服务端加载函数和端点决定允许执行的操作。如果基础设施缺失,不要静默跳过认证。参见 references/auth.md。

12. Cookie 和 locals 是请求状态。 将它们视为每个请求独有的服务端数据。不要将其镜像到全局模块状态,也不要信任客户端副本来进行授权。

13. API 端点有自己的安全边界。 在每个 +server.ts 中检查方法、认证、授权、输入验证和响应结构。页面布局与直接 HTTP 调用无关。

远程函数仍是服务端边界

14. 远程函数不会取消验证。 command、query 和 form 仍会跨越客户端/服务端边界。验证参数、检查认证,并返回可序列化数据。远程函数取决于版本/功能标志;在推荐使用前,确认项目已选择启用。参见 references/remote-functions.md。

15. 根据意图选择远程原语。 使用 query 进行重复读取,使用 command 执行命令式变更,使用 form 处理表单形式的提交。没有充分理由时,不要用远程函数绕过 SvelteKit 的常规页面/表单模型。

SSR 是默认环境

16. 浏览器 API 需有条件地使用。 SSR 期间不存在 window、document、localStorage、媒体 API 和 DOM 测量功能。谨慎使用组件副作用、browser 或仅限客户端的边界。参见 references/ssr-hydration.md。

17. Hydration 不匹配是设计反馈。 如果服务端和客户端渲染的初始标记不同,请修复数据边界,或有意延迟仅限浏览器的渲染。不要用随机客户端检查来掩盖不匹配。

处理变更

由外向内逐步处理——先确定每个边界,再继续下一步:

  1. 运行时与路由边界。 确定有哪些 + 文件,以及每个文件在哪里运行(服务端 / 通用 / 端点)。→ 确认机密信息和数据库访问不会进入 +page.ts 或组件。
  2. 数据归属。 服务端拥有的数据放在 +*.server.ts 中;load 返回可序列化数据。→ 确认没有类实例或函数跨越 load。
  3. 变更。 表单形式的数据通过原生表单和 +page.server.ts action 处理。→ 添加 use:enhance 前,确认禁用 JavaScript 时仍可正常工作。
  4. 认证。 Hook 填充 locals;每个页面加载函数和每个 +server.ts 都执行策略并默认拒绝。→ 对每个端点测试直接 HTTP 调用,而不只是测试页面。
  5. SSR。 对浏览器 API 进行门控;初始标记保持一致。→ 关闭 JS 进行渲染,并确认没有 hydration 不匹配。
  6. 发现问题时的处理顺序: 先处理安全性/正确性问题(认证、序列化、抛出控制流),再处理渐进增强方面的缺失,最后处理易用性问题。
表单 action 流程
  1. 使用包含真实输入项和标签的原生 <form method="POST">。
  2. +page.server.ts 中的 actions 在服务端验证;输入无效时执行 return fail(400, { errors }),成功时执行 throw redirect(...)。
  3. 组件渲染 form?.errors(如果项目使用 shadcn-svelte / bits-ui,则通过 Field.* 渲染)。
  4. 最后添加 use:enhance——仅用于待处理状态、焦点和失效处理。
  5. 检查: 禁用 JavaScript 后提交;变更仍应生效。
保护路由
  1. 将受保护路由放在包含受保护 +layout.server.ts 的路由组下;登录/注册页面放在该组之外。
  2. hooks.server.ts 将会话解析到 locals。
  3. 受保护的 +layout.server.ts 对未认证用户执行 throw redirect(...)。
  4. 保护范围内的每个 +server.ts 都要自行重新检查认证。
  5. 检查: 没有会话时,直接请求受保护端点会被拒绝。

常见错误(Agent 失效模式)

  • 在 onMount 中获取服务器拥有的数据 → 使用服务器 load。
  • 使用 $effect 将查询/页面状态推送到导航中 → 在控件的事件处理程序或表单提交中更新 URL;需要时从 data 派生显示值。
  • 使用通用 load 处理密钥 → 移至 +page.server.ts 或 +layout.server.ts。
  • 从 load 返回类/函数 → 返回可序列化的普通数据。
  • 调用 redirect() / error() 时不加 throw → 对它们使用 throw。
  • 通过布局保护端点 → 在每个 +server.ts 中检查身份验证。
  • 只在 hooks 中处理身份验证策略 → hooks 填充 locals;路由负责执行策略。
  • 数据库/会话基础设施缺失时静默跳过身份验证 → 默认拒绝访问。
  • 将登录页面放在受保护的路由组中 → 将身份验证页面置于受保护布局之外。
  • 构建仅依赖 JS 的表单 → 使用原生表单 + actions + 渐进增强。
  • 信任客户端验证 → 在服务器边界进行验证。
  • 使用原始包装器渲染 shadcn-svelte 验证 → 在组件中使用 Field.Field、Field.Label 和 Field.Error。
  • 使用远程函数却不进行身份验证/验证 → 将它们视为服务器端点。
  • 在 SSR 期间使用浏览器 API → 使用 effects/仅浏览器逻辑进行限制。
  • 将 svelte5 组件建议用于应用数据流 → 加载 SvelteKit 参考文档。

快速参考

常见问题SvelteKit 默认做法参考
不确定选择哪个路由文件根据运行时和边界选择file-naming
受保护的页面组在 +layout.server.ts 中检查身份验证auth
受保护的端点在 +server.ts 中检查身份验证auth
浏览器代码中的数据库/密钥server load/action/endpointload-functions
通过 $effect 更新查询/页面控件事件处理程序或表单提交load-functions
表单形式的变更操作表单 actionform-actions
字段验证错误fail(400, { errors })forms-validation
裸调用 redirect() 或 error()throw redirect(...) / throw error(...)errors-and-redirects
从 load 返回复杂对象可序列化的普通数据serialization
SSR 中仅客户端可用的 APIeffect/浏览器环境保护ssr-hydration
客户端重复读取服务器数据适用远程函数时使用 query()remote-functions
从客户端命令式修改服务器数据使用带验证/身份验证的 command()remote-functions
组件 API/runes 问题使用 svelte5svelte5

参考索引

文件命名 · 布局模式 · Load 函数 · 表单 Actions · 表单验证 · 身份验证 · 错误/重定向 · 序列化 · SSR/Hydration · 远程函数 · Better Auth · Cloudflare

评论

支持 Markdown