Dynamic Routes
ใน Next.js App Router คุณใช้ [slug]/page.tsx + generateStaticParams() เพื่อ pre-render หน้าแบบ dynamic ณ build time Astro ใช้ convention ชื่อไฟล์แบบ bracket เดียวกัน — [slug].astro — คู่กับ getStaticPaths() export ที่ จำเป็น ภายใน frontmatter
Dynamic route ต้องการการสร้างหลายหน้า — รัน example เหล่านี้ใน Astro project เต็มรูปแบบ (
npm create astro@latest) ในเครื่องของคุณ
การกำหนด dynamic segment
หัวข้อที่มีชื่อว่า “การกำหนด dynamic segment”// app/blog/[slug]/page.tsx (Next.js App Router)export async function generateStaticParams() { const posts = await getPosts(); return posts.map((post) => ({ slug: post.slug }));}
export default function BlogPost({ params,}: { params: { slug: string };}) { return <h1>Post: {params.slug}</h1>;}---// src/pages/blog/[slug].astroexport async function getStaticPaths() { const posts = await getPosts(); return posts.map((post) => ({ params: { slug: post.slug }, props: { post }, // ส่งข้อมูลพร้อม params }));}
const { slug } = Astro.params;const { post } = Astro.props;---<h1>{post.title}</h1>สิ่งสำคัญที่ควรสังเกต:
getStaticPaths()ถูก export จากภายใน frontmatter — ไม่ใช่เป็น separate file export แบบ Next.js- แต่ละ path object มี field
propsเพื่อนำข้อมูลที่ fetch มาไว้คู่กับ path — ไม่ต้อง fetch ซ้ำในหน้า Astro.paramsเก็บค่า dynamic segment เทียบเท่ากับparams.slugใน Next.js
การเข้าถึง params และ props
หัวข้อที่มีชื่อว่า “การเข้าถึง params และ props”// Next.js Pages Router equivalent// pages/blog/[slug].tsximport type { GetStaticPaths, GetStaticProps } from 'next';
export const getStaticPaths: GetStaticPaths = async () => { const posts = await getPosts(); return { paths: posts.map((p) => ({ params: { slug: p.slug } })), fallback: false, };};
export const getStaticProps: GetStaticProps = async ({ params }) => { const post = await getPost(params!.slug as string); return { props: { post } };};
export default function BlogPost({ post }: { post: Post }) { return <article><h1>{post.title}</h1></article>;}---// src/pages/blog/[slug].astro// getStaticPaths + data fetching ในฟังก์ชันเดียว:export async function getStaticPaths() { const posts = await getPosts(); return posts.map((post) => ({ params: { slug: post.slug }, props: { post }, }));}
// props มาทาง Astro.props เหมือน component ทั่วไปconst { post } = Astro.props;---<article> <h1>{post.title}</h1> <div set:html={post.body} /></article>File tree สำหรับ blog
หัวข้อที่มีชื่อว่า “File tree สำหรับ blog”flowchart TD pages["src/pages/"] --> blog["blog/"] blog --> index["index.astro"] blog --> slug["[slug].astro"] index --> indexURL["/blog (list all posts)"] slug --> slugURL["/blog/:slug (individual post)"]
Catch-all routes
หัวข้อที่มีชื่อว่า “Catch-all routes”Astro รองรับ catch-all route แบบ rest-parameter ด้วย [...path].astro ซึ่งแมปกับ [[...slug]]/page.tsx ใน Next.js
// app/docs/[[...slug]]/page.tsxexport default function DocsPage({ params,}: { params: { slug?: string[] };}) { const path = params.slug?.join('/') ?? ''; return <div>Docs path: {path}</div>;}---// src/pages/docs/[...path].astroconst { path } = Astro.params;// path เป็น string เช่น "getting-started/intro"---<div>Docs path: {path}</div>