Skip to main content
The NavbarGlass component is a floating navigation bar with glassmorphic styling that adapts its position based on the current route and integrates with the shopping cart.

Overview

Key features:
  • Glassmorphic design with backdrop blur
  • Dynamic positioning (top/bottom based on route)
  • Shopping cart integration with item counter
  • GSAP entrance animations
  • Responsive design for mobile and desktop
  • React Router integration

Props

The NavbarGlass component does not accept props. It uses React Router and the CartContext internally.

Dependencies

react-router-dom
Library
Link and useLocation for navigation and route detection
CartContext
Context
Access to cart state (carrito, setCarritoAbierto)
gsap
Library
For entrance animations

Implementation

import { Link, useLocation } from "react-router-dom";
import { useEffect, useRef } from "react";
import { useCart } from "../../context/CartContext/CartContext.jsx";
import gsap from "gsap";

function NavbarGlass() {
  const navRef = useRef(null);
  const location = useLocation();
  const { carrito, setCarritoAbierto } = useCart();
  const totalItems = carrito.reduce((acc, p) => acc + p.cantidad, 0);

  const isTop = location.pathname.startsWith("/categoria") || 
                location.pathname.startsWith("/producto");

  useEffect(() => {
    const ctx = gsap.context(() => {
      gsap.fromTo(navRef.current,
        { y: isTop ? -40 : 40, opacity: 0 },
        { y: 0, opacity: 1, duration: 1, ease: "power3.out", delay: 0.3 }
      );
    });
    return () => ctx.revert();
  }, [location.pathname]);

  return (
    <header className={`fixed ${isTop ? "top-6" : "bottom-6"} left-1/2 -translate-x-1/2 z-50 w-[90vw] md:w-auto`}>
      <nav ref={navRef} className="flex gap-3 md:gap-6 text-white bg-white/10 backdrop-blur-lg border border-white/20 rounded-xl px-4 md:px-6 py-3 shadow-lg">
        <Link to="/">Inicio</Link>
        <Link to="/categoria/guitarra">Guitarras</Link>
        <Link to="/categoria/piano">Pianos</Link>
        <Link to="/categoria/bateria">Baterías</Link>
        <Link to="/categoria/bajo">Bajos</Link>
        <button onClick={() => setCarritoAbierto(true)} className="relative">
          Carrito
          {totalItems > 0 && (
            <span className="absolute -top-2 -right-4 bg-white text-black text-xs rounded-full w-4 h-4 flex items-center justify-center font-bold">
              {totalItems}
            </span>
          )}
        </button>
      </nav>
    </header>
  );
}

export default NavbarGlass;

Usage

import NavbarGlass from './components/Navbar/NavbarGlass';
import { CartProvider } from './context/CartContext/CartContext';

function App() {
  return (
    <CartProvider>
      <NavbarGlass />
      {/* Other content */}
    </CartProvider>
  );
}

Dynamic Positioning

The navbar changes position based on the current route:
const isTop = location.pathname.startsWith("/categoria") || 
              location.pathname.startsWith("/producto");
  • Top position: On category and product pages
  • Bottom position: On home page
This creates a unique UX where the navbar floats at the bottom of the hero section, then moves to the top on internal pages.

Cart Integration

The navbar displays the total number of items in the cart:
const totalItems = carrito.reduce((acc, p) => acc + p.cantidad, 0);
When items are in the cart, a badge appears:
{totalItems > 0 && (
  <span className="absolute -top-2 -right-4 bg-white text-black text-xs rounded-full w-4 h-4">
    {totalItems}
  </span>
)}
The navbar includes links to:
/
Route
Home page (Inicio)
/categoria/guitarra
Route
Guitar category page
/categoria/piano
Route
Piano category page
/categoria/bateria
Route
Drum category page
/categoria/bajo
Route
Bass category page

Styling & Customization

Glassmorphism Effect

The navbar uses a glassmorphic style:
className="bg-white/10 backdrop-blur-lg border border-white/20 rounded-xl shadow-lg"
  • bg-white/10: 10% white background
  • backdrop-blur-lg: Background blur effect
  • border border-white/20: 20% white border
  • rounded-xl: Large border radius

Responsive Design

className="gap-3 md:gap-6 px-4 md:px-6 py-3"
  • Mobile: Smaller gaps (gap-3) and padding (px-4)
  • Desktop: Larger gaps (gap-6) and padding (px-6)

Animation

Entrance animation adapts based on position:
gsap.fromTo(navRef.current,
  { y: isTop ? -40 : 40, opacity: 0 },  // Slide from top or bottom
  { y: 0, opacity: 1, duration: 1, ease: "power3.out", delay: 0.3 }
);
The animation re-triggers when navigating between pages (when location.pathname changes).

Build docs developers (and LLMs) love