关于 sveltekit-overview
面向使用 Svelte 构建 Web 应用的开发者的 SvelteKit 技能,涵盖项目创建、路由、渲染模式、服务端端点与部署适配器。
主要功能
- 01使用 sv CLI 创建项目
- 02SSR、SSG、SPA 与 MPA 模式
- 03基于文件系统的路由
- 04服务端端点与 Web API
- 05路由类型与项目结构
- 06适配器和部署说明
适用场景
- 01启动 SvelteKit 应用
- 02为网站选择渲染模式
- 03创建路由和 HTTP 端点
- 04了解路由文件与生成的类型
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ full-stack-skills/ svelte-skills --skill sveltekit-overview安装后在 Claude Code 中输入/sveltekit-overview确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlexamples/project-creation.mdproject-structure.mdproject-types.mdREADME.mdrouting-pages.mdrouting-server.mdsvelte-config.mdweb-standards.mdreferences/project-structure-reference.mdproject-types-reference.mdREADME.mdrouting-reference.mdweb-standards-reference.md详细介绍
SvelteKit 概览
SvelteKit 是 Svelte 的官方应用框架。它提供路由、构建流水线、服务器运行时和部署适配器,让你可以基于单个 SvelteKit 代码库交付 Web 应用(SSR、SSG、SPA、MPA、移动端、桌面端、嵌入式)。
何时使用此技能
在以下情况下使用此技能:
- 使用
npx sv create初始化新的 SvelteKit 项目。 - 在不同渲染模式(SSR、SSG、SPA、MPA、混合模式)之间进行选择。
- 了解标准项目布局(
src/routes、src/lib、static、svelte.config.js)。 - 决定使用
+page.svelte、+page.js、+page.server.js还是+server.js。 - 在 SvelteKit 处理器中使用 Web 平台 API(
fetch、Request、Response、Headers、FormData、ReadableStream、URL、URLSearchParams、crypto)。 - 使用
$types模块为路由文件添加类型(PageLoad、PageServerLoad、LayoutLoad、LayoutServerLoad、RequestHandler、PageProps、LayoutProps)。 - 使用
+server.js构建 API 端点(GET / POST / PUT / PATCH / DELETE / OPTIONS / fallback)。 - 配置布局、错误边界(
+error.svelte)和嵌套路由。
重要:SvelteKit 与 Svelte(何时使用哪个)
Svelte 是 UI 组件层。SvelteKit 是封装 Svelte 的应用框架。
| 需求 | 使用 |
|---|---|
| 渲染单个组件,嵌入现有网站 | 仅使用 Svelte |
| 构建包含路由、数据加载、SSR 和适配器的完整应用 | SvelteKit |
| SSG / SSR / SPA / MPA / 无服务器 | SvelteKit |
| 在页面中使用 Svelte 5 符文 | 在 SvelteKit 中使用 Svelte |
经验法则:如果你有多个“页面”、后端,或者需要 SEO,就使用 SvelteKit。
# Pure Svelte (no routing, no SSR)
npm create vite@latest my-app -- --template svelte
# Full SvelteKit app (routing + SSR + adapters)
npx sv create my-app
重要:创建项目(npx sv create)
# Minimal
npx sv create my-app
cd my-app
npm install
npm run dev # http://localhost:5173
实用标志(参见 sv CLI 文档):
# Non-interactive with explicit choices
npx sv create my-app \
--template minimal --types ts --no-add-ons --install npm
# Pick a template
npx sv create my-app --template demo # demo | minimal | library
# Add common add-ons later
npx sv add prettier eslint vitest playwright tailwindcss
CLI 会搭建以下文件:package.json、svelte.config.js、vite.config.js、tsconfig.json、src/app.html、src/routes/+page.svelte,以及(根据选项)hooks.client.js、hooks.server.js、service-worker.js。
重要:项目类型决策矩阵
渲染设置按适配器和页面配置(export const prerender = true、export const ssr = false、export const csr = false)。通常会混合搭配使用。
| 项目类型 | 适配器 | 配置 | 适用场景 |
|---|---|---|---|
| 默认(SSR + CSR) | 任意 | 无 | 大多数应用。首次渲染使用 SSR,导航后使用 CSR。 |
| 静态站点生成(SSG) | adapter-static | prerender = true(根级或按页面设置) | 文档、博客、营销网站。 |
| 单页应用(SPA) | 带 fallback 的 adapter-static | ssr = false | 应用外壳 + JSON 后端,无需 SEO。 |
| 多页应用(MPA) | 任意 | <body data-sveltekit-reload> + csr = false | 低 JS、由服务器驱动的页面。 |
| 独立后端 | adapter-node 或无服务器 | 跳过 server 文件 | 后端使用 Go/Rust/Java/PHP。 |
| 无服务器 | adapter-vercel / adapter-netlify / adapter-cloudflare | 无 | 部署到 Vercel / Netlify / Cloudflare。 |
| 自有服务器 / VPS | adapter-node | 无 | 可自托管的 Node 服务器。 |
| 容器(Docker/LXC) | adapter-node | 无 | 在容器镜像中运行。 |
| 库 | @sveltejs/package 插件 | 选择“library”模板 | 将 Svelte 组件作为软件包发布。 |
| 离线 / PWA | 任意 | src/service-worker.js | 支持离线的应用。 |
| 移动端 | adapter-static | bundleStrategy: 'single' | 使用 Tauri 或 Capacitor 封装。 |
| 桌面端 | adapter-static | bundleStrategy: 'single' | 使用 Tauri / Wails / Electron 封装。 |
| 浏览器扩展 | adapter-static 或社区适配器 | manifest + 扩展配置 | Chrome / Firefox 扩展。 |
| 嵌入式设备 | 任意 | bundleStrategy: 'single' | 电视 / 微控制器(并发请求较少)。 |
关键:项目结构
my-project/
├ src/
│ ├ lib/
│ │ ├ server/ # server-only lib (use $lib/server alias)
│ │ └ [your libs] # client-safe libs (use $lib alias)
│ ├ params/ # param matchers
│ ├ routes/ # filesystem router (one folder per route)
│ ├ app.html # HTML template (placeholders: %sveltekit.head% etc.)
│ ├ error.html # static fallback error page
│ ├ hooks.client.js
│ ├ hooks.server.js
│ ├ service-worker.js
│ └ instrumentation.server.js
├ static/ # served verbatim (robots.txt, favicon.ico)
├ tests/ # Playwright tests (if added)
├ package.json
├ svelte.config.js
├ tsconfig.json
└ vite.config.js
关键规则:
$lib→src/lib(可从任何位置导入)。$lib/server→src/lib/server(仅限服务器端使用 — SvelteKit 会阻止客户端导入)。src/routes定义 URL 树。每个文件夹都是一个路由;+page.svelte会创建一个页面。src/routes或src/app.html之外的内容都是可选的。- 优先使用
import导入资源(Vite 会为其生成哈希),而不是使用static/。
关键:svelte.config.js
最低限度的配置:一个空对象。svelte.config.js 导出一个用于配置 kit、preprocess、compilerOptions 等的 SvelteConfig 对象。
// svelte.config.js
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
adapter: adapter(),
alias: {
$components: 'src/lib/components',
$utils: 'src/lib/utils'
}
}
};
export default config;
请参阅 examples/svelte-config.md,了解 8 种以上常见配置。
关键:Web 标准(Fetch / FormData / Streams / URL / Web Crypto)
SvelteKit“使用平台能力”。浏览器原生 API 可用于 load 函数、+server.js 处理程序和钩子。SvelteKit 会在基于 Node 的适配器中为这些 API 提供 polyfill。
| API | 在 SvelteKit 中的使用位置 |
|---|---|
fetch | load、钩子、+server.js,以及服务器端和客户端 |
Request | 钩子和 +server.js 中的 event.request |
Response | +server.js 处理程序和 fetch() 的返回值 |
Headers | event.request.headers、Response.headers |
FormData | 表单提交:await event.request.formData() |
ReadableStream | 响应正文(流式传输、SSE) |
URL | event.url、page.url、beforeNavigate/afterNavigate |
URLSearchParams | url.searchParams.get('foo') |
crypto | crypto.randomUUID()、CSPRNG、哈希 |
特别说明:在 load 函数和 +server.js 中,fetch 接受相对 URL,并会自动保留凭据。在其他位置使用时,请显式传递 Cookie/标头。
关键:路由(+page、+layout、+server、+error、$types)
文件系统就是路由器。路由文件以 + 开头。
| 文件 | 用途 |
|---|---|
+page.svelte | 页面 UI。 |
+page.js | 通用 load 函数(服务器端 + 客户端)。 |
+page.server.js | 仅限服务器端的 load 和表单 actions。 |
+layout.svelte | 包装页面和嵌套布局。 |
+layout.js / +layout.server.js | 加载布局数据。 |
+server.js | API 端点(导出 HTTP 方法处理程序)。 |
+error.svelte | 单个路由的错误边界。 |
*.js(其他) | 会被忽略 — 将组件或工具函数放在同一目录中。 |
请牢记以下三条规则:
- 所有路由文件都可以在服务器端运行。
- 除
+server.js外,所有路由文件都会在客户端运行。 +layout和+error适用于所在目录及其所有子目录。
+page 三件套
<script>
/** @type {import('./$types').PageProps} */
let { data } = $props();
</script>
<h1>{data.title}</h1>
// src/routes/blog/[slug]/+page.js -- universal load
/** @type {import('./$types').PageLoad} */
export function load({ params }) {
return { title: params.slug };
}
// src/routes/blog/[slug]/+page.server.js -- server-only
import { error } from '@sveltejs/kit';
/** @type {import('./$types').PageServerLoad} */
export async function load({ params }) {
const post = await db.posts.find(params.slug);
if (!post) error(404, 'not found');
return { post };
}
+layout 三件套
布局会包装页面。根目录下的 +layout.svelte 必须渲染 children:
<script>
let { children } = $props();
</script>
<nav><a href="/">Home</a></nav>
{@render children()}
+server.js(API 端点)
// src/routes/api/random-number/+server.js
import { json, error } from '@sveltejs/kit';
/** @type {import('./$types').RequestHandler} */
export function GET({ url }) {
const min = Number(url.searchParams.get('min') ?? 0);
const max = Number(url.searchParams.get('max') ?? 1);
if (max <= min) error(400, 'invalid range');
return json({ value: min + Math.random() * (max - min) });
}
处理程序:GET、POST、PUT、PATCH、DELETE、OPTIONS、HEAD,以及一个会捕获其他所有请求的特殊 fallback。
+error.svelte
<script>
import { page } from '$app/state';
</script>
<h1>{page.status} — {page.error.message}</h1>
SvelteKit 会沿树向上查找最近的 +error.svelte。如果找不到,则使用静态文件 src/error.html。
$types
SvelteKit 会为每个路由文件自动生成 ./$types.d.ts。使用这些类型可确保类型安全:
| 类型 | 用于 |
|---|---|
PageLoad | +page.js |
PageServerLoad | +page.server.js |
LayoutLoad | +layout.js |
LayoutServerLoad | +layout.server.js |
RequestHandler | +server.js |
PageProps | +page.svelte({ data, params, form }) |
LayoutProps | +layout.svelte({ data, children }) |
PageData、LayoutData、ActionData | 较旧或范围较窄的类型 |
使用 VS Code 和 Svelte 扩展时,类型会自动推断 — 可以省略显式注解。
快速修复
- 找不到模块
$lib—svelte.config.js默认包含$lib别名;请检查svelte.config.js是否扩展了正确的配置,并确认至少运行过一次npm run dev。 +page.server.js中的数据未显示 — 确认文件名准确无误,必须是+page.server.js(包含+)。+layout未嵌套 — 布局必须在模板中的某处调用{@render children()}。- 动态参数返回 404 —
[slug]文件夹名会创建参数;[...rest]是“剩余”参数(贪婪匹配)。 - Hydration 不匹配警告 — 通常由
Date.now()/Math.random()在服务器端和客户端渲染出不同值导致。请将它们移到onMount或+page.server.js中。 Cannot import $lib/server into client code—src/lib/server下的文件仅限服务器端使用。请将共享代码移到src/lib。- Service worker 未更新 — 请更新
src/service-worker.js中的版本(它是构建时的缓存清除标记)。 - 开发模式下出现 Body 扩展警告 —
app.html应将%sveltekit.body%放在<div>内,而不是直接放在<body>中。 Cannot read properties of undefined (reading 'request')— 处理函数缺少event解构,或者忘了声明export async function POST(event)/GET({ request, url })。- JSDoc 中的类型报错 — 确保
tsconfig.json的extends指向./.svelte-kit/tsconfig.json。
注意事项
+page.js会在服务器端和客户端运行。不要在其中放置密钥或数据库调用 — 请使用+page.server.js。+page.server.js返回的数据会使用devalue序列化;函数 / 类实例 /Map/Set需要显式转换。+server.js文件不会经过+layout.svelte包装。它们会发出原始响应。跨领域关注点请使用handlehook。+error.svelte不会处理在+server.js或handlehook 中抛出的错误。请使用src/error.html作为回退。csr = false会移除页面上的所有 JavaScript — 包括客户端路由器。链接会变成完整页面重新加载。- 根布局中的
prerender = true会预渲染所有路由。可针对单个页面设置prerender = false覆盖。 <a href="/foo">使用客户端路由器。使用<a href="/foo" data-sveltekit-reload>可强制进行服务器端导航。- 如果键不存在,
URLSearchParams.get()会返回null(而不是undefined)。 +server.js中的event.url是完整 URL;客户端的page.url也同样是完整 URL;在load的专用 fetch 中可以使用相对 URL。- 只有使用剩余参数
[...rest]时,动态片段才会跨/边界匹配。 - 浏览器扩展直接向
<body>注入元素可能会破坏 Hydration — 请将%sveltekit.body%放在<div>内。
常见问题
问:我需要 TypeScript 吗?
不需要。npx sv create 可以搭建仅使用 JS 的项目。JSDoc 类型也能正常使用,并提供类型安全。
问:我可以在 SvelteKit 中使用 Svelte 5 runes 吗?
可以。SvelteKit 2.20+ 支持 Svelte 5。照常使用 $state、$derived、$props、$effect 即可。
问:如何从 +page.server.js 调用自己的后端?
使用 fetch(在 load 中使用 SvelteKit 特有的 fetch,可以保留 Cookie 并接受相对 URL)。在 load 之外,请显式传递 cookie/authorization 标头。
问:+page.js 和 +page.server.js 可以共存吗?
不可以。同一路由只能使用其中一个。处理敏感数据时,优先使用 +page.server.js。
问:API 密钥应该放在哪里?
放在仅服务端可用的环境变量中:$env/static/private(在构建时内联)或 $env/dynamic/private(在运行时读取)。绝不要将私有环境变量暴露给客户端代码。
问:error(404) 和 throw error(404) 有什么区别?
error() 会返回一个特殊对象——不要抛出它。只需调用 error(404, 'msg'),其余工作由 SvelteKit 处理。
问:如何在页面中获取查询参数?
使用 $page.url.searchParams.get('foo')(Svelte 4 store),或 page.url.searchParams.get('foo')(通过 $app/state 在 Svelte 5 中使用)。
问:我可以构建纯静态网站吗?
可以——安装 adapter-static,并在根布局(或每个页面)中设置 prerender = true。构建输出为纯 HTML。
问:SvelteKit 与 Next.js / Nuxt 有何不同?
它采用基于文件的路由器,默认先 SSR 再 CSR,没有内置的 API 风格——端点需要自行编写 +server.js。适配器由官方提供并得到良好维护。
示例与参考
示例
| 文件 | 描述 |
|---|---|
| examples/README.md | 所有示例的索引 |
| examples/project-creation.md | npx sv create、--template、--types、--add、--install |
| examples/project-types.md | 各类项目及其适配器和配置片段 |
| examples/project-structure.md | src/、路由、静态文件、package.json、svelte.config.js |
| examples/svelte-config.md | 常见的 svelte.config.js 设置(预处理、kit、别名) |
| examples/web-standards.md | 带凭据的 fetch、Request、Response、FormData、流、URL |
| examples/routing-pages.md | +page.svelte、+page.js、+page.server.js、参数、布局 |
| examples/routing-server.md | +server.js GET/POST/PUT/DELETE、内容协商、回退 |
参考
| 文件 | 描述 |
|---|---|
| references/README.md | 所有参考资料的索引 |
| references/project-types-reference.md | 所有项目类型的完整决策矩阵 |
| references/project-structure-reference.md | 标准项目布局中的每个文件 |
| references/web-standards-reference.md | SvelteKit 中的 Fetch / Request / Response / FormData / Streams / URL / Web Crypto |
| references/routing-reference.md | +page、+layout、+server、+error、$types 参考 |