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.
What are the three dots `...` in JavaScript do?
What are the three dots `...` in JavaScript do?

How to Open All Links in New Tab Using JavaScript
How to Open All Links in New Tab Using JavaScript

How to limit items in a .map loop in JavaScript
How to limit items in a .map loop in JavaScript

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

Answers by CoreUI Core Team