Dynamic routing is less about URLs and more about contracts. A good slug route defines how content is found, what happens when it is missing, and how related pages connect together.
Make the slug the stable contract
Whether content starts in a static array, a CMS, or a relational database, the page should only care about receiving a post that matches the slug. That separation keeps the interface portable.
TypeScriptexport function getPostBySlug(slug: string, posts: Post[]) {\n return posts.find((post) => post.slug === slug);\n}
- Normalize trailing slashes before matching routes.
- Render a useful not-found state for unknown content.
- Generate links from the same slug field that powers lookup.
When data fetching changes later, the route should not need a redesign. It should simply receive the same shape from a stronger source.


