
Master the Hybrid Header: Building a Dynamic Navigation Menu in Next.js 15
In this second tutorial of our Next.js Mastery series, we are moving beyond "Hello World" to build a real-world, database-driven navigation menu. We will explore how to combine Server Components (for database fetching) and Client Components (for interactivity) to create a high-performance Header.
1. The File Structure
For a clean and professional architecture, we separate our logic into a dedicated component folder. This makes our code easier to manage as the project grows.
Plaintext
src/
└── components/
└── Header/
└── Menu/
├── Menu.jsx (Server Component - Data Fetching)
└── MenuClient.jsx (Client Component - UI & Interactivity)
2. The Code Explanation
Phase 1: The Server Component (Menu.jsx)
This is the entry point. In Next.js, components are Server Components by default.
Why do we do this? We want to fetch our categories directly from the database using Prisma. Doing this on the server means the database credentials never leave the server, making it highly secure and fast.
JavaScript
import prisma from "@/lib/prisma";
import MenuClient from './MenuClient';
export default async function Menu() {
// 1. Database Fetching: Getting live categories from Prisma
const categories = await prisma.category.findMany({
orderBy: { name: 'asc' },
});
// 2. Passing data to the Client Component
return <MenuClient categories={categories} />;
}
Phase 2: The Client Component (MenuClient.jsx)
We use the 'use client'; directive here because we need browser-only features like useState (for the mobile toggle) and usePathname (to highlight the active link).
How it works:
Active Link Highlighting: It uses
usePathname()to check which page the user is on. If the current URL matches the link, it applies a bold style (text-gray-900 font-semibold).Mobile Interactivity: It manages an
openstate. When you click the "Hamburger" icon, it toggles the mobile menu visibility using Tailwind CSS transitions.Data Rendering: it maps through the
categoriesarray received from the server to generate dynamic links.
3. Why This Architecture? (The "Why" and "How")
The Hybrid Approach
In Next.js, we don't want everything to be a Client Component because it makes the JavaScript bundle larger. By using this hybrid approach:
Speed: The category list is fetched on the server during the initial request.
SEO: Search engines see all the navigation links immediately in the HTML.
UX: The mobile menu feels snappy because the toggle logic happens on the client-side.
Key Logic Breakdowns:
sticky top-0: Keeps the menu at the top of the screen while scrolling.z-50: Ensures the menu stays on top of all other content (like ads or images).max-h-0tomax-h-96: A clever Tailwind trick to animate the mobile menu opening without needing a complex animation library.The Code Implementation
JavaScript
// src/app/page.js import Menu from "@/components/Header/Menu/Menu"; export default function HomePage() { return ( <main> {/* 1. The Menu Component is placed at the top */} <Menu /> {/* 2. The rest of your page content */} <section className="container mx-auto px-4 py-10"> <h1 className="text-4xl font-bold">Welcome to Wisemix Media</h1> <p className="mt-4 text-gray-600"> This is our home page where the dynamic menu is now active. </p> </section> </main> ); }
Next.js Mastery: Technical Glossary
Here are the key terms used in this tutorial explained in simple English:
TermSimple ExplanationServer ComponentA component that runs only on the server. It is great for fetching data securely from a database (like Prisma) without slowing down the user's browser.Client ComponentA component that runs in the browser. It allows users to interact with the page, like clicking buttons, using forms, or opening a menu.ToggleA logic that switches between two states (e.g., Open vs. Closed). In our menu, it controls the mobile view visibility.SnappyA term for a user interface that responds instantly. It means the website feels fast and smooth to the user.PrismaAn ORM (Object-Relational Mapper) that makes it easy to talk to your database using JavaScript instead of complex SQL queries.Hook (useState)A special React function that allows a component to "remember" things. Here, it remembers if the mobile menu is open or shut.HydrationThe process where Next.js adds interactivity (JavaScript) to a static page sent from the server so that buttons and menus start working.Sticky HeaderA design technique where the menu stays "stuck" at the top of the screen even when the user scrolls down the page.z-index (z-50)A CSS property that controls which element stays on top. z-50 ensures our menu is always visible above images or ads.





