Overview
The Nav component provides the primary site navigation with a responsive design that adapts from a mobile hamburger menu to a horizontal desktop navigation. It includes menu items, social media links, and theme toggle integration.
Props
The Nav component accepts no props. Menu items and social links are hardcoded within the component.
Features
- Responsive Menu: Hamburger menu on mobile, horizontal nav on desktop
- Active Page Highlighting: Current page link is visually highlighted
- Social Media Icons: Links to Twitter, GitHub, YouTube, CodePen, Dribbble, Twitch
- Theme Toggle Integration: Built-in dark/light mode switcher
- Progressive Enhancement: Menu works without JavaScript
- Custom Element: Uses Web Components for menu toggle functionality
Text Links
The main navigation items defined in the component:
const textLinks = [
{ label: 'Home', href: '/' },
{ label: 'Work', href: '/work/' },
{ label: 'About', href: '/about/' },
];
Social Icon Links
const iconLinks = [
{ label: 'Twitter', href: 'https://twitter.com/juanrocciax', icon: 'twitter-logo' },
{ label: 'GitHub', href: 'https://github.com/JuanRoccia', icon: 'github-logo' },
{ label: 'YouTube', href: 'https://www.youtube.com/channel/UCAGgGhZin_pUFnk_q6wyZew', icon: 'youtube-logo' },
{ label: 'CodePen', href: 'https://codepen.io/J-u-a-n', icon: 'codepen-logo' },
{ label: 'dribbble', href: 'https://dribbble.com/juanroccia', icon: 'dribbble-logo' },
{ label: 'Twitch', href: 'https://twitch.tv/me', icon: 'twitch-logo' },
];
Usage
---
import Nav from '../components/Nav.astro';
---
<Nav />
The Nav component is typically included in the BaseLayout component and appears at the top of every page.
Real-World Example
In BaseLayout
From src/layouts/BaseLayout.astro:
<body>
<Nav />
<slot />
<Footer />
</body>
Responsive Behavior
Mobile (< 50em)
- Hamburger menu button in top-right
- Menu items displayed vertically in dropdown
- Social icons visible in menu footer
- Theme toggle in menu footer
Desktop (≥ 50em)
- Horizontal navigation bar with rounded pill styling
- Menu items displayed inline
- Social icons hidden until 60em+ breakpoint
- Theme toggle positioned on right side
JavaScript Functionality
The Nav component includes a custom MenuButton Web Component that:
- Shows/hides the menu when hamburger button is clicked
- Automatically expands menu on desktop viewports
- Hides hamburger button on desktop
- Works without JavaScript (menu shown by default, then hidden when JS loads)
class MenuButton extends HTMLElement {
constructor() {
super();
// Inject menu toggle button
this.appendChild(this.querySelector('template').content.cloneNode(true));
const btn = this.querySelector('button');
// Hide menu (shown by default for no-JS)
const menu = document.getElementById('menu-content');
menu.hidden = true;
// Toggle on click
btn.addEventListener('click', () => setExpanded(menu.hidden));
// Auto-expand on large screens
const mediaQueries = window.matchMedia('(min-width: 50em)');
mediaQueries.addEventListener('change', handleViewports);
}
}
Active Link Detection
The navigation automatically highlights the current page:
<a
aria-current={Astro.url.pathname === href}
class:list={[
'link',
{
active:
Astro.url.pathname === href ||
(href !== '/' && Astro.url.pathname.startsWith(href)),
},
]}
href={href}
>
{label}
</a>
Customization
To customize the navigation:
- Edit Menu Items: Modify the
textLinks array in Nav.astro
- Update Social Links: Edit the
iconLinks array with your profile URLs
- Change Site Title: Update the text in the
.site-title link
- Modify Logo Icon: Change the
icon prop in the site title
The Nav component relies on the Icon and ThemeToggle components. Make sure these are available when using Nav.
Accessibility Features
- ARIA Labels: Menu button includes
aria-expanded attribute
- Screen Reader Text: Social links have
.sr-only labels
- Keyboard Navigation: All links and buttons are keyboard accessible
- Current Page: Uses
aria-current to indicate active page
- Forced Colors Mode: Supports high contrast themes
The Nav component uses CSS custom properties for theming, making it easy to adjust colors through your global CSS variables.