Dynamic Routes¶
So far, we've created static routes like /, /about, and /dashboard. But what if you need to create pages for specific items, like individual tasks in our Task Management App? Each task will have a unique ID, and we don't want to create a separate page.tsx file for every single task. This is where Dynamic Routes come in handy.
Dynamic Routes allow you to create routes whose segments are determined at request time. This is achieved by using square brackets [] around a folder name in your app directory.
Creating Dynamic Segments [slug] for Individual Task Pages (/tasks/[id]/page.tsx)¶
For our Task Management App, we'll want to have a dedicated page for viewing and editing a single task. This page will be accessible via a URL like /tasks/123 or /tasks/abc-456, where 123 or abc-456 is the unique ID of the task.
To implement this, we'll create a dynamic segment within the tasks route.
-
Create new folders within your
appdirectory to represent the dynamic route:my-task-app/ └── app/ ├── ... └── tasks/ <-- NEW DIRECTORY (if not already present from outline) └── [id]/ <-- NEW DYNAMIC SEGMENT FOLDER └── page.tsx <-- NEW FILE- The
tasksfolder will eventually contain apage.tsxfor a list of all tasks (we'll add that later). For now, it just serves as the parent for our dynamic route. - The
[id]folder is the key. The square brackets indicate thatidis a dynamic parameter. Next.js will automatically capture the value in the URL at this position and make it available to your component. - Add the following content to the
app/tasks/[id]/page.tsxfile:
app/tasks/[id]/page.tsx// app/tasks/[id]/page.tsx // This is a dynamic route segment for displaying a single task by its ID. // It is a Server Component by default. // The 'params' prop is automatically provided by Next.js for dynamic routes. // It contains an object where keys match the dynamic segment names (e.g., 'id'). export default async function SingleTaskPage({ params }: { params: { id: string } }) { const { id } = await params; // Destructure the 'id' from params return ( <div className="flex flex-col items-center justify-center p-6 bg-white shadow-md rounded-lg"> <h2 className="text-3xl font-bold text-blue-700 mb-4">Task Details</h2> <p className="text-lg text-gray-700 mb-2"> You are viewing task with ID: <span className="font-semibold text-indigo-600">{id}</span> </p> <p className="text-md text-gray-500"> (Content for this specific task will be loaded here in future modules) </p> </div> ); } - The
Accessing Dynamic Parameters¶
As you can see in the SingleTaskPage component above, Next.js automatically provides the dynamic segment values through the params prop to the page.tsx (and layout.tsx) components.
- The
paramsprop is an object. - The keys of this object correspond to the names of your dynamic segments (e.g.,
idin[id]). - The values are the actual values from the URL.
In our example, if a user navigates to /tasks/task-123, the params object will be { id: 'task-123' }. We can then destructure id from params to use it in our component.
Summary¶
What we've done:
- We've created a new dynamic route
app/tasks/[id]/page.tsx. - We've shown how to access the dynamic
idparameter from theparamsprop in a Server Component. - The page now displays the ID retrieved from the URL.
To test your dynamic route:
- Ensure your development server is running (
npm run dev). - Open your browser and try navigating to different URLs:
http://localhost:3000/tasks/1http://localhost:3000/tasks/my-first-taskhttp://localhost:3000/tasks/xyz-789
You should see the "Task Details" page with the specific ID you entered in the URL displayed on the page. This is the foundation for creating pages for individual items in your application, a crucial pattern for any data-driven web app.
In the next section, we'll learn how to use the <Link> component to navigate between these routes efficiently and with optimized performance.