Navbar / Sidebar
The x-nav
component is a fully featured, highly customizable sidebar navigation built for modern dashboards.
It supports categories, nested submenus, icons, badges, tooltips, dividers, permission filtering, external links, sidebar collapse (with Alpine.js), and much more.
Navigation data can be passed as an array, loaded from a config file, or generated dynamically—making it perfect for any Laravel app.
You can customize this component
Features
- Multi-category and nested navigation: Organize your menu in multiple categories, each with unlimited levels of children/submenus.
- Sidebar collapse support: Fully supports collapsing sidebars (with Alpine.js, Livewire, or custom state).
- Active state detection: Automatically highlights active items by route match, wildcard pattern (
match
), or if any child is active. - Presets for color, style, and highlight mode: Easily switch style using props like
color="emerald"
orhighlight-mode="text"
(standard/text). -
Super-flexible icons:
- Accepts
<i>
tags (e.g. FontAwesome),<svg>
, or<img>
directly for full control. - Supports passing a plain icon name (e.g.
'check'
): auto-resolves using your preferred icon set via<x-bt-icon name="check" />
as fallback. - You can globally set the default icon set in Beartropy presets, making it easy to use Lucide, Heroicons, FontAwesome, or your own SVGs.
- Accepts
- Badges and tooltips per item: Show counts, statuses, or extra info using
badge
andtooltip
props. - Divider support: Add horizontal lines to visually separate groups or sections.
- Permission filtering: Each item can have a
can
property, filtered via Laravel policies or Spatie Permission (built-in static method to pre-filter arrays). - Config file navigation: Load your menu from files in
config/beartropy/ui/navs/*.php
for easy management, sharing, and customization. - External links & disabled items: Support for opening links in a new tab (
external
) and for non-clickable items (disabled
). - Custom classes per item: Override or extend any item’s classes (e.g. for colors, icons, layout, or custom badges).
- Fully responsive and themeable: Works with Tailwind dark mode and adapts to any layout.
Sidebar with Collapse Example
Here’s a minimal working example with a sidebar that can be collapsed using Alpine.js.
Try collapsing the sidebar!
Now the main content moves left as the sidebar collapses.
This layout uses CSS grid
with dynamic column widths via Alpine.
blade
1<div 2 x-data="{ sidebarCollapsed: false }" 3 :class="sidebarCollapsed ? 'grid-cols-[5rem_1fr]' : 'grid-cols-[16rem_1fr]'" 4 class="grid min-h-[400px] bg-slate-50 dark:bg-gray-900 rounded-xl shadow overflow-hidden border border-gray-200 dark:border-gray-800 transition-all duration-300" 5 > 6 <!-- Sidebar --> 7 <aside class="transition-all duration-300 bg-transparent p-3"> 8 <x-nav 9 :items="[10 [11 'category' => 'Demo',12 'items' => [13 [14 'label' => 'Dashboard',15 'icon' => 'window',16 'route' => '/',17 'tooltip' => 'Dashboard'18 ],19 [20 'label' => 'Users',21 'icon' => 'user-group',22 'route' => '/users',23 'badge' => 3,24 'tooltip' => 'Users'25 ],26 [27 'divider' => true28 ],29 [30 'label' => 'Settings',31 'icon' => 'cog',32 'children' => [33 [34 'label' => 'Monitoring',35 'route' => '/monitoring',36 'icon' => 'presentation-chart-line'37 ],38 [39 'label' => 'Advance settings',40 'route' => '/advance-settings',41 'icon' => 'wrench-screwdriver'42 ],43 ]44 ],45 ]46 ]47 ]"48 sidebar-bind="sidebarCollapsed"49 />50 </aside>51 <!-- Main Content -->52 <main class="p-4 bg-gray-200 dark:bg-gray-800">53 <h2 class="text-xl font-semibold mb-2">Try collapsing the sidebar!</h2>54 <p>55 Now the main content <b>moves left</b> as the sidebar collapses.<br>56 This layout uses <code>CSS grid</code> with <b>dynamic column widths</b> via Alpine.57 </p>58 <x-button59 @click="sidebarCollapsed = !sidebarCollapsed"60 outline61 >62 <span x-text="sidebarCollapsed ? 'Expand' : 'Collapse'"></span>63 </x-button>64 </main>65 </div>
Custom badge slot per item
You can fully customize any badge by passing a named slot matching the item's
Useful for special badges, icons, animations, or even Livewire components.
id
.Useful for special badges, icons, animations, or even Livewire components.
blade
1<x-nav :items="[ 2 [ 3 'category' => 'App', 4 'items' => [ 5 [ 6 'id' => 'users', 7 'label' => 'Usuarios', 8 'icon' => 'user-group', 9 'route' => '/users',10 ],11 [12 'id' => 'settings',13 'label' => 'Configuración',14 'icon' => 'cog',15 'route' => '/settings',16 ],17 ]18 ]19]">20 <x-slot name="badge-users">21 <x-badge md color="green">+3</x-badge>22 </x-slot>23</x-nav>
Reactive badge with Alpine.js
Update the badge live with Alpine.js. The menu must be inside the
x-data
to be reactive!
blade
1<div x-data="{ usersBadge: 5 }" class="space-y-4"> 2 <x-nav 3 :items="[ 4 [ 5 'category' => 'General', 6 'items' => [ 7 [ 8 'id' => 'users', 9 'label' => 'Usuarios',10 'icon' => 'user-group',11 'route' => '/users',12 ]13 ]14 ]15 ]"16 :custom-badges="['users' => 'usersBadge']"17 />18 <x-button green outline @click="usersBadge++">19 +1 Notificación20 </x-button>21</div>
Props
items
: Navigation structure. Array, config name (string), or null (loadsdefault
config).sidebar-bind
: (string) Alpine/Livewire variable for collapse state (default:sidebarCollapsed
).color
: (string) Color preset (e.g.green
,emerald
,primary
).highlight-mode
: (string)standard
ortext
(changes how active items are styled).highlight-parent-class
,highlight-child-class
: Classes for active parent/child (override preset).item-class
,child-item-class
: Classes for menu items (override preset).category-class
: Classes for category titles (default: muted uppercase).icon-class
: Additional classes for icons.child-border-class
: Classes for child submenu container border.
Menu item options (array)
Each navigation item supports the following keys:
label
: Menu label (string)icon
: Icon (FontAwesome class, SVG string, or image string)route
: Laravel route or URLbadge
: Number or string badgetooltip
: Tooltip textchildren
: Array of child items (submenu)divider
: Boolean, draws a horizontal dividerexternal
: Opens link in new tabdisabled
: Disables the itemcan
: Permission required (policy or Spatie)class
: Override item classlabel_class
: Custom class for the label
Children and Badges Example
With children and badges:
blade
1<x-nav 2 :items="[ 3 [ 4 'category' => 'Management', 5 'items' => [ 6 [ 7 'label' => 'Teams', 8 'icon' => 'user-group', 9 'route' => '/teams',10 'badge' => 2,11 ],12 [13 'label' => 'Projects',14 'icon' => 'map',15 'route' => '/projects',16 'children' => [17 [18 'label' => 'Active',19 'route' => '/projects/active',20 'badge' => 521 ],22 [23 'label' => 'Archived',24 'route' => '/projects/archived'25 ]26 ]27 ],28 [29 'divider' => true30 ],31 [32 'label' => 'External Link',33 'icon' => 'link',34 'route' => 'https://beartropy.com',35 'external' => true,36 'badge' => 'Docs',37 'tooltip' => 'View docs'38 ]39 ]40 ]41 ]"42/>
Highlight Mode Example
You can set the
highlight-mode
prop to change how active items are styled:
standard
(default): Highlights the entire itemtext
: Highlights only the text label
blade
1<x-nav 2 highlight-mode="text" 3 :items="[ 4 [ 5 'category' => 'Management', 6 'items' => [ 7 [ 8 'label' => 'Teams', 9 'icon' => 'user-group',10 'route' => '/teams',11 'badge' => 2,12 ],13 [14 'label' => 'Projects',15 'icon' => 'map',16 'route' => '/projects',17 'children' => [18 [19 'label' => 'Active',20 'route' => '/projects/active',21 'badge' => 522 ],23 [24 'label' => 'Archived',25 'route' => '/projects/archived'26 ]27 ]28 ],29 [30 'divider' => true31 ],32 [33 'label' => 'External Link',34 'icon' => 'link',35 'route' => 'https://beartropy.com',36 'external' => true,37 'badge' => 'Docs',38 'tooltip' => 'View docs'39 ]40 ]41 ]42 ]"43/>
Loading from config
You can load navigation from a config file, for example:
Pass the file name (without
config/beartropy/ui/navs/sidebar.php
.Pass the file name (without
.php
) as the items
prop:
<x-nav items="sidebar" />
Permission-based filtering
Use
can
for permission filtering. You can pre-filter using:
blade
1<?php2 $items = \Beartropy\Ui\Components\Nav::filterNavItems($yourItemsArray);3?>
Code highlighting provided by Torchlight