How to build a navbar in Vue

Navigation bars provide primary navigation structure for web applications, offering consistent access to main sections and improving user orientation across pages. As the creator of CoreUI, a widely used open-source UI library, I’ve built navigation systems in Vue applications throughout my 11 years of Vue development. The most effective approach is creating a navbar component with Vue Router integration and responsive mobile menu toggle. This method ensures seamless navigation with active route highlighting and mobile-friendly collapsible menus.

Create a navbar component with Vue Router links and mobile menu toggle for responsive design.

<template>
  <nav class="navbar">
    <div class="navbar-container">
      <router-link to="/" class="navbar-brand">
        MyApp
      </router-link>

      <button @click="isMobileMenuOpen = !isMobileMenuOpen" class="navbar-toggle">
        
      </button>

      <ul :class="['navbar-menu', { open: isMobileMenuOpen }]">
        <li>
          <router-link to="/" @click="isMobileMenuOpen = false">
            Home
          </router-link>
        </li>
        <li>
          <router-link to="/about" @click="isMobileMenuOpen = false">
            About
          </router-link>
        </li>
        <li>
          <router-link to="/contact" @click="isMobileMenuOpen = false">
            Contact
          </router-link>
        </li>
      </ul>
    </div>
  </nav>
</template>

<script setup>
import { ref } from 'vue'

const isMobileMenuOpen = ref(false)
</script>

<style scoped>
.navbar {
  background: #333;
  color: white;
  padding: 1rem 0;
}

.navbar-container {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 1rem;
}

.navbar-brand {
  font-size: 1.5rem;
  font-weight: bold;
  color: white;
  text-decoration: none;
}

.navbar-toggle {
  display: none;
  background: none;
  border: none;
  color: white;
  font-size: 1.5rem;
  cursor: pointer;
}

.navbar-menu {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  gap: 2rem;
}

.navbar-menu a {
  color: white;
  text-decoration: none;
  padding: 0.5rem 1rem;
}

.navbar-menu a.router-link-active {
  background: #555;
  border-radius: 4px;
}

@media (max-width: 768px) {
  .navbar-toggle {
    display: block;
  }

  .navbar-menu {
    display: none;
    flex-direction: column;
    position: absolute;
    top: 60px;
    left: 0;
    right: 0;
    background: #333;
    padding: 1rem;
  }

  .navbar-menu.open {
    display: flex;
  }
}
</style>

Here router-link components create navigation links with automatic active class application. The navbar-toggle button controls isMobileMenuOpen state for mobile menu visibility. The @click handlers on links close the mobile menu after navigation. The router-link-active class automatically applies to the current route’s link, providing visual feedback. Media queries hide the desktop menu and show the toggle button on mobile devices, while the open class controls mobile menu visibility.

Best Practice Note:

This is the navbar pattern we implement in CoreUI Vue templates for consistent navigation across applications. Add dropdown submenus for complex navigation hierarchies, implement sticky positioning for always-visible navigation, and use Vue Router’s beforeEach guard to close mobile menus on route changes automatically.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to replace all occurrences of a string in JavaScript?
How to replace all occurrences of a string in JavaScript?

How to get element ID in JavaScript
How to get element ID in JavaScript

How to check if a string is a number in JavaScript
How to check if a string is a number in JavaScript

How to check if an element is visible in JavaScript
How to check if an element is visible in JavaScript

Answers by CoreUI Core Team