Navigation
ใน React คุณใช้ <Link> จาก react-router หรือ Next.js เพื่อ client-side navigation และ usePathname() / useRouter() เพื่ออ่าน URL ปัจจุบัน โมเดล MPA ของ Astro หมายความว่า plain HTML <a href> ทำงานได้สมบูรณ์แบบ — ไม่ต้องใช้ component พิเศษ สำหรับ URL ปัจจุบัน ใช้ Astro.url (object URL มาตรฐานที่ใช้ได้ในทุกไฟล์ .astro)
Navigation พื้นฐาน
หัวข้อที่มีชื่อว่า “Navigation พื้นฐาน”// React / Next.js — ต้องใช้ <Link> สำหรับ client-side navimport Link from 'next/link';import { usePathname } from 'next/navigation';
export default function Nav() { const pathname = usePathname(); const links = ['/', '/about', '/blog'];
return ( <nav> {links.map((href) => ( <Link key={href} href={href} className={pathname === href ? 'active' : ''} > {href === '/' ? 'Home' : href.slice(1)} </Link> ))} </nav> );}---// src/components/Nav.astro// Astro.url คือ URL object มาตรฐาน — ไม่ต้อง hookconst pathname = Astro.url.pathname;const links = ['/', '/about', '/blog'];---<nav> {links.map((href) => ( <a href={href} class={pathname === href ? 'active' : ''} > {href === '/' ? 'Home' : href.slice(1)} </a> ))}</nav>ประเด็นสำคัญ:
Astro.urlคือURLobject มาตรฐาน — ใช้.pathname,.origin,.searchParamsฯลฯ- การตรวจสอบ active link คือการเปรียบเทียบ string ล้วนๆ — ไม่ต้อง hook พิเศษ
<a href>ปกติจะส่ง HTTP request เต็มรูปแบบ (โมเดล MPA) browser จัดการ navigation ให้เอง
ตัวอย่าง runnable — แสดง current path
หัวข้อที่มีชื่อว่า “ตัวอย่าง runnable — แสดง current path”หน้าแบบ self-contained นี้แสดงการทำงานของ Astro.url เปิดใน StackBlitz และสังเกตว่า pathname ปัจจุบันถูก render ฝั่ง server
---
const url = Astro.url;
const links = ['/', '/about', '/blog', '/contact'];
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Navigation demo</title>
<style>
body { font-family: sans-serif; padding: 2rem; }
nav { display: flex; gap: 1rem; margin-bottom: 2rem; }
a { color: #6366f1; text-decoration: none; padding: 0.25rem 0.75rem;
border-radius: 4px; border: 1px solid #6366f1; }
a.active { background: #6366f1; color: #fff; }
.info { background: #f1f5f9; padding: 1rem; border-radius: 6px; }
code { background: #e2e8f0; padding: 0.1rem 0.4rem; border-radius: 3px; }
</style>
</head>
<body>
<nav>
{links.map((href) => (
<a href={href} class={url.pathname === href ? 'active' : ''}>{href}</a>
))}
</nav>
<div class="info">
<p><strong>Astro.url.pathname:</strong> <code>{url.pathname}</code></p>
<p><strong>Astro.url.origin:</strong> <code>{url.origin}</code></p>
</div>
<p>คลิก link — active state ถูกกำหนดณ build/render time ไม่ใช่ใน JS</p>
</body>
</html>ClientRouter — animation แบบ SPA
หัวข้อที่มีชื่อว่า “ClientRouter — animation แบบ SPA”Astro มี <ClientRouter /> component built-in ที่ครอบ View Transitions API ของ browser เพียงเพิ่มลงใน layout ก็ได้ transition แบบ animation ระหว่างหน้าโดยไม่ต้องแปลง site เป็น SPA
// Next.js — page transition ต้องใช้ library// เช่น framer-motion AnimatePresence หรือ next-view-transitionsimport { ViewTransitions } from 'next-view-transitions';
export default function RootLayout({ children }) { return ( <html> <body> <ViewTransitions> {children} </ViewTransitions> </body> </html> );}---// src/layouts/Layout.astroimport { ClientRouter } from 'astro:transitions';---<html lang="en"> <head> <meta charset="utf-8" /> <title>My Site</title> <!-- เพิ่มบรรทัดนี้บรรทัดเดียวเพื่อ transition แบบ SPA --> <ClientRouter /> </head> <body> <slot /> </body></html>เมื่อเพิ่ม <ClientRouter /> แล้ว Astro จะสกัด link click และใช้ native View Transitions API ของ browser สร้าง animation ระหว่างหน้า คุณยังคงใช้ mental model แบบ MPA — ไม่มี client-side router ไม่มี JavaScript bundle สำหรับ routing logic