···11+---
22+title: Dynamic Breadcrumb in Next.js with Parallel Routes
33+description:
44+ Learn how to create a dynamic breadcrumb in Next.js with parallel routes.
55+author:
66+ name: Thibault Le Ouay Ducasse
77+ url: https://twitter.com/thibaultleouay
88+publishedAt: 2024-08-19
99+image: /assets/posts/dynamic-breadcrumb-nextjs/breadcrumb.png
1010+---
1111+1212+In this post, we'll dive into the process of creating dynamic breadcrumbs in Next.js using parallel routes. Our goal is to build a breadcrumb component that automatically updates based on the current page and its hierarchy, all while leveraging server-side rendering for optimal performance.
1313+1414+## Introduction
1515+1616+Breadcrumbs are an essential navigation aid in web applications, helping users understand their current location within a site's hierarchy. With Next.js 13's introduction of parallel routes, we have new tools to create more dynamic and flexible navigation structures.
1717+1818+1919+You can find the complete, working example for this tutorial on [GitHub](https://github.com/openstatusHQ/nextjs-dynamic-breadcrumb/). The project uses Next.js 15 and demonstrates the implementation of parallel routes alongside our dynamic breadcrumb.
2020+2121+2222+## The Challenge
2323+2424+We're building a website that showcases a catalog of dogs and cats. Our primary challenge is to create a breadcrumb that adapts to the user's current location within the site structure.
2525+2626+### Project Structure
2727+2828+Our repository is organized as follows:
2929+3030+3131+```
3232+src/
3333+ app/
3434+ about/
3535+ page.tsx
3636+ cats/
3737+ page.tsx
3838+ [id]/
3939+ page.tsx
4040+ dogs/
4141+ page.tsx
4242+ [id]/
4343+ page.tsx
4444+```
4545+4646+4747+### Desired Breadcrumb Behavior
4848+4949+5050+1. On the homepage:
5151+5252+`Home`
5353+5454+2. On pet pages (e.g., Dogs or Cats):
5555+5656+`Home > Dogs` or `Home > Cats`
5757+5858+3. On individual pet pages:
5959+6060+Here we only have the pet id, so we need to fetch the pet name from the server side and display it in the breadcrumb.
6161+6262+`Home > Dogs > Dog Name`
6363+6464+The key is to fetch the necessary data on the server side and dynamically update the breadcrumb based on the current route instead of displaying the pet id.
6565+6666+6767+6868+### Parallel route ๐
6969+7070+[Parallel routes](https://nextjs.org/docs/app/building-your-application/routing/parallel-routes) in Next.js allow us to render multiple pages in the same layout simultaneously. This feature is particularly useful for our breadcrumb implementation as it allows us to maintain a consistent navigation structure across different page types.
7171+7272+7373+#### Homepage
7474+7575+In our root layout we will use slot to render the breadcrumb component.
7676+7777+```tsx
7878+export default function RootLayout({
7979+ breadcrumb,
8080+ children,
8181+}: Readonly<{
8282+ breadcrumb: React.ReactNode;
8383+ children: React.ReactNode;
8484+}>) {
8585+ return (
8686+ <html lang="en">
8787+ <body>
8888+ {breadcrumb}
8989+ {children}
9090+ </body>
9191+ </html>
9292+ );
9393+}
9494+```
9595+9696+We need to create a new folder `@breadcrumb` in the `app` folder
9797+9898+Here we create a new file `page.tsx` that will be responsible for rendering the breadcrumb.
9999+100100+```tsx
101101+import {
102102+ Breadcrumb,
103103+ BreadcrumbItem,
104104+ BreadcrumbLink,
105105+ BreadcrumbList,
106106+} from "@/components/ui/breadcrumb";
107107+108108+export default function BreadcrumbSlot() {
109109+ return (
110110+ <Breadcrumb>
111111+ <BreadcrumbList>
112112+ <BreadcrumbItem>
113113+ <BreadcrumbLink href="/">Home</BreadcrumbLink>
114114+ </BreadcrumbItem>
115115+ </BreadcrumbList>
116116+ </Breadcrumb>
117117+ );
118118+}
119119+```
120120+121121+#### Pet pages
122122+123123+We also want to create a catch all components for the dynamic routes in the `app` folder, to achieve this we need to create a new file `page.tsx` in the `@breadcrumb/[...all]` folder.
124124+125125+```tsx
126126+import {
127127+ Breadcrumb,
128128+ BreadcrumbItem,
129129+ BreadcrumbLink,
130130+ BreadcrumbList,
131131+ BreadcrumbPage,
132132+ BreadcrumbSeparator,
133133+} from "@/components/ui/breadcrumb";
134134+import React from "react";
135135+import type { ReactElement } from "react";
136136+137137+export default function BreadcrumbSlot({
138138+ params,
139139+}: { params: { all: string[] } }) {
140140+ const breadcrumbItems: ReactElement[] = [];
141141+ let breadcrumbPage: ReactElement = <></>;
142142+ for (let i = 0; i < params.all.length; i++) {
143143+ const route = params.all[i];
144144+ const href = `/${params.all.at(0)}/${route}`;
145145+ if (i === params.all.length - 1) {
146146+ breadcrumbPage = (
147147+ <BreadcrumbItem>
148148+ <BreadcrumbPage className="capitalize">{route}</BreadcrumbPage>
149149+ </BreadcrumbItem>
150150+ );
151151+ } else {
152152+ breadcrumbItems.push(
153153+ <React.Fragment key={href}>
154154+ <BreadcrumbItem>
155155+ <BreadcrumbLink href={href} className="capitalize">
156156+ {route}
157157+ </BreadcrumbLink>
158158+ </BreadcrumbItem>
159159+ </React.Fragment>,
160160+ );
161161+ }
162162+ }
163163+164164+ return (
165165+ <Breadcrumb>
166166+ <BreadcrumbList>
167167+ <BreadcrumbItem>
168168+ <BreadcrumbLink href="/">Home</BreadcrumbLink>
169169+ </BreadcrumbItem>
170170+ {breadcrumbItems}
171171+ <BreadcrumbSeparator />
172172+ {breadcrumbPage}
173173+ </BreadcrumbList>
174174+ </Breadcrumb>
175175+ );
176176+}
177177+```
178178+This code was taken from the [Jeremy's post](https://jeremykreutzbender.com/blog/app-router-dynamic-breadcrumbs) about dynamic breadcrumbs in Next.js.
179179+180180+#### Dogs and Cats pages
181181+182182+We need to create a new file `page.tsx` in the `@breadcrumb/dogs/[id]` folder, we must follow the exact same structure as our specific pet pages.
183183+In this component we will fetch the pet name from the server side and display it in the breadcrumb.
184184+185185+```tsx
186186+187187+import {
188188+ BreadcrumbItem,
189189+ BreadcrumbLink,
190190+ BreadcrumbList,
191191+ BreadcrumbPage,
192192+ BreadcrumbSeparator,
193193+} from "@/components/ui/breadcrumb";
194194+195195+export default async function BreadcrumbSlot({params}: {params: {id: string}}) {
196196+ // Fetch our cat information from the database
197197+ const cat = await fetchCat({id: params.id});
198198+199199+ return (
200200+ <BreadcrumbList>
201201+ <BreadcrumbItem>
202202+ <BreadcrumbLink href="/">Home</BreadcrumbLink>
203203+ </BreadcrumbItem>
204204+ <BreadcrumbSeparator />
205205+ <BreadcrumbItem>
206206+ <BreadcrumbLink href="/cats">Cats</BreadcrumbLink>
207207+ </BreadcrumbItem>
208208+ <BreadcrumbSeparator />
209209+ <BreadcrumbItem>
210210+ <BreadcrumbPage className="capitalize">{cat.name}</BreadcrumbPage>
211211+ </BreadcrumbItem>
212212+ </BreadcrumbList>
213213+ );
214214+}
215215+```
216216+217217+218218+## Conclusion
219219+220220+By leveraging Next.js parallel routes and server-side rendering, we've created a dynamic breadcrumb component that updates based on the current route and fetches data efficiently on the server side. This approach provides a smooth user experience while maintaining good performance.
221221+222222+Remember to check out the full working example on [GitHub](https://github.com/openstatusHQ/nextjs-dynamic-breadcrumb/) to see how all the pieces fit together in a Next.js 15 project.
223223+224224+Happy coding!