The LNavbar component provides a complete top navigation bar with search functionality, navigation links, notification button, and user avatar dropdown menu.
Props
searchPlaceholder
string
default:"Search..."
Placeholder text for the search input field
Keyboard shortcut to focus the search input
searchItems
DropdownMenuItem[]
default:"[]"
Items to display in the search dropdown (currently not fully implemented)
Navigation links to display in the navbar using UNavigationMenu
User name to display in the avatar dropdown
User email to display in the avatar dropdown
User avatar image source URL
Navigation path when clicking on user info in dropdown
Menu items to display in the user avatar dropdown
Whether to show the search input
Whether to show the notification dot indicator
Model
Two-way binding for the search input value
Events
Emitted when the notification button is clicked
Slots
Custom content for the right side of the navbar (replaces default notifications and user menu)
Usage
Basic Navbar
<template>
<LNavbar
v-model:search-term="searchTerm"
menu-user-name="John Doe"
:menu-items="menuItems"
/>
</template>
<script setup>
const searchTerm = ref('')
const menuItems = [
[
{ label: 'Profile', icon: 'i-lucide-user', onSelect: () => navigateTo('/profile') }
],
[
{ label: 'Logout', icon: 'i-lucide-log-out', onSelect: handleLogout }
]
]
</script>
Complete Navbar with All Features
<template>
<LNavbar
v-model:search-term="searchTerm"
search-placeholder="Search projects, tasks..."
:links="navLinks"
menu-user-name="Jane Smith"
menu-user-email="[email protected]"
menu-user-avatar-src="/images/jane.jpg"
menu-user-to="/profile"
:menu-items="userMenuItems"
:has-notification="hasUnreadNotifications"
@on-click-notifications="openNotifications"
/>
</template>
<script setup>
const searchTerm = ref('')
const hasUnreadNotifications = ref(true)
const navLinks = [
{ label: 'Dashboard', to: '/dashboard', icon: 'i-lucide-layout-dashboard' },
{ label: 'Projects', to: '/projects', icon: 'i-lucide-folder' },
{ label: 'Team', to: '/team', icon: 'i-lucide-users' }
]
const userMenuItems = [
[
{ label: 'Profile', icon: 'i-lucide-user', onSelect: () => navigateTo('/profile') },
{ label: 'Settings', icon: 'i-lucide-settings', onSelect: () => navigateTo('/settings') },
{ label: 'Billing', icon: 'i-lucide-credit-card', onSelect: () => navigateTo('/billing') }
],
[
{ label: 'Documentation', icon: 'i-lucide-book', onSelect: () => window.open('/docs') },
{ label: 'Support', icon: 'i-lucide-life-buoy', onSelect: () => navigateTo('/support') }
],
[
{ label: 'Logout', icon: 'i-lucide-log-out', onSelect: handleLogout }
]
]
function openNotifications() {
console.log('Opening notifications')
}
function handleLogout() {
// Logout logic
}
</script>
Without Search
<template>
<LNavbar
:has-search="false"
:links="links"
menu-user-name="Admin"
:menu-items="menuItems"
/>
</template>
Custom Keyboard Shortcut
<template>
<LNavbar
v-model:search-term="searchTerm"
search-shortcut="meta_k"
search-placeholder="Quick search (⌘K)"
/>
</template>
With Active Notifications
<template>
<LNavbar
v-model:search-term="searchTerm"
:has-notification="notifications.length > 0"
@on-click-notifications="handleNotificationClick"
/>
</template>
<script setup>
const notifications = ref([
{ id: 1, message: 'New comment on your post' },
{ id: 2, message: 'Task assigned to you' }
])
function handleNotificationClick() {
navigateTo('/notifications')
}
</script>
Custom Right Slot
<template>
<LNavbar v-model:search-term="searchTerm">
<template #right>
<UButton variant="ghost" icon="i-lucide-settings">
Settings
</UButton>
<UButton color="primary" icon="i-lucide-plus">
New Project
</UButton>
</template>
</LNavbar>
</template>
Search with Live Results
<template>
<LNavbar
v-model:search-term="searchTerm"
search-placeholder="Search..."
/>
<div v-if="searchTerm" class="search-results">
<div v-for="result in searchResults" :key="result.id">
{{ result.title }}
</div>
</div>
</template>
<script setup>
const searchTerm = ref('')
const searchResults = computed(() => {
if (!searchTerm.value) return []
// Perform search
return performSearch(searchTerm.value)
})
</script>
Multi-level Navigation
<template>
<LNavbar
v-model:search-term="searchTerm"
:links="navigationLinks"
menu-user-name="Developer"
:menu-items="menuItems"
/>
</template>
<script setup>
const navigationLinks = [
{
label: 'Products',
children: [
{ label: 'All Products', to: '/products' },
{ label: 'Categories', to: '/products/categories' },
{ label: 'New Product', to: '/products/new' }
]
},
{
label: 'Orders',
to: '/orders'
}
]
</script>
Responsive Navbar
<template>
<LNavbar
v-model:search-term="searchTerm"
:links="links"
menu-user-name="User"
:menu-items="menuItems"
:class="{ 'border-b': isScrolled }"
/>
</template>
<script setup>
const isScrolled = ref(false)
onMounted(() => {
window.addEventListener('scroll', () => {
isScrolled.value = window.scrollY > 0
})
})
</script>
Keyboard Shortcuts
The search input supports keyboard shortcuts:
- Default:
/ key focuses the search
- Customizable via
searchShortcut prop
- Clear button (X) appears when search has text
Layout Structure
UDashboardNavbar
├── Left Section (gap-8)
│ ├── Search Input (if hasSearch)
│ └── Navigation Menu
└── Right Section (gap-3)
├── Notifications Button
└── User Avatar Dropdown
Styling Customization
The navbar uses Nuxt UI’s theming:
:ui="{ left: 'gap-8', right: 'gap-3' }"
Search Features
- Icon:
i-lucide-search
- Width: Fixed
w-60
- Clear Button: Appears when text is entered
- Shortcut Display: Shows keyboard shortcut as KBD element
- Auto-focus: Can be focused programmatically via shortcut
Notification Button
- Tooltip: “Notifications” with shortcut
N
- Chip: Red dot indicator when
hasNotification is true
- Color: Neutral ghost variant
- Icon:
i-lucide-bell
Source: /home/daytona/workspace/source/app/components/l/l-navbar.vue:97