Next.js - Dynanic API Routes
Next.js - Dynamic Routes and Data Fetching
Section titled “Next.js - Dynamic Routes and Data Fetching”Dynamic routes allow you to create pages from dynamic data, such as blog posts, product details, or user profiles, where the URL structure depends on parameters.
In the App Router, dynamic segments are defined using square brackets [] in folder names. For example, app/posts/[slug]/page.tsx creates routes like /posts/my-first-post, /posts/learning-nextjs, etc.
Example: Creating Dynamic Blog Post Pages
Section titled “Example: Creating Dynamic Blog Post Pages”Let’s build a simple blog where each post has its own page based on a unique ‘slug’.
Step 1: Define Data Source
Create a utility file to simulate fetching blog post data. Create lib/posts.ts (create the lib directory in the project root if it doesn’t exist):
export interface Post { slug: string; title: string; content: string; date: string;}
// Simulate a database or API callconst posts: Post[] = [ { slug: 'getting-started-with-nextjs', title: 'Getting Started with Next.js', content: 'Next.js is a React framework for production...', date: '2024-01-10', }, { slug: 'dynamic-routing-explained', title: 'Dynamic Routing Explained', content: 'Learn how dynamic routes work in the App Router...', date: '2024-01-15', },];
// Function to get all possible slugs (for static generation)export async function getAllPostSlugs(): Promise<{ slug: string }[]> { // In a real app, fetch this from your CMS or database return posts.map(post => ({ slug: post.slug }));}
// Function to get post data by slugexport async function getPostData(slug: string): Promise<Post | null> { // In a real app, fetch this from your CMS or database const post = posts.find(p => p.slug === slug); return post || null;}Step 2: Create the Dynamic Page Component
Create the file app/posts/[slug]/page.tsx. The folder name [slug] indicates that slug is a dynamic parameter.
import { getPostData, getAllPostSlugs } from '@/lib/posts'; // Using path alias '@'import { notFound } from 'next/navigation';import { Metadata } from 'next';
interface PostPageProps { params: { slug: string; // The dynamic segment value };}
// Function to generate Metadata dynamicallyexport async function generateMetadata({ params }: PostPageProps): Promise<Metadata> { const post = await getPostData(params.slug); if (!post) { return { title: 'Post Not Found' }; } return { title: post.title };}
// Function to generate static paths at build timeexport async function generateStaticParams() { const slugs = await getAllPostSlugs(); // Returns an array like: [{ slug: 'post-1' }, { slug: 'post-2' }] return slugs;}
// The Page componentexport default async function PostPage({ params }: PostPageProps) { const post = await getPostData(params.slug);
// Handle cases where the post data isn't found if (!post) { notFound(); // Renders the nearest not-found.tsx page or a default 404 }
return ( <article> <h1>{post.title}</h1> <p><time dateTime={post.date}>{post.date}</time></p> <div>{post.content}</div> {/* Add a link back if desired */} {/* <Link href="/posts">Back to Posts List</Link> */} </article> );}Explanation
Section titled “Explanation”[slug]Folder: Defines a dynamic route segment namedslug.paramsProp: The page component receives aparamsprop containing the actual value of the dynamic segment(s) for the current request (e.g.,{ slug: 'getting-started-with-nextjs' }).generateStaticParams(): (Optional but recommended for static generation) This function tells Next.js which possible values ofslugexist at build time. Next.js will pre-render a static HTML page for each path returned by this function. If a user requests a path not generated here, Next.js might try to generate it on-demand or show a 404, depending on configuration (dynamicParamsoption inlayout.jsorpage.js, default istrue).- Data Fetching: The
PostPagecomponent is a Server Component, so it directly fetches data usingawait getPostData(params.slug). No need forgetStaticPropsorgetServerSidePropslike in the Pages Router. notFound(): A helper function fromnext/navigationused to gracefully handle cases where data for the requested slug doesn’t exist, rendering a 404 page.generateMetadata(): (Optional) Allows generating page metadata (like title, description) dynamically based on the fetched data.
Start Development Server
Section titled “Start Development Server”Run the development server:
npm run devVerify Output
Section titled “Verify Output”-
Open
http://localhost:3000/posts/getting-started-with-nextjsin your browser. You should see the content for the first blog post. -
Open
http://localhost:3000/posts/dynamic-routing-explained. You should see the content for the second blog post. -
Try navigating to a non-existent slug like
http://localhost:3000/posts/invalid-slug. You should see a 404 Not Found page (either a customnot-found.tsxif you created one, or the default Next.js 404 page).