Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Menus Laravel Package

rinvex/laravel-menus

Rinvex Laravel Menus is a fluent, database-backed menu builder for Laravel. Create nested, sortable menus with route links, authorization checks, and Blade rendering helpers for flexible navigation.

View on GitHub
Deep Wiki
Context7

Getting Started

Install with Composer:

composer require rinvex/laravel-menus

Laravel package discovery should register the service provider and Menu facade. If you disable discovery, register Rinvex\Menus\Providers\MenusServiceProvider and alias Rinvex\Menus\Facades\Menu as Menu.

Publish the package config first:

php artisan vendor:publish --provider="Rinvex\Menus\Providers\MenusServiceProvider"

Look first at:

  • config/rinvex.menus.php — default presenter and package options.
  • src/Presenters/Bootstrap/ — built-in Navbar, Nav Pills, Nav Tabs, Sidebar, and Breadcrumb presenters.
  • src/MenuBuilder.php, src/Menu.php, and src/MenuItem.php — the builder/item API you will use daily.

Define your first menu in a service provider, usually AppServiceProvider::boot() or a dedicated MenuServiceProvider:

use Rinvex\Menus\Facades\Menu;

Menu::make('main', function ($menu) {
    $menu->add('Home', ['route' => 'home']);
    $menu->add('About', ['url' => '/about']);
});

Render it in Blade:

{!! Menu::get('main')
    ->setPresenter(\Rinvex\Menus\Presenters\Bootstrap\NavbarPresenter::class)
    ->render() !!}

Implementation Patterns

Centralize menu definitions. Define menus in a service provider or a small dedicated menu class rather than in controllers or Blade templates. This keeps menus reusable across layouts, emails, and API-driven views, and avoids duplicate Menu::make() calls.

Use route/action/url options deliberately. The second argument to add() can be a URL string or an options array. Prefer explicit options so intent is clear:

$menu->add('Dashboard', ['route' => 'dashboard', 'icon' => 'fa fa-dashboard']);
$menu->add('Docs', ['url' => 'https://example.com/docs']);

Build hierarchy by nesting. Child items are added on the parent item:

$menu->add('Settings', '#')->add('Profile', ['route' => 'profile']);
$menu->add('Settings')->add('Billing', ['route' => 'billing']);

Use presenters as the styling boundary. Set a presenter per menu or globally in config. Built-in Bootstrap presenters cover common cases; for custom markup, extend a built-in presenter and override the rendering methods rather than manually looping menu items in Blade.

Separate data from HTML attributes. Use attr() for HTML attributes and data() for presenter-specific values:

$menu->add('Reports', ['route' => 'reports'])
    ->attr('class', 'reports-link')
    ->data('icon', 'fa fa-chart');

Handle active state explicitly where needed. Auto-detection is usually URL-based. For route-based menus, nested resources, or query strings, force activation:

$menu->add('Users', ['route' => 'users.index'])->activate();

Use a view composer for shared menus. Share the rendered menu or the menu object with layouts once, instead of resolving it in every Blade file:

View::composer('layouts.app', function ($view) {
    $view->with('mainMenu', Menu::get('main'));
});

Cache static menus. Menu construction is cheap but not free. For large or permission-filtered menus, cache the rendered HTML or the menu definition and invalidate on deploy or permission changes. Avoid caching per-user menus without a user-specific key.

If using persistent menu models, publish migrations/models only if your installed version provides them, then treat the database as configuration and cache aggressively. The core package is primarily an in-memory builder.

Gotchas and Tips

  • Rendering is raw HTML. render() returns markup; in Blade you must use {!! !!}. Escape user-generated titles or attribute values yourself, or you introduce XSS.
  • add('Name', 'about') treats the second argument as a URL, not a route name. Use ['route' => 'about'] when you mean a named route.
  • Active detection is fragile. Trailing slashes, query strings, route parameters, and parent/child paths can produce false negatives or multiple active items. Override isActive() logic in a custom presenter or call activate() explicitly.
  • Presenter choice is Bootstrap-version-sensitive. Built-in presenters target Bootstrap-era markup. Check the generated classes against Bootstrap 4/5 or Tailwind, and fork/override presenter methods if needed.
  • The builder is a singleton. In tests, menus can leak between test cases. Reset or recreate menus in setUp()/tearDown(), or avoid asserting on global menu state.
  • Facade alias conflicts. The Menu alias can collide with app models or other packages. Inject MenuBuilder or alias the facade explicitly in config/app.php.
  • Service provider order matters. Menus that depend on routes, auth, or permissions should be defined after those services are available. Use booted() or a dedicated provider if definitions run too early.
  • data() is not attr(). Putting class or id in data() will not automatically render it as an HTML attribute unless your presenter reads it.
  • Custom presenters are the main extension point. Override getItemView, getItemLinkView, getItemAttributes, and child-item methods to change markup without rewriting menu definitions.
  • Small package, small ecosystem. Pin the version, keep presenters in your app rather than patching vendor code, and expect to own Bootstrap/Tailwind markup customizations.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib