Routing & links
How the framework-agnostic library integrates with your router.
The core adminlte-vue library never imports a router. Instead, LteDashboardLayout takes a small set of props that let you wire it to whatever routing solution your app uses — Nuxt, Vue Router, or plain anchors. This keeps the library framework-agnostic while still giving you active-link highlighting and working navigation in the command palette.
The three integration points
| Prop | Type | Default | What it does |
|---|---|---|---|
currentPath | string | '/' | The current route path. Used for active-link detection in the sidebar — the nav item whose href matches gets the active state. |
linkComponent | string | Component | 'a' | The component used to render sidebar and palette links. Pass your router's link component (e.g. NuxtLink) for client-side navigation. |
navigate | (href: string) => void | — | Callback invoked when a command-palette result is chosen. Wire it to your router's programmatic navigation. |
By default the layout renders plain <a> tags and reads currentPath as '/', so it works with zero configuration — links just do full-page navigation.
Nuxt example
In Nuxt, pull the current path from useRoute(), resolve NuxtLink for client-side navigation, and pass navigateTo as the palette's navigate callback.
<script setup lang="ts">
import { resolveComponent } from 'vue'
import type { MenuNode } from 'adminlte-vue'
const route = useRoute()
const NuxtLink = resolveComponent('NuxtLink')
const menuItems: MenuNode[] = [
{ type: 'header', text: 'MAIN' },
{ type: 'item', text: 'Dashboard', href: '/', icon: 'bi-speedometer' },
{
type: 'group',
text: 'Pages',
icon: 'bi-files',
children: [
{ type: 'item', text: 'Profile', href: '/pages/profile' },
{ type: 'item', text: 'Settings', href: '/pages/settings' },
],
},
]
</script>
<template>
<LteDashboardLayout
:menu-items="menuItems"
:current-path="route.path"
:link-component="NuxtLink"
:navigate="navigateTo"
>
<slot />
</LteDashboardLayout>
</template>
The @adminlte/nuxt module auto-registers LteDashboardLayout and auto-imports the MenuNode type, so no manual component import is needed in a Nuxt app.
Vue Router example
The same props work with plain Vue Router — resolve RouterLink, read the path from the current route, and use router.push for the palette.
<script setup lang="ts">
import { resolveComponent } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { LteDashboardLayout, type MenuNode } from 'adminlte-vue'
const route = useRoute()
const router = useRouter()
const RouterLink = resolveComponent('RouterLink')
const menuItems: MenuNode[] = [
{ type: 'item', text: 'Dashboard', href: '/', icon: 'bi-speedometer' },
]
</script>
<template>
<LteDashboardLayout
:menu-items="menuItems"
:current-path="route.path"
:link-component="RouterLink"
:navigate="(href) => router.push(href)"
>
<RouterView />
</LteDashboardLayout>
</template>
Most router link components (
NuxtLink,RouterLink) accept anhref/toprop and render an anchor, so the sidebar's link rendering stays compatible. With the default'a', links navigate with a full page load.
The menu structure
A single MenuNode[] array drives both the sidebar navigation tree and the ⌘K command palette. MenuNode is a discriminated union of three node types, distinguished by the type field.
MenuHeader
A non-interactive section label.
| Field | Type | Description |
|---|---|---|
type | 'header' | Discriminant. |
text | string | The label text. |
MenuItem
A clickable leaf link.
| Field | Type | Description |
|---|---|---|
type | 'item' | Discriminant. |
text | string | Link label. |
href | string | Link target. Matched against currentPath for the active state. |
icon | string | Bootstrap Icons class, e.g. 'bi-speedometer' (with or without the leading bi). |
iconColor | BootstrapTheme | Icon color variant. |
badge | string | number | Optional badge content. |
badgeColor | BootstrapTheme | Badge color variant. |
target | '_blank' | '_self' | Anchor target. |
MenuGroup
A collapsible submenu (treeview) that nests further MenuNodes.
| Field | Type | Description |
|---|---|---|
type | 'group' | Discriminant. |
text | string | Group label. |
icon | string | Bootstrap Icons class. |
iconColor | BootstrapTheme | Icon color variant. |
badge | string | number | Optional badge content. |
badgeColor | BootstrapTheme | Badge color variant. |
children | MenuNode[] | Nested nodes — groups can nest other groups for multi-level menus. |
import type { MenuNode } from 'adminlte-vue'
const menuItems: MenuNode[] = [
{ type: 'header', text: 'NAVIGATION' },
{ type: 'item', text: 'Dashboard', href: '/', icon: 'bi-speedometer' },
{
type: 'group',
text: 'Pages',
icon: 'bi-files',
badge: 4,
badgeColor: 'secondary',
children: [
{ type: 'item', text: 'Profile', href: '/pages/profile' },
{
type: 'group',
text: 'Auth',
children: [
{ type: 'item', text: 'Login', href: '/login' },
{ type: 'item', text: 'Register', href: '/register' },
],
},
],
},
]
Active-link detection & the treeview
The sidebar compares each MenuItem's href against currentPath to apply the active class. Because currentPath is reactive, the highlighted item updates automatically on navigation when you wire it to route.path.
For nested menus, set accordion on the layout to keep only one group open at a time:
<LteDashboardLayout :menu-items="menuItems" :current-path="route.path" :accordion="true">
<slot />
</LteDashboardLayout>