Documentation Index
Fetch the complete documentation index at: https://docs.laravelshopper.dev/llms.txt
Use this file to discover all available pages before exploring further.
This guide covers how to install and use the sidebar package in a standalone Laravel application (without Shopper).
Installation
Install the package via Composer:
composer require shopper/sidebar
Publish the configuration file:
php artisan vendor:publish --provider="Shopper\Sidebar\SidebarServiceProvider" --tag="sidebar-config"
Optionally, publish the views for customization:
php artisan vendor:publish --provider="Shopper\Sidebar\SidebarServiceProvider" --tag="sidebar-views"
Setting Up the Middleware
Add the sidebar resolver middleware to your route group or in bootstrap/app.php:
Route::middleware(['web', \Shopper\Sidebar\Middleware\ResolveSidebars::class])
->group(function () {
...
});
Or in Laravel 11+ with bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->appendToGroup('web', [
\Shopper\Sidebar\Middleware\ResolveSidebars::class,
]);
})
Create a class that implements the Sidebar contract:
<?php
namespace App\Sidebar;
use Shopper\Sidebar\Contracts\Builder\Menu;
use Shopper\Sidebar\Contracts\Builder\Group;
use Shopper\Sidebar\Contracts\Builder\Item;
use Shopper\Sidebar\Contracts\Sidebar;
class AdminSidebar implements Sidebar
{
public function __construct(private Menu $menu) {}
public function build(): void
{
$this->menu->group('Main', function (Group $group): void {
$group->weight(1);
$group->setAuthorized();
$group->setGroupItemsClass('space-y-1');
$group->item('Dashboard', function (Item $item): void {
$item->weight(1);
$item->setAuthorized();
$item->route('dashboard');
$item->setIcon('heroicon-o-home');
});
$group->item('Users', function (Item $item): void {
$item->weight(2);
$item->setAuthorized();
$item->route('users.index');
$item->setIcon('heroicon-o-users');
// Add sub-items
$item->item('All Users', function (Item $subItem): void {
$subItem->route('users.index');
});
$item->item('Create User', function (Item $subItem): void {
$subItem->route('users.create');
});
});
});
$this->menu->group('Settings', function (Group $group): void {
$group->weight(10);
$group->setAuthorized();
$group->item('General', function (Item $item): void {
$item->weight(1);
$item->route('settings.general');
$item->setIcon('heroicon-o-cog');
});
});
}
public function getMenu(): Menu
{
return $this->menu;
}
}
Register your sidebar in a service provider using the SidebarManager:
<?php
namespace App\Providers;
use App\Sidebar\AdminSidebar;
use Illuminate\Support\ServiceProvider;
use Shopper\Sidebar\SidebarManager;
class SidebarServiceProvider extends ServiceProvider
{
public function boot(SidebarManager $manager): void
{
$manager->register(AdminSidebar::class);
}
}
Don’t forget to register the service provider in config/app.php or bootstrap/providers.php.
Option 1: Livewire Component
The easiest way to use the sidebar is with the built-in Livewire component:
@livewire('sidebar', [
'sidebarClass' => \App\Sidebar\AdminSidebar::class,
'class' => 'h-full',
'collapsible' => true,
])
Option 2: Custom Blade Implementation
For full control, use the SidebarRenderer directly:
@php
$sidebar = app(\App\Sidebar\AdminSidebar::class);
$sidebar->build();
$renderer = app(\Shopper\Sidebar\Presentation\SidebarRenderer::class);
$renderedSidebar = $renderer->render($sidebar);
@endphp
<aside class="sidebar" x-data x-bind:class="{ 'collapsed': $store.sidebar.isCollapsed }">
<div class="sidebar-header">
<img src="/logo.png" alt="Logo" />
<span x-show="!$store.sidebar.isCollapsed">My App</span>
</div>
<nav class="sidebar-nav">
{!! $renderedSidebar !!}
</nav>
<div class="sidebar-footer">
<button @click="$store.sidebar.toggle()">
Toggle Sidebar
</button>
</div>
</aside>
Alpine.js Store Setup
The sidebar uses an Alpine.js store for state management. Add the store to your JavaScript:
import Alpine from 'alpinejs'
import sidebarStore from './vendor/sidebar/stores/sidebar'
Alpine.store('sidebar', sidebarStore())
Alpine.start()
document.addEventListener('alpine:init', () => {
Alpine.store('sidebar').init()
})
To get the source JavaScript files, publish them:
php artisan vendor:publish --provider="Shopper\Sidebar\SidebarServiceProvider" --tag="sidebar-js"
This will publish the files to resources/js/vendor/sidebar/.
Store API
The sidebar store provides these properties and methods:
State properties:
| Property | Description |
|---|
$store.sidebar.isOpen | Mobile: sidebar visibility |
$store.sidebar.isCollapsed | Desktop: collapsed state |
$store.sidebar.collapsible | Whether collapse is enabled |
$store.sidebar.currentPath | Current URL path |
Sidebar visibility (mobile):
$store.sidebar.open()
$store.sidebar.close()
Sidebar collapse (desktop):
$store.sidebar.toggle()
$store.sidebar.collapse()
$store.sidebar.expand()
$store.sidebar.toggleCollapse()
Group management:
$store.sidebar.toggleGroup(label)
$store.sidebar.isGroupCollapsed(label)
$store.sidebar.collapseGroup(label)
$store.sidebar.expandGroup(label)
Navigation tracking (for SPA):
$store.sidebar.isActive(url)
CSS Variables
Add CSS variables to your layout for sidebar dimensions:
<style>
:root {
--sidebar-width: {{ \Shopper\Sidebar\sidebar_width() }};
--sidebar-collapsed-width: {{ \Shopper\Sidebar\sidebar_collapsed_width() }};
}
</style>
<body
data-sidebar-breakpoint="{{ \Shopper\Sidebar\sidebar_breakpoint() }}"
data-sidebar-collapsible="{{ \Shopper\Sidebar\sidebar_is_collapsible() ? 'true' : 'false' }}"
>
Basic Item Options
$group->item('Label', function (Item $item): void {
// URL or Route
$item->setUrl('/path'); // Direct URL
$item->route('route.name'); // Route name
$item->route('route.name', ['id' => 1]); // Route with parameters
// Icon
$item->setIcon(
icon: 'heroicon-o-home',
type: 'blade', // 'blade' or 'svg'
iconClass: 'size-5',
attributes: ['stroke-width' => '1.5'],
);
// Ordering
$item->weight(1); // Sort order (lower = higher)
// Authorization
$item->setAuthorized(); // Always authorized
$item->setAuthorized(fn() => auth()->user()->isAdmin()); // Conditional
// Behavior
$item->useSpa(); // Use wire:navigate for Livewire
$item->isNewTab(); // Open in new tab
// CSS Classes
$item->setItemClass('my-item-class');
$item->setActiveClass('active');
});
Adding Badges
$item->badge('New'); // Simple text badge
$item->badge(5); // Number badge
$item->badge('3', 'bg-red-500 text-white'); // Styled badge
$item->badge(function (Badge $badge): void {
$badge->setValue($this->getNotificationCount());
$badge->setClass('bg-primary-500 text-white');
$badge->color('danger');
});
Adding Append Elements
Append elements are additional action buttons displayed next to the item:
$item->append('/users/create', 'heroicon-o-plus', 'Add User');
$item->append(function (Append $append): void {
$append->route('users.create');
$append->setIcon('heroicon-o-plus', 'blade', 'size-4');
$append->setName('Add User');
$append->setClass('hover:bg-gray-100');
});
Sub-Items
$item->item('Sub Item 1', function (Item $subItem): void {
$subItem->route('sub.route.1');
});
$item->item('Sub Item 2', function (Item $subItem): void {
$subItem->route('sub.route.2');
});
Group API
$menu->group('Group Name', function (Group $group): void {
$group->weight(1); // Sort order
$group->setAuthorized(); // Authorization
$group->hideHeading(); // Hide the group heading
$group->collapsible(true); // Allow collapsing
// CSS Classes
$group->setClass('my-group-class');
$group->setHeadingClass('my-heading-class');
$group->setGroupItemsClass('space-y-1');
// Add items
$group->item('Item', function (Item $item): void {
// ...
});
});
Helper Functions
The package provides namespaced helper functions:
use function Shopper\Sidebar\sidebar_config;
use function Shopper\Sidebar\sidebar_width;
use function Shopper\Sidebar\sidebar_collapsed_width;
use function Shopper\Sidebar\sidebar_breakpoint;
use function Shopper\Sidebar\sidebar_is_collapsible;
$value = sidebar_config('cache.method', 'default');
$width = sidebar_width();
$collapsed = sidebar_collapsed_width();
$breakpoint = sidebar_breakpoint();
$collapsible = sidebar_is_collapsible(); // true/false