Basics
The navigation menu is configured in App\Providers\MoonShineServiceProvider via the menu()
method, which returns an array of menu items.
In order to add a menu item, you must use the MoonShine\Menu\MenuItem class and its static method make()
.
MenuItem::make(Closure|string $label, Closure|MenuFiller|string $filler, null|string $icon = null, Closure|bool $blank = false)
$label
- name of the menu item
$filler
- element for forming url
$icon
- icon for the menu item,
$blank
- open in new tab.
You can pass as the second parameter ModelResource , Page or Resource.
namespace App\Providers; use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('Admins', new MoonShineUserResource()), MenuItem::make('Home', fn() => route('home')), MenuItem::make('Docs', 'https://moonshine-laravel.com/en/docs'), MenuItem::make('Laravel Docs', 'https://laravel.com/en/docs', blank: true) ]; } //...}
If the menu is created for ModelResource or Resource, then the menu item will use the first page advertised in method pages()
.
Menu via Closure
You can declare a menu using a closure based on the current request:
namespace App\Providers; use Closure;use MoonShine\MoonShineRequest;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): Closure { return static function (MoonShineRequest $request) { return [ //... ]; }; }; //...}
It will be useful if you decide to use multi tenancy or if you have both the web and admin parts implemented on MoonShine.
Groups
Menu items can be combined into groups. To do this, use the MoonShine\Menu\MenuGroup class with the static method make()
.
MenuGroup::make(Closure|string $label, iterable $items, null|string $icon = null)
$label
- group name
$items
- array of menu components
$icon
- icon for the group.
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource;use MoonShine\Resources\MoonShineUserRoleResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make('System', [ MenuItem::make('Admins', new MoonShineUserResource()), MenuItem::make('Roles', new MoonShineUserRoleResource()), ]) ]; } //...}
You can also add elements to a group using method setItems()
setItems(iterable $items)
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource;use MoonShine\Resources\MoonShineUserRoleResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make('System')->setItems([ MenuItem::make('Admins', new MoonShineUserResource()), MenuItem::make('Roles', new MoonShineUserRoleResource()), ]) ]; } //...}
To create a multi-level menu, groups can be nested.
Attributes
The customAttributes()
method allows you to add your own attributes for groups and menu items.
customAttributes(array $attributes)
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource;use MoonShine\Resources\MoonShineUserRoleResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make(static fn () => __('moonshine::ui.resource.system'), [ MenuItem::make( static fn () => __('moonshine::ui.resource.admins_title'), new MoonShineUserResource() ), MenuItem::make( static fn () => __('moonshine::ui.resource.role_title'), new MoonShineUserRoleResource() ) ->customAttributes(['class' => 'group-li-custom-class']), ]) ->customAttributes(['class' => 'group-li-custom-class']) ]; } //...}
The linkAttributes()
method allows you to add attributes to the a
link tag.
linkAttributes(array $attributes)
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource;use MoonShine\Resources\MoonShineUserRoleResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make(static fn () => __('moonshine::ui.resource.system'), [ MenuItem::make( static fn () => __('moonshine::ui.resource.admins_title'), new MoonShineUserResource() ) ->linkAttributes(['class' => 'group-a-custom-class']), MenuItem::make( static fn () => __('moonshine::ui.resource.role_title'), new MoonShineUserRoleResource() ), ]) ->linkAttributes(['class' => 'group-button-custom-class']) ]; } //...}
Delimiter
Menu items can be visually divided using MoonShine\Menu\MenuDivider.
MenuDivider::make(Closure|string $label = '')
namespace App\Providers; use App\MoonShine\Resources\ArticleResource;use App\MoonShine\Resources\CategoryResource;use MoonShine\Menu\MenuDivider;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('Admins', new MoonShineUserResource()), MenuDivider::make(), MenuItem::make('Roles', new MoonShineUserRoleResource()), ]; } //...}
You can use text as a delimiter; to do this, you need to pass it to the make()
method.
namespace App\Providers; use App\MoonShine\Resources\ArticleResource;use App\MoonShine\Resources\CategoryResource;use MoonShine\Menu\MenuDivider;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('Admins', new MoonShineUserResource()), MenuDivider::make('Divider'), MenuItem::make('Roles', new MoonShineUserRoleResource()), ]; } //...}
Display condition
You can display menu items based on conditions using the canSee()
method.
canSee(Closure $callback)
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource;use MoonShine\Resources\MoonShineUserRoleResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make('System', [ MenuItem::make('Admins', new MoonShineUserResource()), MenuItem::make('Roles', new MoonShineUserRoleResource()) ->canSee(fn()=> false) ]) ->canSee(function(Request $request) { return $request->user('moonshine')?->id === 1; }) ]; } //...}
Icon
You can set an icon for a menu item and a group. This can be accomplished in several ways.
Via parameter
The icon can be set by passing the name as the third parameter in static method make()
.
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource;use MoonShine\Resources\MoonShineUserRoleResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make('System', [ MenuItem::make('Admins', new MoonShineUserResource(), 'heroicons.outline.users'), MenuItem::make('Roles', new MoonShineUserRoleResource(), 'heroicons.hashtag'), ]) ]; } //...}
Via method
Use method icon()
.
icon(string $icon)
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider;use MoonShine\Resources\MoonShineUserResource;use MoonShine\Resources\MoonShineUserRoleResource; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make('System', [ MenuItem::make('Admins', new MoonShineUserResource()) ->icon('heroicons.outline.users'), MenuItem::make('Roles', new MoonShineUserRoleResource()) ->icon('heroicons.hashtag'), ]) ->icon('heroicons.cog') ]; } //...}
Via attribute
The menu item will display an icon if the class ModelResource, Page or Resource the Icon
attribute is specified and the icon is not overridden in other ways.
namespace MoonShine\Resources; #[Icon('heroicons.outline.users')]class MoonShineUserResource extends ModelResource{ //... }
For more detailed information, please refer to the section Icons.
Label
It is also possible to add an icon to a menu item.
Via menu item
To add a badge to a menu item, use method badge()
, which takes a closure as a parameter.
badge(Closure $callback)
namespace App\Providers; use App\Models\Comment;use App\MoonShine\Resources\CommentResource;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('Comments', new CommentResource()) ->badge(fn() => Comment::count()) ]; } //...}
Through a class method
For ModelResource, Page or Resource There is an alternative way to set the badge - method getBadge()
.
namespace App\MoonShine\Resources; use App\Models\Post;use MoonShine\Resources\ModelResource; class PostResource extends ModelResource{ //... public function getBadge(): string { return 'new'; } //...}
Translation
To translate menu items, you need to pass the translation key as the name and add method translatable()
translatable(string $key = '')
namespace App\Providers; use App\Models\Comment;use App\MoonShine\Resources\CommentResource;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('menu.Comments', new CommentResource()) ->translatable() // or MenuItem::make('Comments', new CommentResource()) ->translatable('menu') ]; } //...}
// lang/ru/menu.php return [ 'Comments' => 'Comments',];
You can use Laravel's translation tools to translate menu labels.
namespace App\Providers; use App\Models\Comment;use App\MoonShine\Resources\CommentResource;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('Comments', new CommentResource()) ->badge(fn() => __('menu.badge.new')) ]; } //...}
Open in new tab
A menu item can have a flag indicating whether the link should be opened in a new tab or not. This can be implemented in several ways.
Via parameter
The flag can be set by passing true/false
or a closure in a static method make()
.
namespace App\Providers; use MoonShine\Menu\MenuGroup;use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make('System', [ MenuItem::make('MoonShine Docs', 'https://moonshine-laravel.com/en/docs', 'heroicons.arrow-up', true), MenuItem::make('Laravel Docs', 'https://laravel.com/en/docs', 'heroicons.arrow-up', fn() => true), ]) ]; } //...}
Via method
Use method blank()
.
blank(Closure|bool $blankCondition = true)
namespace App\Providers; use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('MoonShine Docs', 'https://moonshine-laravel.com/en/docs') ->blank(), MenuItem::make('Laravel Docs', 'https://laravel.com/en/docs') ->blank(fn() => true), ]; } //...}
Active item
The menu item becomes active if it matches the url, but the forceActive()
method allows you to force the item to be active.
forceActive(Closure|bool $forceActive)
namespace App\Providers; use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuItem::make('Label', '/endpoint') ->forceActive(fn() => request()->fullUrlIs('*admin/endpoint/*')), ]; } //...}
Custom view
When you need to change the view using fluent interface you can use the customView()
method.
customView(string $path)
namespace App\Providers; use MoonShine\Menu\MenuItem;use MoonShine\Providers\MoonShineApplicationServiceProvider; class MoonShineServiceProvider extends MoonShineApplicationServiceProvider{ protected function menu(): array { return [ MenuGroup::make('Group', [ MenuItem::make('Label', '/endpoint') ->customView('admin.custom-menu-item'), ]) ->customView('admin.custom-menu-group'), ]; } //...}