Layouts และ Navigation
ใน React Router คุณสร้าง layout ด้วยการวาง <Outlet /> ไว้ใน parent route component — child route ใดก็ตามจะ render ตรงที่คุณวาง outlet ไว้ SvelteKit ใช้แนวทางจาก file system แทน: ไฟล์ +layout.svelte จะ wrap ทุก route ในไดเรกทอรีเดียวกันให้อัตโนมัติ คุณได้พฤติกรรม nesting แบบเดียวกัน แต่ไม่ต้องตั้งค่า route config ใด ๆ เลย เหมือนกับ Next.js App Router, layout ของ SvelteKit จะ persist ข้ามการนำทาง — ไม่ unmount และ remount เมื่อคุณนำทางระหว่าง child route
รันตัวอย่างนี้ในโปรเจกต์ SvelteKit (
npx sv create)
Layout กับ nested routes
หัวข้อที่มีชื่อว่า “Layout กับ nested routes”ใน React Router คุณระบุจุดที่ children จะ render ด้วยการวาง <Outlet /> ใน SvelteKit Svelte 5 layout ใช้ snippet syntax {@render children()} — ไม่มี <slot /> ใน Svelte 5 layout
// src/layouts/RootLayout.jsx (React Router v6)import { Outlet, Link } from 'react-router-dom';
export default function RootLayout() { return ( <div> <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/blog">Blog</Link> </nav> <main> <Outlet /> </main> </div> );}<!-- src/routes/+layout.svelte --><script> let { children } = $props();</script>
<nav> <a href="/">Home</a> <a href="/about">About</a> <a href="/blog">Blog</a></nav>
<main> {@render children()}</main>{@render children()} คือจุดที่ child route ที่ตรงกันจะ render เข้ามา children snippet ถูกส่งมาให้อัตโนมัติโดย SvelteKit — คุณแค่ destructure มันออกมาจาก $props()
Active link highlighting
หัวข้อที่มีชื่อว่า “Active link highlighting”React Router ให้ useLocation() เพื่ออ่าน URL ปัจจุบันและคำนวณ active style SvelteKit เปิดเผยข้อมูลเดียวกันผ่าน object page ที่ import จาก $app/state
// React Router — active link with useLocationimport { Link, useLocation } from 'react-router-dom';
const links = [ { to: '/', label: 'Home' }, { to: '/about', label: 'About' }, { to: '/blog', label: 'Blog' },];
export default function Nav() { const { pathname } = useLocation();
return ( <nav> {links.map(({ to, label }) => ( <Link key={to} to={to} className={pathname === to ? 'active' : ''} > {label} </Link> ))} </nav> );}<!-- +layout.svelte (Svelte 5) --><script> import { page } from '$app/state'; let { children } = $props();
const links = [ { href: '/', label: 'Home' }, { href: '/about', label: 'About' }, { href: '/blog', label: 'Blog' }, ];</script>
<nav> {#each links as { href, label }} <a {href} class:active={page.url.pathname === href}> {label} </a> {/each}</nav>
<main> {@render children()}</main>
<style> a { margin-right: 1rem; text-decoration: none; color: inherit; } a.active { font-weight: bold; border-bottom: 2px solid currentColor; }</style>page จาก $app/state เป็น reactive object — มันอัปเดตทุกครั้งที่มีการนำทางโดยอัตโนมัติ ไม่ต้องมี useEffect ไม่ต้อง setup subscription
นำทางด้วย <a href> ธรรมดา
หัวข้อที่มีชื่อว่า “นำทางด้วย <a href> ธรรมดา”ใน React คุณต้องใช้ component <Link> (react-router หรือ next/link) เพื่อ client-side navigation — <a> ธรรมดาจะทำให้เกิด full page reload SvelteKit ไม่ต้องการสิ่งเหล่านั้นเลย: ใช้ <a href> ธรรมดาได้เลย แล้ว SvelteKit จะ intercept การคลิกและทำ client-side navigation ให้อัตโนมัติ ไม่ต้อง import ไม่ต้องมี wrapper component
$app/state และ object page
หัวข้อที่มีชื่อว่า “$app/state และ object page”page จาก $app/state เป็น reactive object ที่เปิดเผยทุกอย่างเกี่ยวกับ route ปัจจุบัน — เทียบเท่ากับ useLocation() + useParams() ใน React Router หรือ usePathname() + useSearchParams() ใน Next.js โดยตรง
<script> import { page } from '$app/state';</script>
<p>Current path: {page.url.pathname}</p><p>URL params: {JSON.stringify(page.params)}</p><p>Search: {page.url.search}</p>property สำคัญที่ page ให้:
| Property | เทียบเท่าใน React |
|---|---|
page.url.pathname | useLocation().pathname / usePathname() |
page.params | useParams() |
page.url.searchParams | useSearchParams() |
page.data | ข้อมูลที่ load function ส่งกลับมา |
page.status | HTTP status code ของหน้านี้ |
Full +layout.svelte with active-link navigation
หัวข้อที่มีชื่อว่า “Full +layout.svelte with active-link navigation”นี่คือ layout แบบสมบูรณ์ที่คุณนำไปใช้ในโปรเจกต์ SvelteKit ใดก็ได้:
<script> import { page } from '$app/state'; let { children } = $props();</script>
<header> <a href="/" class="logo">MySite</a> <nav> <a href="/" class:active={page.url.pathname === '/'}>Home</a> <a href="/about" class:active={page.url.pathname === '/about'}>About</a> <a href="/blog" class:active={page.url.pathname.startsWith('/blog')}>Blog</a> </nav></header>
<main> {@render children()}</main>
<footer>© 2026 MySite</footer>
<style> header { display: flex; align-items: center; gap: 1rem; padding: 0.75rem 1.5rem; border-bottom: 1px solid #e5e7eb; } .logo { font-weight: 700; text-decoration: none; } nav { display: flex; gap: 1rem; margin-left: auto; } nav a { text-decoration: none; color: inherit; } nav a.active { font-weight: 600; color: #FF3E00; }</style>Nested layouts
หัวข้อที่มีชื่อว่า “Nested layouts”Layout ซ้อนกันได้ตามลำดับชั้นไดเรกทอรี — เหมือนกับ Next.js App Router ทุกประการ
flowchart TB routes(["src/routes/"]) routes --> rootLayout["+layout.svelte (root layout — nav + footer)"] routes --> rootPage["+page.svelte → /"] routes --> dashboard["dashboard/"] dashboard --> dashLayout["+layout.svelte (dashboard layout — sidebar)"] dashboard --> dashPage["+page.svelte → /dashboard"] dashboard --> settings["settings/"] settings --> settingsPage["+page.svelte → /dashboard/settings"]
/dashboard/settings จะได้รับทั้ง root layout และ dashboard layout ซ้อนกัน โดยไม่ต้องกำหนด config ใด ๆ เพิ่มเติม
ประเด็นสำคัญ
หัวข้อที่มีชื่อว่า “ประเด็นสำคัญ”+layout.sveltewrap ทุก route ในไดเรกทอรีเดียวกัน — และไดเรกทอรีลูกจะสืบทอดมันอัตโนมัติ- Children render ที่
{@render children()}(Svelte 5 snippet syntax) ไม่มี<slot />ใน Svelte 5 layout - Layout ซ้อนกันได้:
dashboard/+layout.sveltewrap ทุก route ภายใต้/dashboardซ้อนอยู่ภายใน root layout - ใช้
<a href="/about">ธรรมดา — ไม่ต้องมี component<Link>SvelteKit intercept การคลิก<a>และทำ client-side navigation ให้อัตโนมัติ pageจาก$app/stateให้url,params,data,route.idและอื่น ๆ — reactive ทั้งหมดpage.url.pathnameคือวิธีมาตรฐานในการทำ active-link logic- Layout persist ข้ามการนำทางระหว่าง child route ของมัน — ไม่ unmount เหมือนกับ layout ของ Next.js App Router