PHPackages                             offload-project/laravel-navigation - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. offload-project/laravel-navigation

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

offload-project/laravel-navigation
==================================

Configurable navigation package for Laravel with breadcrumb and tree generation

v1.4.0(1mo ago)31.5k↓50%1MITPHPPHP ^8.3CI passing

Since Dec 16Pushed 1mo agoCompare

[ Source](https://github.com/offload-project/laravel-navigation)[ Packagist](https://packagist.org/packages/offload-project/laravel-navigation)[ Docs](https://github.com/offload-project/laravel-navigation)[ RSS](/packages/offload-project-laravel-navigation/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (24)Versions (14)Used By (1)

 [![Latest Version on Packagist](https://camo.githubusercontent.com/abfe89755a91e53b6ba9ab1d46b4cede3d9fcbed276e29af54ff8be8a791ef76/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6f66666c6f61642d70726f6a6563742f6c61726176656c2d6e617669676174696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/offload-project/laravel-navigation) [![GitHub Tests Action Status](https://camo.githubusercontent.com/5ece533bafbea80a6e9005ea45ea46ae414fc44f085ad78238a185cdfe61c586/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6f66666c6f61642d70726f6a6563742f6c61726176656c2d6e617669676174696f6e2f74657374732e796d6c3f6272616e63683d6d61696e267374796c653d666c61742d737175617265)](https://github.com/offload-project/laravel-navigation/actions) [![Total Downloads](https://camo.githubusercontent.com/a9041dc98d3b7f9b0fb1afacc5f6477cdad95c238b511ec2141f00eb23f31f60/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6f66666c6f61642d70726f6a6563742f6c61726176656c2d6e617669676174696f6e2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/offload-project/laravel-navigation)

Laravel Navigation
==================

[](#laravel-navigation)

A powerful, flexible navigation management package for Laravel. Define multiple navigation structures with breadcrumbs, active state detection, and pre-compiled icons — perfect for Inertia.js, React, Vue, and Blade applications.

Features
--------

[](#features)

- **Multiple Navigations** — Define unlimited nav structures (main, footer, sidebar, user menu)
- **Fluent Builder API** — IDE-friendly builder with full autocomplete support
- **Route-Based** — Use Laravel route names with full IDE autocomplete
- **Breadcrumb Generation** — Auto-generate breadcrumbs from your navigation config
- **Active State Detection** — Smart detection of active items and their parents
- **Authorization** — Built-in `can` and `visible` attributes for permissions
- **Pre-compiled Icons** — Compile Lucide icons to inline SVG for optimal performance
- **Action Support** — POST/DELETE actions for logout, form submissions, etc.
- **Wildcard Parameters** — Match dynamic routes like `/users/{id}/edit` in breadcrumbs
- **Custom Metadata** — Attach badges, feature flags, or any data to nav items

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 11.0+

Installation
------------

[](#installation)

```
composer require offload-project/laravel-navigation
```

Optionally publish the configuration:

```
php artisan vendor:publish --tag=navigation-config
```

Quick Start
-----------

[](#quick-start)

### Using the Fluent Builder (Recommended)

[](#using-the-fluent-builder-recommended)

The fluent builder provides full IDE autocomplete and a clean, readable syntax:

```
use OffloadProject\Navigation\Item;

return [
    'navigations' => [
        'main' => [
            Item::make('Dashboard')->route('dashboard')->icon('home'),
            Item::make('Users')
                ->route('users.index')
                ->icon('users')
                ->can('view-users')
                ->children([
                    Item::make('All Users')->route('users.index'),
                    Item::make('Roles')->route('roles.index'),
                ]),
            Item::make('Settings')->route('settings')->icon('settings'),
        ],
    ],
];
```

### Using Helper Functions

[](#using-helper-functions)

Global helper functions provide the most concise syntax:

```
return [
    'navigations' => [
        'main' => [
            nav_item('Dashboard', 'dashboard', 'home'),
            nav_item('Users', 'users.index', 'users')
                ->can('view-users')
                ->children([
                    nav_item('All Users', 'users.index'),
                    nav_item('Roles', 'roles.index'),
                ]),
            nav_separator(),
            nav_item('Settings', 'settings', 'settings'),
            nav_external('Documentation', 'https://docs.example.com', 'book'),
            nav_action('Logout', 'logout', 'post', 'log-out'),
        ],
    ],
];
```

Available helpers:

- `nav_item($label, $route?, $icon?)` — Standard navigation item
- `nav_group($label, $children?, $icon?)` — Collapsible group/section
- `nav_separator()` — Visual separator
- `nav_divider($spacing?)` — Divider with optional spacing
- `nav_external($label, $url, $icon?)` — External link
- `nav_action($label, $route, $method?, $icon?)` — POST/DELETE action

### Using Shorthand Syntax

[](#using-shorthand-syntax)

For quick configuration, use the shorthand array syntax:

```
return [
    'navigations' => [
        'main' => [
            ['Dashboard', 'dashboard', 'home'],           // [label, route, icon]
            ['Users', 'users.index', 'users'],            // [label, route, icon]
            ['Docs', 'https://docs.example.com', 'book'], // URLs auto-detected
        ],
    ],
];
```

### Using Array Syntax

[](#using-array-syntax)

The traditional array syntax is still fully supported:

```
return [
    'navigations' => [
        'main' => [
            ['label' => 'Dashboard', 'route' => 'dashboard', 'icon' => 'home'],
            [
                'label' => 'Users',
                'route' => 'users.index',
                'icon' => 'users',
                'can' => 'view-users',
                'children' => [
                    ['label' => 'All Users', 'route' => 'users.index'],
                    ['label' => 'Roles', 'route' => 'roles.index'],
                ],
            ],
        ],
    ],
];
```

Runtime Registration
--------------------

[](#runtime-registration)

Register navigations at runtime in your service provider or middleware:

```
use OffloadProject\Navigation\Facades\Navigation;
use OffloadProject\Navigation\Item;

// Fluent builder
Navigation::register('sidebar')
    ->item('Dashboard', 'dashboard', 'home')
    ->item('Users', 'users.index', 'users')
        ->child('All Users', 'users.index')
        ->child('Create User', 'users.create')
    ->separator()
    ->item('Settings', 'settings', 'settings')
    ->done();

// Or with Item instances
Navigation::addNavigation('sidebar', [
    Item::make('Dashboard')->route('dashboard')->icon('home'),
    Item::make('Users')->route('users.index')->icon('users'),
]);
```

Getting Navigation Data
-----------------------

[](#getting-navigation-data)

```
use OffloadProject\Navigation\Facades\Navigation;

// Get navigation items
$items = Navigation::get('main')->items();

// Get breadcrumbs (auto-detects current route)
$breadcrumbs = Navigation::breadcrumbs('main');

// Check if navigation exists
if (Navigation::has('sidebar')) {
    // ...
}

// Get all navigation names
$names = Navigation::names();
```

Pass to your frontend:

```
// Inertia.js
return inertia('Dashboard', [
    'navigation' => Navigation::get('main')->items(),
    'breadcrumbs' => Navigation::breadcrumbs('main'),
]);
```

Fluent Builder API
------------------

[](#fluent-builder-api)

The `Item` class provides a fluent interface with full IDE support:

```
use OffloadProject\Navigation\Item;

// Basic item
Item::make('Dashboard')->route('dashboard')->icon('home')

// Shorthand with route and icon
Item::to('Dashboard', 'dashboard', 'home')

// External link
Item::external('Documentation', 'https://docs.example.com', 'book')

// Action (POST/DELETE)
Item::action('Logout', 'logout', 'post', 'log-out')

// Separator
Item::separator()

// Divider with spacing
Item::divider('large')

// With children
Item::make('Settings')
    ->route('settings')
    ->icon('settings')
    ->children([
        Item::make('Profile')->route('settings.profile'),
        Item::make('Security')->route('settings.security'),
    ])

// With authorization
Item::make('Admin')
    ->route('admin')
    ->can('access-admin')

// With visibility
Item::make('Dashboard')
    ->route('dashboard')
    ->visible(fn () => auth()->check())
    ->whenAuthenticated()  // Shorthand for authenticated users
    ->whenGuest()          // Shorthand for guests only

// With badge
Item::make('Notifications')
    ->route('notifications')
    ->badge(5)
    ->badge(fn () => auth()->user()->unreadCount(), 'red')

// For breadcrumbs only
Item::make(fn ($user) => "Edit: {$user->name}")
    ->route('users.edit')
    ->params(['user' => '*'])
    ->breadcrumbOnly()

// For navigation only
Item::make('Admin Section')
    ->route('admin')
    ->navOnly()

// Custom metadata
Item::make('Dashboard')
    ->route('dashboard')
    ->meta('badge', 5)
    ->meta('feature', 'beta')
```

Groups &amp; Sections
---------------------

[](#groups--sections)

Organize navigation items into collapsible groups with headers:

```
use OffloadProject\Navigation\Item;

return [
    'navigations' => [
        'sidebar' => [
            Item::make('Dashboard')->route('dashboard')->icon('home'),

            Item::group('Settings', [
                Item::make('Profile')->route('settings.profile'),
                Item::make('Security')->route('settings.security'),
                Item::make('Notifications')->route('settings.notifications'),
            ])->icon('cog'),

            Item::group('Administration', [
                Item::make('Users')->route('admin.users'),
                Item::make('Roles')->route('admin.roles'),
            ])->icon('shield')->collapsed(), // Starts collapsed
        ],
    ],
];
```

Or with helper functions:

```
return [
    'navigations' => [
        'sidebar' => [
            nav_item('Dashboard', 'dashboard', 'home'),

            nav_group('Settings', [
                nav_item('Profile', 'settings.profile'),
                nav_item('Security', 'settings.security'),
            ], 'cog'),

            nav_group('Admin', [], 'shield')
                ->collapsed()
                ->can('access-admin')
                ->children([
                    nav_item('Users', 'admin.users'),
                    nav_item('Roles', 'admin.roles'),
                ]),
        ],
    ],
];
```

### Group Options

[](#group-options)

```
// Basic group
Item::group('Settings', [...])

// With icon
Item::group('Settings', [...])->icon('cog')

// Not collapsible (always expanded)
Item::group('Main')->collapsible(false)

// Starts collapsed
Item::group('Advanced')->collapsed()

// With authorization
Item::group('Admin')->can('access-admin')

// With visibility
Item::group('Beta')->visible(config('features.beta'))

// Nested groups
Item::group('Settings', [
    Item::make('General')->route('settings.general'),
    Item::group('Advanced', [
        Item::make('API Keys')->route('settings.api'),
        Item::make('Webhooks')->route('settings.webhooks'),
    ])->collapsed(),
])
```

### Group Output

[](#group-output)

Groups output with these additional fields:

```
[
    'id' => 'nav-sidebar-1',
    'label' => 'Settings',
    'url' => null,           // Groups don't have URLs
    'isActive' => true,      // Active if any child is active
    'icon' => '...',
    'group' => true,         // Identifies this as a group
    'collapsible' => true,   // Can be collapsed
    'collapsed' => false,    // Default collapsed state
    'children' => [...],
]
```

Route Parameters
----------------

[](#route-parameters)

Pass parameters for routes that require them:

```
// For routes like /users/{user}/posts
$items = Navigation::get('sidebar')->items(['user' => $user->id]);
```

Authorization
-------------

[](#authorization)

Use the `can` attribute to check gates or policies:

```
Item::make('Admin')
    ->route('admin.index')
    ->can('access-admin')

// With policy model
Item::make('Edit Post')
    ->route('posts.edit')
    ->can(['update', $post])
```

Items are automatically hidden when the user isn't authenticated or lacks permission.

For non-authorization logic (feature flags, environment checks), use `visible`:

```
Item::make('Beta Features')
    ->route('beta')
    ->visible(config('features.beta'))

// Or with closures
Item::make('Debug')
    ->route('debug')
    ->visible(fn () => app()->isLocal())
```

Action Items
------------

[](#action-items)

Define items that trigger POST/DELETE requests:

```
Item::action('Logout', 'logout', 'post', 'log-out')

// Or with array syntax
['label' => 'Logout', 'route' => 'logout', 'method' => 'post', 'icon' => 'log-out']
```

Handle in your frontend by checking for the `method` key and using a form or Inertia's `router.post()`.

Breadcrumbs &amp; Wildcards
---------------------------

[](#breadcrumbs--wildcards)

Handle CRUD pages elegantly with `breadcrumbOnly` and wildcard parameters:

```
Item::make('Users')
    ->route('users.index')
    ->children([
        Item::make(fn ($user) => "Edit: {$user->name}")
            ->route('users.edit')
            ->params(['user' => '*'])
            ->breadcrumbOnly(),
    ])
```

When visiting `/users/5/edit`:

- **Navigation** shows only "Users"
- **Breadcrumbs** show "Users &gt; Edit: John Doe"
- **Active state** marks "Users" as active

### Breadcrumbs API

[](#breadcrumbs-api)

```
// Auto-detect current route, search all navigations
$breadcrumbs = Navigation::breadcrumbs();

// Search specific navigation
$breadcrumbs = Navigation::breadcrumbs('main');

// Specify route explicitly
$breadcrumbs = Navigation::breadcrumbs('main', 'users.edit');

// With route parameters
$breadcrumbs = Navigation::breadcrumbs('main', 'users.edit', ['user' => $user]);
```

Visibility Control
------------------

[](#visibility-control)

Use `navOnly` and `breadcrumbOnly` to control where items appear:

```
Item::make('Admin Section')
    ->route('admin.index')
    ->navOnly()  // Shows in nav, excluded from breadcrumbs
    ->children([
        Item::make('Users')->route('admin.users'),
        Item::make(fn ($user) => "Edit {$user->name}")
            ->route('admin.users.edit')
            ->params(['user' => '*'])
            ->breadcrumbOnly(),  // Shows in breadcrumbs, excluded from nav
    ])
```

- **`navOnly`** — Section headers that would be redundant in breadcrumbs
- **`breadcrumbOnly`** — Edit/show pages that shouldn't clutter navigation

Custom Metadata
---------------

[](#custom-metadata)

Attach any data to navigation items:

```
Item::make('Notifications')
    ->route('notifications')
    ->badge(5)
    ->meta('badgeColor', 'red')
    ->meta('feature', 'new')

// Or with array syntax
[
    'label' => 'Notifications',
    'route' => 'notifications',
    'badge' => 5,
    'badgeColor' => 'red',
]
```

Custom keys pass through unchanged to your frontend.

Icon Compilation
----------------

[](#icon-compilation)

Pre-compile Lucide icons to inline SVG for optimal performance:

```
php artisan navigation:compile-icons
```

Add to your deployment pipeline for production builds.

Route Validation
----------------

[](#route-validation)

Validate all route references exist:

```
php artisan navigation:validate
```

Add to CI/CD to catch broken navigation links early.

Inertia.js Integration
----------------------

[](#inertiajs-integration)

Share navigation globally via middleware:

```
// app/Http/Middleware/HandleInertiaRequests.php
public function share(Request $request): array
{
    return [
        ...parent::share($request),
        'navigation' => Navigation::get('main')->items(),
        'breadcrumbs' => Navigation::breadcrumbs('main'),
    ];
}
```

Output Format
-------------

[](#output-format)

The `items()` method returns a frontend-ready structure:

```
[
    [
        'id' => 'nav-main-0',
        'label' => 'Dashboard',
        'url' => '/dashboard',
        'isActive' => true,
        'icon' => '...',
        'children' => [],
    ],
    // ...
]
```

The `breadcrumbs()` method returns:

```
[
    ['id' => 'breadcrumb-main-0-1', 'label' => 'Users', 'route' => 'users.index', 'url' => '/users'],
    ['id' => 'breadcrumb-main-1-0', 'label' => 'Edit: John', 'route' => 'users.edit', 'url' => '/users/1/edit', 'isActive' => true],
]
```

The last breadcrumb includes `isActive => true` to identify the current page.

Configuration Reference
-----------------------

[](#configuration-reference)

OptionTypeDescription`label``string|Closure`Display text (closures receive route models)`route``string`Laravel route name`url``string`External URL (alternative to `route`)`method``string`HTTP method (`post`, `delete`)`icon``string`Lucide icon name`children``array`Nested navigation items`visible``bool|Closure`Visibility condition`can``string|array`Gate/policy check`breadcrumbOnly``bool`Hide from nav, show in breadcrumbs`navOnly``bool`Show in nav, hide from breadcrumbs`params``array`Route parameters (`['id' => '*']` for wildcards)Error Messages
--------------

[](#error-messages)

The package provides helpful error messages when configuration is invalid:

```
Navigation item cannot have both "route" and "url". Use "route" for internal
Laravel routes (e.g., "users.index") or "url" for external links
(e.g., "https://docs.example.com"), but not both.
See: https://github.com/offload-project/laravel-navigation#routing

```

Migration Guide
---------------

[](#migration-guide)

### Upgrading to v1.1

[](#upgrading-to-v11)

#### Breaking Changes

[](#breaking-changes)

**Icon Storage Format Changed**

Compiled icons are now stored as JSON instead of PHP. If you have previously compiled icons:

```
# Recompile your icons to use the new format
php artisan navigation:compile-icons
```

The old PHP format (`storage/navigation/icons.php`) will still be loaded for backwards compatibility, but new compilations will use JSON (`storage/navigation/icons.json`).

**NavigationManager Constructor**

If you're manually instantiating `NavigationManager`, the constructor now requires an `ItemVisibilityResolver` instance:

```
// Before
new NavigationManager($config, $iconCompiler);

// After
new NavigationManager($config, $iconCompiler, $visibilityResolver);
```

Most users won't be affected as the class is typically resolved from the container.

### Deprecated Methods

[](#deprecated-methods)

The following methods are deprecated and will be removed in v2.0:

DeprecatedUse Instead`->toTree()``->items()``->getBreadcrumbs()``->breadcrumbs()`Testing
-------

[](#testing)

```
./vendor/bin/pest
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

###  Health Score

48

—

FairBetter than 95% of packages

Maintenance90

Actively maintained with recent releases

Popularity24

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 70.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~12 days

Recently: every ~18 days

Total

9

Last Release

54d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/331bcc01f75f46dded875d74f3db055da6d74be5f8820f0a29105c6a2cd8afc8?d=identicon)[shavonn](/maintainers/shavonn)

---

Top Contributors

[![shavonn](https://avatars.githubusercontent.com/u/3074595?v=4)](https://github.com/shavonn "shavonn (24 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (10 commits)")

---

Tags

laravelnavigationnavwayfinder

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/offload-project-laravel-navigation/health.svg)

```
[![Health](https://phpackages.com/badges/offload-project-laravel-navigation/health.svg)](https://phpackages.com/packages/offload-project-laravel-navigation)
```

###  Alternatives

[watson/active

Laravel helper for recognising the current route, controller and action

3253.6M14](/packages/watson-active)[nwidart/laravel-menus

Laravel Menu management

168180.3k10](/packages/nwidart-laravel-menus)[pingpong/menus

Laravel Menus

70194.4k13](/packages/pingpong-menus)[dragon-code/pretty-routes

Pretty Routes for Laravel

10058.7k4](/packages/dragon-code-pretty-routes)[rinvex/laravel-menus

Rinvex Menus is a simple menu builder package for Laravel, that supports hierarchical structure, ordering, and styling with full flexibility using presenters for easy styling and custom structure of menu rendering.

294.0k20](/packages/rinvex-laravel-menus)[bjuppa/laravel-blog

Add blog functionality to your Laravel project

483.3k2](/packages/bjuppa-laravel-blog)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
