ข้ามไปยังเนื้อหา

Dynamic Pages from Data

Next.js App Router ใช้ generateStaticParams() เพื่อระบุ dynamic routes ตอน build time Next Pages Router ใช้ getStaticPaths() Astro ก็ใช้ getStaticPaths() ในไฟล์ [slug].astro — ชื่อเดียวกับ Pages Router แต่คุณ return array ของ object ที่มี key params (จะมี key props ด้วยก็ได้) แล้วเข้าถึงผ่าน Astro.props และ Astro.params ใน frontmatter

ต้องใช้โปรเจกต์ Astro เต็มรูปแบบถึงจะรันได้ ใช้ npm create astro@latest เพื่อสร้างโปรเจกต์

React
// app/blog/[slug]/page.tsx (Next.js App Router)
import { allPosts } from 'contentlayer/generated';
export async function generateStaticParams() {
return allPosts.map(post => ({ slug: post.slug }));
}
export default function PostPage({ params }) {
const post = allPosts.find(p => p.slug === params.slug);
return (
<article>
<h1>{post.title}</h1>
<p>{post.description}</p>
</article>
);
}
Astro
---
// src/pages/blog/[slug].astro (Astro)
import { getCollection, render } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.id },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await render(post);
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>

ใน Astro, getStaticPaths กับ page template อยู่ในไฟล์เดียวกัน key props ให้คุณส่ง collection entry ทั้งก้อนไปตรง ๆ ได้เลย — ไม่ต้อง lookup ซ้ำอีกรอบ

React
// pages/blog/[slug].tsx (Next.js Pages Router)
export async function getStaticPaths() {
const posts = await fetchAllPosts(); // or contentlayer
return {
paths: posts.map(p => ({ params: { slug: p.slug } })),
fallback: false,
};
}
export async function getStaticProps({ params }) {
const post = await fetchPost(params.slug);
return { props: { post } };
}
export default function PostPage({ post }) {
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.contentHtml }} />
</article>
);
}
Astro
---
// src/pages/blog/[slug].astro (Astro)
import { getCollection, render } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
// params defines the URL; props pass data to the page
return posts.map(post => ({
params: { slug: post.id },
props: { post },
}));
}
// Both params and props land here — no second getStaticProps needed
const { post } = Astro.props;
const { Content } = await render(post);
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>

Next Pages Router แยก path enumeration (getStaticPaths) ออกจาก data fetching (getStaticProps) Astro รวมสองอย่างเข้าด้วยกัน: ส่ง props ไปพร้อมกับ getStaticPaths แล้วข้าม round-trip รอบที่สองไปได้เลย

src/pages/blog/[slug].astro
---
import { getCollection, render } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
export async function getStaticPaths() {
const posts = await getCollection('blog', ({ data }) => !data.draft);
return posts.map((post) => ({
params: { slug: post.id },
props: { post },
}));
}
const { post } = Astro.props;
const { Content, headings } = await render(post);
const { title, date, tags = [] } = post.data;
---
<BaseLayout title={title}>
<article>
<header>
<h1>{title}</h1>
<time datetime={date.toISOString()}>
{date.toLocaleDateString('en-US', { dateStyle: 'long' })}
</time>
{tags.length > 0 && (
<ul class="tags">
{tags.map((tag) => <li>{tag}</li>)}
</ul>
)}
</header>
<Content />
</article>
</BaseLayout>
`getStaticPaths()` อยู่ที่ไหนในโปรเจกต์ Astro?
แต่ละ object ในอาร์เรย์ที่ `getStaticPaths` คืนค่าแทนอะไร?
อะไรคือ equivalent ของ Next App Router `generateStaticParams` ใน Astro?