# 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/docs'), MenuItem::make('Laravel Docs', 'https://laravel.com/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()
.
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.
When declaring a menu using Closure, you need to manually register pages and resources in the corresponding methods.
# 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.
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'), ]) ]; } //...}
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') ]; } //...}
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.
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()) ]; } //...}
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.
The flag can be set by passing as the fourth parameter 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/docs', 'heroicons.arrow-up', true), MenuItem::make('Laravel Docs', 'https://laravel.com/docs', 'heroicons.arrow-up', fn() => true), ]) ]; } //...}
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/docs') ->blank(), MenuItem::make('Laravel Docs', 'https://laravel.com/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'), ]; } //...}