Menu & Sidebar

The sidebar is driven by a single array of MenuNode objects passed to <LteDashboardLayout :menu-items>. The layout resolves active state from currentPath, renders nested groups as collapsible treeviews, and feeds the same tree into the ⌘K command palette.

The menu data shape

MenuNode is a discriminated union on type — a section header, a clickable item, or a collapsible group:

import type { MenuNode } from '@adminlte/vue'

const menu: MenuNode[] = [
  { type: 'item', text: 'Dashboard', href: '/', icon: 'bi-speedometer' },

  { type: 'header', text: 'MANAGEMENT' },

  {
    type: 'group',
    text: 'Pages',
    icon: 'bi-files',
    badge: 3,
    badgeColor: 'info',
    children: [
      { type: 'item', text: 'Profile', href: '/profile' },
      { type: 'item', text: 'Settings', href: '/settings', icon: 'bi-gear' },
    ],
  },

  {
    type: 'item',
    text: 'Documentation',
    href: 'https://adminlte.io',
    icon: 'bi-book',
    target: '_blank',
  },
]

Node fields

FieldOnPurpose
typeall'header' | 'item' | 'group' (the discriminant).
textallThe visible label (or section title for a header).
hrefitemThe link target; matched against currentPath for active state.
iconitem, groupA Bootstrap Icons class, e.g. bi-speedometer (with or without the leading bi).
iconColoritem, groupA BootstrapTheme tint for the icon.
badgeitem, groupA small badge label (string | number).
badgeColoritem, groupA BootstrapTheme for the badge.
targetitem'_blank' | '_self' — e.g. _blank for external links.
childrengroupA nested MenuNode[], rendered as a collapsible treeview.

Rendering links with your router

Pass your router's link component as linkComponent so internal items render as SPA links instead of full page loads; external items (absolute URLs, or any with target="_blank") fall back to a plain anchor automatically:

<script setup lang="ts">
const route = useRoute()
const NuxtLink = resolveComponent('NuxtLink') // or RouterLink from vue-router
</script>

<template>
  <LteDashboardLayout
    :menu-items="menu"
    :current-path="route.path"
    :link-component="NuxtLink"
  >
    <slot />
  </LteDashboardLayout>
</template>

Active state

The sidebar marks items active by comparing each item's href with the currentPath you pass:

  • A leaf item is active when its href matches the current path.
  • A group is active (and its treeview opens) when any descendant item is active.
  • Because the layout is told the path explicitly via the prop, active state is fully SSR-deterministic — no client-only window.location read.

The command palette

The same menu tree is flattened into searchable commands for the ⌘K / Ctrl+K palette. <LteCommandPalette> is part of the default layout; the exported flattenMenuToCommands() helper produces the CommandItem[] list ({ label, href, icon?, group? }) it indexes, so every navigable menu entry is searchable for free.

Build the menu under each route's own component or a shared module and pass it down — there is no central config file in plain Vue. In Nuxt, define it once in app/layouts/default.vue (or a composable) and it is shared across all pages using that layout.


AdminLTE 4 · Vue port Edit on GitHub