SSR, CSR และ Prerendering
Next.js กำหนด rendering mode ผ่านฟังก์ชัน getServerSideProps, getStaticProps, หรือ React Server Components SvelteKit ใช้แนวทางที่สม่ำเสมอกว่า: ทุก page มีค่า default เป็น SSR และคุณ opt out ได้ต่อ page ผ่าน page options ที่ export ออกมาจาก +page.js หรือ +layout.js
SSR คือค่า default
หัวข้อที่มีชื่อว่า “SSR คือค่า default”เมื่อ user เปิดหน้าเว็บเป็นครั้งแรก SvelteKit จะ render บนฝั่ง server แล้วส่ง HTML ไปพร้อมกับ JavaScript สำหรับ hydration — เหมือนกับ Next.js SSR ทุกประการ แต่คุณไม่ต้องเลือก mode ใด ๆ เป็น default อยู่แล้ว
// Next.js App Router — SSR คือ default สำหรับ Server Components// app/products/page.tsxasync function ProductsPage() { const products = await fetchProducts(); // รันบน server return ( <ul> {products.map(p => ( <li key={p.id}>{p.name}</li> ))} </ul> );}export default ProductsPage;<!-- src/routes/products/+page.server.js -->export async function load() { const products = await fetchProducts(); // รันบน server return { products };}
<!-- src/routes/products/+page.svelte --><script> let { data } = $props();</script>
<ul> {#each data.products as product} <li>{product.name}</li> {/each}</ul>+page.server.js ไม่เคยส่งโค้ดไปยัง browser เลย — ปลอดภัยสำหรับ database queries, API keys, และ secrets ทุกอย่าง
ปิด SSR: CSR เท่านั้น
หัวข้อที่มีชื่อว่า “ปิด SSR: CSR เท่านั้น”บาง page ไม่จำเป็นต้องใช้ SSR เช่น dashboard ที่ต้องการ authentication หรือ page ที่ข้อมูลทั้งหมดโหลดจาก client-side ส่ง ssr = false เพื่อบอก SvelteKit ให้ skip server render
export const ssr = false;
export async function load({ fetch }) { // โหลดข้อมูลบน client เท่านั้น const res = await fetch('/api/user-data'); return { userData: await res.json() };}เทียบได้กับการใช้ 'use client' directive ใน Next.js App Router หรือใช้ Pages Router โดยไม่มี getServerSideProps
Prerendering: Static Site Generation
หัวข้อที่มีชื่อว่า “Prerendering: Static Site Generation”สำหรับหน้าที่ข้อมูลไม่เปลี่ยนบ่อย เช่น หน้า about, blog posts, หรือ marketing pages ให้ prerender ตอน build time เทียบได้กับ getStaticProps ของ Next.js
// Next.js Pages Router — Static Generation// pages/about.tsxexport async function getStaticProps() { return { props: { buildTime: new Date().toISOString() }, };}
export default function About({ buildTime }) { return <p>Built at: {buildTime}</p>;}<!-- +page.js -->export const prerender = true;
export async function load() { return { buildTime: new Date().toISOString(), };}
<!-- +page.svelte --><script> let { data } = $props();</script>
<p>Built at: {data.buildTime}</p>ตั้งค่า export const prerender = true ใน +layout.js ของ root เพื่อ prerender ทั้ง site (Static Site Generation) หรือตั้งค่าต่อ page ก็ได้
Page options สรุปทั้งหมด
หัวข้อที่มีชื่อว่า “Page options สรุปทั้งหมด”// +page.js หรือ +layout.jsexport const ssr = true; // default: true — render บน server ก่อนexport const csr = true; // default: true — hydrate บน clientexport const prerender = false; // default: false — render ตอน build timeexport const trailingSlash = 'never'; // 'always' | 'never' | 'ignore'ตัวเลือกเหล่านี้ inherit จาก layout ลงมา ถ้าตั้งค่า prerender = true ใน root layout ทุก page จะถูก prerender ยกเว้นจะ override ต่อ page
Adapters: deploy ที่ไหนก็ได้
หัวข้อที่มีชื่อว่า “Adapters: deploy ที่ไหนก็ได้”SvelteKit ใช้ adapters เพื่อ compile app สำหรับ deployment target ต่าง ๆ แนวคิดนี้ไม่มีใน Next.js (Next.js ผูกกับ Vercel) แต่ SvelteKit ออกแบบมาให้ portable ตั้งแต่แรก
| Adapter | ใช้เมื่อ |
|---|---|
@sveltejs/adapter-auto | detect environment อัตโนมัติ (Vercel, Netlify, Cloudflare) |
@sveltejs/adapter-node | Node.js server (self-hosted, Docker) |
@sveltejs/adapter-static | Static files เท่านั้น (ต้อง prerender ทั้งหมด) |
@sveltejs/adapter-cloudflare | Cloudflare Workers + Pages |
@sveltejs/adapter-vercel | Vercel Edge Functions |
import adapter from '@sveltejs/adapter-node';
export default { kit: { adapter: adapter({ out: 'build' }), },};เทียบกับ Next.js: Next.js ทำงานได้ดีที่สุดบน Vercel แต่ต้องการ workaround สำหรับ host อื่น SvelteKit สลับ adapter แล้ว build ได้ทันที ไม่ต้องแก้โค้ด
การผสม rendering modes
หัวข้อที่มีชื่อว่า “การผสม rendering modes”SvelteKit ให้ผสม mode ในแต่ละ route ได้:
flowchart TB routes(["src/routes/"]) routes --> rootLayout["+layout.js → ssr: true (default)"] routes --> rootPage["+page.svelte → SSR (home page)"] routes --> about["about/"] about --> aboutConfig["+page.js → prerender: true"] about --> aboutPage["+page.svelte → static (prerendered)"] routes --> dashboard["dashboard/"] dashboard --> dashConfig["+layout.js → ssr: false"] dashboard --> dashPage["+page.svelte → CSR only (protected page)"]