Dynamic Routes in Next.js
January 17, 2026
A summary of implementing dynamic routes for posts, improving the homepage layout, and ensuring Next.js compatibility.
This site uses Next.js dynamic routes to serve both blog posts and documentation pages. While both types of content live in the same directory (src/posts/), they're routed differently based on their metadata.
Route Structure
We have two parallel route handlers:
- Posts:
/posts/[slug]- Blog posts and narrative content - Docs:
/docs/[slug]- Technical documentation and feature specs
How It Works
Each route has its own page component and API endpoint, but they work identically:
1. Client Requests a Page
When you visit /posts/some-slug or /docs/some-slug, the respective page component (src/app/posts/[slug]/page.tsx or src/app/docs/[slug]/page.tsx) loads.
2. Fetch Filename from API
The page component calls its API route (/api/posts/[slug] or /api/docs/[slug]) to get the filename for that slug.
3. Dynamic Import
The page then dynamically imports the TSX file from src/posts/ using the filename, extracts both the component and metadata, and renders them.
4. Render with ContentHeader
The ContentHeader component displays metadata (author, date, feature, project tags), then the actual content component renders below it.
Current Implementation Notes
Right now there's code duplication between the posts and docs page components - they're nearly identical except for which API they call and which filter function they use. This could be refactored into a shared component, but for now the duplication is minimal and explicit.
The filtering happens in src/lib/posts.ts where getAllPosts()excludes docs (items with type: 'doc') and getAllDocs()only includes docs.