导航栏
概述
简介
默认情况下,Filament 将为每个资源、自定义页面 和 Clusters 注册导航项目。这些类都包含一些静态属性和方法,你可以重写配置导航项目。
如果你想在应道的导航中添加第二层导航,可以使用 Clusters。这对于将资源和页面分组到一起很有用。
自定义导航项标签
默认情况下,导航标签是由资源或者页面名称生成。你可以使用 $navigationLabel
属性自定义:
protected static ?string $navigationLabel = 'Custom Navigation Label';
此外,你也可以自定义 getNavigationLabel()
方法:
public static function getNavigationLabel(): string
{
return 'Custom Navigation Label';
}
自定义导航项图标
要自定义导航项的图标,你可以重写资源或页面类的 $navigationIcon
属性:
use BackedEnum;
protected static string | BackedEnum | null $navigationIcon = 'heroicon-o-document-text';

If you set $navigationIcon = null
on all items within the same navigation group, those items will be joined with a vertical bar below the group label.
当导航项激活时切换图标
通过 $activeNavigationIcon
属性,你指定一个仅用于导航项激活时的图标:
protected static ?string $activeNavigationIcon = 'heroicon-o-document-text';

导航项排序
默认情况下,导航项按照字母顺序排序。你可以使用 $navigationSort
属性自定义排序:
protected static ?int $navigationSort = 3;
排序值较低的导航项会排在排序值高的项目之前,排序顺序为升序。

添加徽章到导航项中
要在导航项旁添加徽章,你可以使用 getNavigationBadge()
方法并返回徽章内容:
public static function getNavigationBadge(): ?string
{
return static::getModel()::count();
}

如果 getNavigationBadge()
返回徽章值,则默认情况下将使用 primary 颜色显示。要根据上下文设置徽章样式,请在 getNavigationBadgeColor()
方法返回 danger
、gray
、info
、primary
、success
或 warning
:
public static function getNavigationBadgeColor(): ?string
{
return static::getModel()::count() > 10 ? 'warning' : 'primary';
}

导航徽章的自定义 tooltip 提示可以在 $navigationBadgeTooltip
中进行设置:
protected static ?string $navigationBadgeTooltip = 'The number of users';
或者也可以由 getNavigationBadgeTooltip()
返回:
public static function getNavigationBadgeTooltip(): ?string
{
return 'The number of users';
}

导航项分组
通过指定资源和自定义页面中的 $navigationGroup
属性,你可以对导航项进行分组:
use UnitEnum;
protected static string | UnitEnum | null $navigationGroup = 'Settings';

处于同一个分组的项目将会展示在同一个分组标签之下,比如上例中的 Settings
。未分组项将保留在导航的起始位置。.
在其他项目之下分组导航项
将父项标签传入到 $navigationParentItem
中,你可以将导航项作为其他项目的子项:
use UnitEnum;
protected static ?string $navigationParentItem = 'Notifications';
protected static string | UnitEnum | null $navigationGroup = 'Settings';
你也可以使用 getNavigationParentItem()
动态设置父项标签:
public static function getNavigationParentItem(): ?string
{
return __('filament/navigation.groups.settings.items.notifications');
}
如上所示,如果父项有导航分组,就必须定义导航分组,这样磁能正确识别父项。
TIP
如果你寻找类似的第三级导航分组,则可以考虑 Clusters,它是资源和自定义页面的逻辑分组,可以共享自己的单独导航。
自定义导航分组
在配置中调用 navigationGroups()
并按照顺序传入 NavigationGroup
对象,你可以自定义导航分组:
use Filament\Navigation\NavigationGroup;
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigationGroups([
NavigationGroup::make()
->label('Shop')
->icon('heroicon-o-shopping-cart'),
NavigationGroup::make()
->label('Blog')
->icon('heroicon-o-pencil'),
NavigationGroup::make()
->label(fn (): string => __('navigation.settings'))
->icon('heroicon-o-cog-6-tooth')
->collapsed(),
]);
}
本例中,我们为分组传入了自定义的 icon()
,并让其默认折叠 collapsed()
。
排序导航分组
使用 navigationGroups()
,你可以为导航分组定义新排序。如果你想要重新排序分组,而不是定义所有 NavigationGroup
对象,你可以以新的排序传入分组标签:
$panel
->navigationGroups([
'Shop',
'Blog',
'Settings',
])
让导航分组不可折叠
默认情况下,导航分组是可折叠的。

通过在 NavigationGroup
对象调用 collapsible(false)
,你可以禁用该行为:
use Filament\Navigation\NavigationGroup;
NavigationGroup::make()
->label('Settings')
->icon('heroicon-o-cog-6-tooth')
->collapsible(false);

或者,你可以在配置全局禁用可折叠,使之使用所有的分组:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->collapsibleNavigationGroups(false);
}
向导航分组添加额外的 HTML 属性
You can pass extra HTML attributes to the navigation group, which will be merged onto the outer DOM element. Pass an array of attributes to the extraSidebarAttributes()
or extraTopbarAttributes()
method, where the key is the attribute name and the value is the attribute value:
NavigationGroup::make()
->extraSidebarAttributes(['class' => 'featured-sidebar-group']),
->extraTopbarAttributes(['class' => 'featured-topbar-group']),
The extraSidebarAttributes()
will be applied to navigation group elements contained in the sidebar, and the extraTopbarAttributes()
will only be applied to topbar navigation group dropdowns when using top navigation.
桌面端可折叠侧边栏
To make the sidebar collapsible on desktop as well as mobile, you can use the configuration:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarCollapsibleOnDesktop();
}

By default, when you collapse the sidebar on desktop, the navigation icons still show. You can fully collapse the sidebar using the sidebarFullyCollapsibleOnDesktop()
method:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarFullyCollapsibleOnDesktop();
}

Navigation groups in a collapsible sidebar on desktop
NOTE
This section only applies to sidebarCollapsibleOnDesktop()
, not sidebarFullyCollapsibleOnDesktop()
, since the fully collapsible UI just hides the entire sidebar instead of changing its design.
When using a collapsible sidebar on desktop, you will also often be using navigation groups. By default, the labels of each navigation group will be hidden when the sidebar is collapsed, since there is no space to display them. Even if the navigation group itself is collapsible, all items will still be visible in the collapsed sidebar, since there is no group label to click on to expand the group.
These issues can be solved, to achieve a very minimal sidebar design, by passing an icon()
to the navigation group objects. When an icon is defined, the icon will be displayed in the collapsed sidebar instead of the items at all times. When the icon is clicked, a dropdown will open to the side of the icon, revealing the items in the group.
When passing an icon to a navigation group, even if the items also have icons, the expanded sidebar UI will not show the item icons. This is to keep the navigation hierarchy clear, and the design minimal. However, the icons for the items will be shown in the collapsed sidebar’s dropdowns though, since the hierarchy is already clear from the fact that the dropdown is open.
Registering custom navigation items
To register new navigation items, you can use the configuration:
use Filament\Navigation\NavigationItem;
use Filament\Pages\Dashboard;
use Filament\Panel;
use function Filament\Support\original_request;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigationItems([
NavigationItem::make('Analytics')
->url('https://filament.pirsch.io', shouldOpenInNewTab: true)
->icon('heroicon-o-presentation-chart-line')
->group('Reports')
->sort(3),
NavigationItem::make('dashboard')
->label(fn (): string => __('filament-panels::pages/dashboard.title'))
->url(fn (): string => Dashboard::getUrl())
->isActiveWhen(fn () => original_request()->routeIs('filament.admin.pages.dashboard')),
// ...
]);
}
Conditionally hiding navigation items
You can also conditionally hide a navigation item by using the visible()
or hidden()
methods, passing in a condition to check:
use Filament\Navigation\NavigationItem;
NavigationItem::make('Analytics')
->visible(fn(): bool => auth()->user()->can('view-analytics'))
// or
->hidden(fn(): bool => ! auth()->user()->can('view-analytics')),
Disabling resource or page navigation items
To prevent resources or pages from showing up in navigation, you may use:
protected static bool $shouldRegisterNavigation = false;
Or, you may override the shouldRegisterNavigation()
method:
public static function shouldRegisterNavigation(): bool
{
return false;
}
Please note that these methods do not control direct access to the resource or page. They only control whether the resource or page will show up in the navigation. If you want to also control access, then you should use resource authorization or page authorization.
Using top navigation
By default, Filament will use a sidebar navigation. You may use a top navigation instead by using the configuration:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->topNavigation();
}

Customizing the width of the sidebar
You can customize the width of the sidebar by passing it to the sidebarWidth()
method in the configuration:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarWidth('40rem');
}
Additionally, if you are using the sidebarCollapsibleOnDesktop()
method, you can customize width of the collapsed icons by using the collapsedSidebarWidth()
method in the configuration:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->sidebarCollapsibleOnDesktop()
->collapsedSidebarWidth('9rem');
}
Advanced navigation customization
The navigation()
method can be called from the configuration. It allows you to build a custom navigation that overrides Filament’s automatically generated items. This API is designed to give you complete control over the navigation.
Registering custom navigation items
To register navigation items, call the items()
method:
use App\Filament\Pages\Settings;
use App\Filament\Resources\Users\UserResource;
use Filament\Navigation\NavigationBuilder;
use Filament\Navigation\NavigationItem;
use Filament\Pages\Dashboard;
use Filament\Panel;
use function Filament\Support\original_request;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigation(function (NavigationBuilder $builder): NavigationBuilder {
return $builder->items([
NavigationItem::make('Dashboard')
->icon('heroicon-o-home')
->isActiveWhen(fn (): bool => original_request()->routeIs('filament.admin.pages.dashboard'))
->url(fn (): string => Dashboard::getUrl()),
...UserResource::getNavigationItems(),
...Settings::getNavigationItems(),
]);
});
}

Registering custom navigation groups
If you want to register groups, you can call the groups()
method:
use App\Filament\Pages\HomePageSettings;
use App\Filament\Resources\Categories\CategoryResource;
use App\Filament\Resources\Pages\PageResource;
use Filament\Navigation\NavigationBuilder;
use Filament\Navigation\NavigationGroup;
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigation(function (NavigationBuilder $builder): NavigationBuilder {
return $builder->groups([
NavigationGroup::make('Website')
->items([
...PageResource::getNavigationItems(),
...CategoryResource::getNavigationItems(),
...HomePageSettings::getNavigationItems(),
]),
]);
});
}
Disabling navigation
You may disable navigation entirely by passing false
to the navigation()
method:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->navigation(false);
}

Disabling the topbar
You may disable topbar entirely by passing false
to the topbar()
method:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->topbar(false);
}
Disabling breadcrumbs
The default layout will show breadcrumbs to indicate the location of the current page within the hierarchy of the app.
You may disable breadcrumbs in your configuration:
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->breadcrumbs(false);
}
Reloading the sidebar and topbar
Once a page in the panel is loaded, the sidebar and topbar are not reloaded until you navigate away from the page, or until a menu item is clicked to trigger an action. You can manually reload these components to update them by dispatching a refresh-sidebar
or refresh-topbar
browser event.
To dispatch an event from PHP, you can call the $this->dispatch()
method from any Livewire component, such as a page class, relation manager class, or widget class:
$this->dispatch('refresh-sidebar');
When your code does not live inside a Livewire component, such as when you have a custom action class, you can inject the $livewire
argument into a closure function, and call dispatch()
on that:
use Filament\Actions\Action;
use Livewire\Component;
Action::make('create')
->action(function (Component $livewire) {
// ...
$livewire->dispatch('refresh-sidebar');
})
Alternatively, you can dispatch an event from JavaScript using the $dispatch()
Alpine.js helper method, or the native browser window.dispatchEvent()
method:
<button x-on:click="$dispatch('refresh-sidebar')" type="button">
Refresh Sidebar
</button>
window.dispatchEvent(new CustomEvent('refresh-sidebar'));
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion