Welcome back, blog architects! We’ve laid down our core layout components, setting a sleek foundation with a blurry navbar
, multi-column footer, and tailored page layouts. Now, let’s amp up the UX with Navigation, Cards & Grids, and some Interactive Elements, channeling modern’s bold aesthetic—think responsive menus, animated cards, and engaging hover effects. We're going wild with loads of creativity here, leveraging Next.js 15.x.x
’s server-side magic and Tailwind CSS
4.x.x’s modern utilities, all while ensuring the code is digestible for newbies and SEO-optimized. Let’s dive into this vibrant continuation!
Navigation: Guiding Users with Style
Navigation is the compass of our blog—intuitive, responsive, and visually striking. We’ll craft a desktop menu with dropdowns, a mobile off-canvas menu, SEO-friendly breadcrumbs, and dynamic pagination.
src/components/DesktopMenu.tsx
– Horizontal Menu with Dropdowns
"use client"; // Client-side for dropdown interactivity import Link from "next/link"; import { useState } from "react"; import { FaChevronDown } from "react-icons/fa"; export default function DesktopMenu() { const [isDropdownOpen, setIsDropdownOpen] = useState(false); // Tracks dropdown state return ( <nav> {/* Simple Links */} <Link href="/about">About</Link> <Link href="/blog">Blog</Link> {/* Dropdown Menu */} <div onMouseEnter={() => setIsDropdownOpen(true)} onMouseLeave={() => setIsDropdownOpen(false)} > Categories {isDropdownOpen && ( <ul> <li>Tech</li> <li>Lifestyle</li> <li>Coding</li> </ul> )} </div> <Link href="/search">Search</Link> </nav> ); }
Why It’s Awesome
- Dropdown: A hover-triggered menu with
backdrop-blur-md
for a glassy effect, fading in/out smoothly. - Hover Effects: Links scale up with
hover:scale-105
—a subtle nod to modern design’s interactivity. - Accessibility: ARIA attributes enhance screen reader support.
src/components/MobileMenu.tsx
– Off-Canvas with Animations
Already integrated into BlurNavbar.tsx
from the last section—its off-canvas design uses translate-y
animations for a slick mobile experience.
src/components/Breadcrumbs.tsx
– SEO-Friendly Navigation
import Link from "next/link"; type Crumb = { label: string; href: string }; export default function Breadcrumbs({ crumbs }: { crumbs: Crumb[] }) { return ( <nav> <Link href="/">Home</Link> {crumbs.map((crumb, index) => ( <span key={crumb.href}> / {index === crumbs.length - 1 ? ( <span>{crumb.label}</span> ) : ( <Link href={crumb.href}>{crumb.label}</Link> )} </span> ))} </nav> ); }
Usage Example
In src/app/blog/[slug]/page.tsx
, add:
<Breadcrumbs crumbs={[ { label: "Blog", href: "/blog" }, { label: "Post Title", href: "/blog/post-title" }, ]} />
Why It Shines
- SEO: Links improve crawlability; the final crumb is text-only for current page semantics.
- Responsive: Wraps gracefully on small screens.
src/components/Pagination.tsx
– Dynamic Pagination
"use client"; import Link from "next/link"; import { usePathname, useSearchParams } from "next/navigation"; export default function Pagination({ totalPages, basePath, }: { totalPages: number; basePath: string; }) { const pathname = usePathname(); const searchParams = useSearchParams(); const currentPage = Number(searchParams.get("page")) || 1; const pages = Array.from({ length: totalPages }, (_, i) => i + 1); return ( <div> {pages.map((page) => ( <Link key={page} href={`${pathname}?page=${page}`} className={currentPage === page ? "active" : ""} > {page} </Link> ))} </div> ); }
Usage Example
In src/app/blog/page.tsx
, add:
<Pagination totalPages={10} basePath="/blog" />
Why It’s Great
- Dynamic: Uses Next.js’s
useSearchParams
for page tracking. - Styling: Rounded buttons with hover transitions aligned with modern web design polish.
Cards & Grids: Visual Storytelling
Cards are the heartbeat of our blog’s content—responsive, interactive, and eye-catching.
src/components/PostCard.tsx
– Enhanced from Last Section
Updated with more flair:
import Link from "next/link"; import Image from "next/image"; type Post = { slug: string; frontmatter: { title: string; description: string; imageOg?: string; category: string; }; }; export default function PostCard({ post, variant = "grid", }: { post: Post; variant?: "grid" | "list"; }) { return ( <div> {/* Image with Hover Zoom */} {post.frontmatter.imageOg && ( <Image src={post.frontmatter.imageOg} alt={post.frontmatter.title} width={300} height={200} className="hover:scale-105 transition-transform" /> )} {/* Content */} <div> <span>{post.frontmatter.category}</span> <h3>{post.frontmatter.title}</h3> <p>{post.frontmatter.description}</p> </div> </div> ); }
What’s New?
- Category Badge: A rounded tag adds visual hierarchy.
- Hover Effects: Card lifts with
hover:shadow-xl
and image zooms—pure modern design's energy. - Responsive Images:
sizes
attribute optimizes image loading.
src/components/CategoryCard.tsx
– Category Highlights
import Link from "next/link"; export default function CategoryCard({ category, count, }: { category: string; count: number; }) { return ( <div> {/* Overlay Effect */} <div> <span>{category}</span> <span>{count} Posts</span> </div> </div> ); }
Usage Example
In src/app/page.tsx
’s trending section:
<CategoryCard category="Tech" count={15} />
Why It Pops
- Gradient: A bold background with a hover overlay adds depth.
- Relative Positioning: Ensures text stays above the overlay.
src/components/AuthorCard.tsx
– Author Spotlight
import Image from "next/image"; import { FaTwitter, FaLinkedin } from "react-icons/fa"; export default function AuthorCard({ name, bio, avatar, twitter, linkedin, }: { name: string; bio: string; avatar: string; twitter?: string; linkedin?: string; }) { return ( <div> <Image src={avatar} alt={name} width={100} height={100} /> <h3>{name}</h3> <p>{bio}</p> {twitter && <a href={twitter}><FaTwitter /></a>} {linkedin && <a href={linkedin}><FaLinkedin /></a>} </div> ); }
Why It Works
- Compact: A clean layout for author bios, with social icons for engagement.
- Dark Mode: Tailwind’s
dark:
classes ensure readability.
Interactive Elements: Engaging Users
Let’s add some interactivity with hover effects and reusable components.
src/components/HoverImage.tsx
– Image with Zoom
import Image from "next/image"; export default function HoverImage({ src, alt, width, height, }: { src: string; alt: string; width: number; height: number; }) { return ( <div className="group"> <Image src={src} alt={alt} width={width} height={height} className="group-hover:scale-110 transition-transform" loading="lazy" /> </div> ); }
Why It’s Engaging
- Zoom:
group-hover:scale-110
creates a subtle, inviting effect. - Lazy Loading: Native
loading="lazy"
boosts performance.
src/components/Tooltip.tsx
– Contextual Info
"use client"; import { useState } from "react"; export default function Tooltip({ content, children, }: { content: string; children: React.ReactNode; }) { const [isVisible, setIsVisible] = useState(false); return ( <div onMouseEnter={() => setIsVisible(true)} onMouseLeave={() => setIsVisible(false)} > {children} {isVisible && <span>{content}</span>} </div> ); }
Usage Example
<Tooltip content="This is a tooltip"> <button>Click here</button> </Tooltip>
Why It’s Handy
- Simple: A hover-triggered tooltip with Tailwind styling.
- Accessible: Naturally works with mouse and touch (though keyboard support could be added).
To Be Continued
We’ve tackled Navigation, Cards & Grids, and started Interactive Elements—all with modern-design-inspired flair, responsive design, and SEO-friendly code. This is part two of a multi-part journey due to the epic scope you’ve set!
Top comments (0)