เทมเพลต SvelteKit สำหรับงานโปรดักชันที่จัดชุดเครื่องมือมาให้พร้อม: routing, auth, API proxy, OpenAPI client, i18n, UI component kit และ developer experience ครบถ้วน สามารถโคลนแล้วเริ่มสร้างฟีเจอร์ได้ทันที
- TL;DR
- Prerequisites
- Getting Started
- Project Highlights
- Architecture Overview
- Auth & API Proxy Flow
- Working with APIs
- Forms & Validation
- i18n (Paraglide.js)
- UI System
- Logging
- Environment Variables
- npm/bun Scripts
- Deployment
- Troubleshooting
- Appendix: Directory Snapshot
- โคลน repo แล้วติดตั้งด้วย
bun install - สร้าง
.envใส่PUBLIC_APP_TITLEและBACKEND_API_URL - รัน
bun run dev - เพิ่ม route/custom logic ได้เลย (auth guard และ proxy พร้อมใช้งาน)
- Node.js 20+ (รองรับผ่าน bun, pnpm, หรือ npm)
- fish shell (ตัวอย่างคำสั่งใช้ fish แต่แทนที่คำสั่งด้วย package manager ที่คุณชอบได้)
- Backend ที่เปิด endpoint
/openapi.json,/v1/auth/login, และ/v1/auth/refreshหากต้องการใช้ proxy + OpenAPI client เต็มรูปแบบ
bun installสร้างไฟล์ .env (หรือกำหนดค่าในระบบ) อย่างน้อยดังนี้
PUBLIC_APP_TITLE=Sveltekitten
BACKEND_API_URL=http://localhost:8000bun run devหรือ build + preview โปรดักชัน
bun run build
bun run previewbun run check
bun run lint
bun run formatbun run openapi:fastapiสคริปต์นี้ดึง schema จาก ${BACKEND_API_URL}/openapi.json
- SvelteKit v2 + Svelte 5 + Vite 7 ด้วย adapter-node
- Tailwind CSS v4 ผ่านปลั๊กอิน
@tailwindcss/vite, ไม่มี config แยก เสริมด้วย component kit ในsrc/lib/components/ui - TanStack Query (Svelte) พร้อม provider ตัวอย่างใช้งานและกลไก caching
- Auth + API proxy รองรับ refresh token อัตโนมัติ และเชื่อมกับ FastAPI ได้ทันที
- OpenAPI integration ใช้
openapi-fetchและ type generation จากopenapi-typescript - Superforms + Zod สำหรับฟอร์มแบบ type-safe (พร้อมตัวอย่างหน้า Login)
- Paraglide.js i18n โครงสร้างพร้อมทำงานหลายภาษา
- Logger & utilities เช่น pino, cookie helpers, auth helpers
src/app.html,src/app.cssจัดโครงสร้างและ global stylessrc/hooks.server.tsรวม middleware ด้วยsequence(auth guard, paraglide, fastapi client)src/lib/เก็บ API clients, UI components, hooks, schemas, utilitiessrc/routes/ใช้ file-based routing ของ SvelteKit (มีกลุ่ม(auth)สำหรับหน้าที่ต้องล็อกอิน)static/สำหรับไฟล์สาธารณะ เช่นrobots.txt
- Auth guard ตรวจทุก request ที่วิ่งเข้าโฟลเดอร์
(auth)หากไม่มีหรือหมดอายุ refresh token จะ redirect ไป/login - API proxy (
src/routes/api/proxy/[...slug]/+server.ts) รับทุกคำขอใต้/api/proxy/**- แนบ
Authorization: Bearer <access_token>จากคุกกี้ให้อัตโนมัติ - หากได้ 401 และมี refresh token จะยิง
/v1/auth/refreshเพื่อขอ access token ใหม่แล้วรีทรีไลน์เดิม - หาก refresh ล้มเหลวจะล้างคุกกี้และส่งสถานะเดิมจาก backend กลับไป
- แนบ
- Login flow (
src/routes/login) ใช้ Superforms + Zod ทำงานฝั่งเซิร์ฟเวอร์ เซ็ตคุกกี้access_token,refresh_tokenและ redirect เข้าหน้า(auth)
- สร้างไว้ใน
src/lib/api/fastapi-client.ts - เข้าถึงผ่าน
event.locals.fastapiClientใน load/action ของ server
const response = await locals.fastapiClient.POST('/v1/auth/login', {
body: { email, password }
});- ใช้
src/lib/api/api.tsสร้าง client กำหนดbaseUrlเอง - มีตัวอย่าง
pokemon-api.tsเรียก PokeAPI สำหรับ demo
- ใช้
superforms+zod - Schema ตัวอย่างอยู่ใน
src/lib/schemas/auth.schema.ts - หน้า login แสดงวิธีผูก form, แสดง error, และเรียก action ฝั่งเซิร์ฟเวอร์
- ไฟล์แปลอยู่ใน
messages/ - การตั้งค่าโปรเจกต์อยู่ใน
project.inlang/ - ปลั๊กอิน
paraglideVitePluginจะ generate โค้ดลงsrc/lib/paraglide/ - เพิ่มภาษาใหม่โดยสร้างไฟล์ JSON เพิ่มใน
messages/แล้วรัน dev/build อีกรอบ
- ใช้ Tailwind v4 (ผ่านปลั๊กอิน Vite) สำหรับ utility-first styling
- คอมโพเนนต์ UI แยกหมวดใน
src/lib/components/ui/เช่น button, card, dropdown menu, form controls - Toaster (
sonner) ถูกเพิ่มไว้ในsrc/routes/+layout.svelte
- ไฟล์ logger หลักอยู่ที่
src/lib/logger.tsใช้pinoตั้งค่าแยก dev/prod อัตโนมัติ - นำเข้าใช้งานได้ทั้งฝั่ง server และ client (เบราว์เซอร์จะดรอป transport pretty ในโปรดักชัน)
- ตัวอย่างการเรียกใช้งาน
import { logger } from '$lib/logger';
logger.info({ userId }, 'Fetching profile');
try {
// ...do work
} catch (error) {
logger.error(error, 'Failed to fetch profile');
}
// ฟังก์ชันเสริมสำหรับดีบักใน dev mode เท่านั้น
logger.inspect(data);
logger.dir({ event });
logger.table(rows);- ฟังก์ชัน
inspect,dir,tableจะ log เฉพาะเวลาdev === trueเพื่อไม่ให้รบกวนโปรดักชัน - หากต้องปรับระดับ log เพิ่ม เติม option ตาม
pinoAPI ภายในcreateLogger()
PUBLIC_APP_TITLEชื่อแอปฝั่ง client (โหลดผ่าน$env/dynamic/public)BACKEND_API_URLURL ของ backend สำหรับ proxy และ OpenAPI ($env/dynamic/private)- ตั้งค่าแบบชั่วคราวใน fish shell ได้ด้วย
set -x PUBLIC_APP_TITLE "Sveltekitten"
set -x BACKEND_API_URL "http://localhost:8000"bun run devเริ่มโหมดพัฒนาbun run buildสร้างโปรดักชันbun run previewเปิดเซิร์ฟเวอร์โปรดักชันแบบโลคอลbun run checkตรวจ type + lint ของ Sveltebun run lintรัน prettier --check และ eslintbun run formatใช้ prettier --writebun run openapiและbun run openapi:fastapiสร้าง type จาก OpenAPI schema
- ใช้
@sveltejs/adapter-nodeได้ไฟล์ Node server ภายหลังbun run build - รันด้วย
bun run previewหรือnode build(ตาม script ที่คุณตั้ง) - ตั้ง environment variable ให้เหมาะกับเครื่องปลายทาง โดยเฉพาะ
BACKEND_API_URL - แนะนำให้ใช้ process manager (PM2, Docker, systemd) ตามบริบท
- 401 ซ้ำๆ จาก proxy: ตรวจสอบ refresh token หมดอายุหรือ endpoint
/v1/auth/refreshทำงานหรือไม่ - CORS: ให้เรียก backend ผ่าน proxy
/api/proxy/**เพื่อลดปัญหา CORS ฝั่งเบราว์เซอร์ - OpenAPI type ไม่อัปเดต: รัน
bun run openapi:fastapiหลัง backend เปลี่ยน schema - Cookie naming: ใช้ชื่อมาตรฐาน
access_tokenและrefresh_tokenให้สอดคล้องกับ helper ในsrc/lib/utils
src/
app.css
app.html
hooks.server.ts
lib/
api/
api.ts
fastapi-client.ts
paths/fastapi.d.ts
components/ui/
button/
card/
dropdown-menu/
form/
hooks/
auth-guard.ts
fastapi.hook.ts
schemas/
auth.schema.ts
utils/
api-core.ts
auth.ts
cookies.ts
routes/
+layout.svelte
+layout.ts
+page.svelte
(auth)/home/+page.svelte
api/proxy/[...slug]/+server.ts
login/
+page.svelte
+page.server.ts
login-form.svelte
พร้อมใช้งานแล้ว! หากมีข้อเสนอแนะหรืออยากเพิ่มตัวอย่าง สามารถเปิด issue หรือ pull request ใน repository ได้เลย