Dynamic segments + generateStaticParams; optional catch-all [[...slug]] матчит base path.
Пример
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((p) => ({ slug: p.slug }));
}
export default async function Post({ params }: { params: Promise }) {
const { slug } = await params;
const post = await getPost(slug);
if (!post) notFound();
return {post.title};
}
export default async function Docs({ params }: { params: Promise }) {
const { slug = [] } = await params;
const path = slug.join('/') || 'index';
return ;
}
Итог
Next 15: await params; [[...slug]] для base + nested paths; notFound() — idiomatic escape.