How to Create a Responsive Navbar in Next.js with TypeScript and Zustand State Management
Mudasir FayazA well-designed navbar is the backbone of any good website. It guides users, defines structure, and enhances usability. In this tutorial, we’ll build a responsive navbar in Next.js usingTypeScript and Zustand — a lightweight state management library that keeps your code clean and predictable.
Why Use Zustand for Navbar State?
Zustand is a minimal and fast state management solution for React. Unlike Redux or Context API, it doesn’t require boilerplate or complex setup. You can use it to easily manage your mobile menu’s open/close state across components — perfect for handling navbars.
“Zustand gives you global state without the complexity — just pure React logic with simplicity.”
Project Setup
Let’s create a new Next.js project with TypeScript enabled:
npx create-next-app@latest my-navbar-app --typescript
cd my-navbar-app
npm install zustandOnce installed, you’re ready to set up Zustand and build your responsive navigation component.
Step 1: Create a Zustand Store
Zustand uses simple hooks for global state. Let’s create one for managing our mobile menu:
// store/navStore.ts
import { create } from 'zustand';
interface NavState {
isOpen: boolean;
toggleMenu: () => void;
}
export const useNavStore = create<NavState>((set) => ({
isOpen: false,
toggleMenu: () => set((state) => ({ isOpen: !state.isOpen })),
}));The useNavStore hook lets any component access and modify the navbar state globally.
Step 2: Build the Navbar Component
Next, let’s create a responsive navbar that uses Zustand to toggle the mobile menu.
// components/Navbar.tsx
'use client';
import Link from 'next/link';
import { useNavStore } from '@/store/navStore';
export default function Navbar() {
const { isOpen, toggleMenu } = useNavStore();
return (
<nav className="fixed top-0 left-0 w-full bg-white shadow-md z-50">
<div className="max-w-6xl mx-auto flex items-center justify-between p-4">
<Link href="/" className="text-xl font-semibold text-gray-800">
MyBrand
</Link>
<button
onClick={toggleMenu}
className="md:hidden text-gray-700 focus:outline-none"
>
☰
</button>
<div
className={`flex-col md:flex-row md:flex gap-6 md:static absolute left-0 top-16 w-full bg-white md:w-auto md:bg-transparent transition-all duration-300 ease-in-out ${isOpen ? 'flex' : 'hidden'}`}
>
<Link href="/" className="p-2 text-gray-700 hover:text-blue-600">
Home
</Link>
<Link href="/about" className="p-2 text-gray-700 hover:text-blue-600">
About
</Link>
<Link href="/projects" className="p-2 text-gray-700 hover:text-blue-600">
Projects
</Link>
<Link href="/contact" className="p-2 text-gray-700 hover:text-blue-600">
Contact
</Link>
</div>
</div>
</nav>
);
}This navbar becomes fully responsive — showing a hamburger icon on smaller screens while keeping desktop navigation visible.
Step 3: Add Smooth Animation (Optional)
You can easily integrate Framer Motion to animate the menu’s opening and closing transitions:
import { motion, AnimatePresence } from 'framer-motion';
<AnimatePresence>
{isOpen && (
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
transition={{ duration: 0.3 }}
className="flex flex-col gap-4 bg-white md:hidden p-4 shadow-lg"
>
{/* Nav links here */}
</motion.div>
)}
</AnimatePresence>This adds a subtle animation that enhances user experience without hurting performance.
Conclusion
Building a responsive navbar in Next.js using TypeScript and Zustand is simpler than you might think. Zustand helps manage global states without overcomplicating your app, while Tailwind ensures responsive design with minimal CSS. Combine them, and you’ll have a professional, scalable navigation bar ready for any modern web project.