Zum Inhalt springen
← Zurück zu den Projekten

Filament Navigation Footermenu

#Filament Navigation Footer Menu

A Filament v4, v5 panel plugin that adds a configurable footer navigation block to your panel:

  • Sidebar mode (default navigation): a collapsible group at the bottom of the sidebar, aligned with Filament’s native navigation styling. Items expand upward so the trigger stays at the bottom (useful above the user area).
  • Top navigation mode ($panel->topNavigation()): a compact icon trigger with a dropdown menu, placed in the top bar with correct spacing next to the user menu.

Styling uses Filament’s own components and CSS tokens, so light/dark mode matches the rest of your panel.


#Requirements

Requirement Version
PHP ^8.2
Laravel (illuminate components) ^11.0 | ^12.0 | ^13.0
Filament ^4.0 | ^5.0

#Installation

#1. Install the package

From Packagist:

composer require cyberline/filament-navigation-footermenu

From a GitHub/VCS repository (before Packagist, or for forks):

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/CyberLine/filament-navigation-footermenu.git"
        }
    ],
    "require": {
        "cyberline/filament-navigation-footermenu": "^1.0"
    }
}

Local path repository (monorepo or development):

{
    "repositories": [
        {
            "type": "path",
            "url": "packages/filament-navigation-footermenu",
            "options": { "symlink": true }
        }
    ],
    "require": {
        "cyberline/filament-navigation-footermenu": "^1.0"
    }
}

Stable installs: this package declares a concrete version in composer.json so projects with "minimum-stability": "stable" can require it without treating the VCS checkout as dev-main.

#2. Register the Laravel service provider

The package registers FooterMenuServiceProvider via Composer’s extra.laravel.providers for package discovery.

In fresh clones or CI, if bootstrap/cache/packages.php is missing or package:discover did not run, you may see:

No hint path defined for [filament-navigation-footermenu].

Alternatively, ensure composer install / php artisan package:discover completes successfully after every deploy.

#3. Register the Filament plugin on your panel

In your PanelProvider (e.g. app/Providers/Filament/AdminPanelProvider.php), add the plugin to the panel’s plugins array:

use Cyberline\FilamentNavigationFootermenu\Data\FooterMenuItem;
use Cyberline\FilamentNavigationFootermenu\FooterMenuPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugins([
            FooterMenuPlugin::make()
                ->triggerLabel('Legal')
                ->triggerIcon('heroicon-o-scale')
                ->items([
                    FooterMenuItem::make('Privacy policy')
                        ->icon('heroicon-o-shield-check')
                        ->url(fn () => route('legal.privacy'))
                        ->openUrlInNewTab(),
                ]),
        ]);
}

No ->register() call on the plugin is required beyond Filament’s normal plugin registration on the panel.


#Publishing (optional)

Publish and customize config, views, or translations:

php artisan vendor:publish --tag=filament-navigation-footermenu-config
php artisan vendor:publish --tag=filament-navigation-footermenu-views
php artisan vendor:publish --tag=filament-navigation-footermenu-lang

After publishing views, your copies live under resources/views/vendor/filament-navigation-footermenu/.


#Configuration

Default values are merged from config/filament-navigation-footermenu.php.

Key Purpose
trigger.label Default trigger label if you do not call ->triggerLabel() on the plugin.
trigger.icon Default Heroicon name for the trigger when you do not call ->triggerIcon().
heading Optional heading shown above the topbar dropdown list (sidebar group does not use it for the default list UI).
items Array of item definitions (see Array-based items). Used when you do not call ->items() on the plugin.

You can leave everything in config, override everything in the panel, or mix (plugin fluent API wins over config for the options you set).


#Usage

#Fluent API (FooterMenuPlugin)

All chainable methods return static for fluent configuration.

Method Description
triggerLabel(string|Closure|null $label) Label for the sidebar group / accessible name for the topbar icon.
triggerIcon(string|Closure|null $icon) Heroicon (or Filament-supported icon) for the trigger.
heading(string|Closure|null $heading) Optional heading in the topbar dropdown.
items(array|Closure $items) Menu entries: FooterMenuItem instances and/or arrays (see below).
view(?string $bladeView) Custom Blade view for item content (sidebar list and/or dropdown body).
visible(bool|Closure $condition) Hide the entire footer menu when false.
sort(int $sort) Reserved for ordering relative to other plugins (Filament plugin sort).
extraAttributes(array|Closure $attributes) Extra HTML attributes merged onto the root wrapper (e.g. class for a top border).

Example – separator from main nav (Tailwind classes):

FooterMenuPlugin::make()
    ->extraAttributes([
        'class' => 'border-t border-gray-200 pt-3 dark:border-white/10',
    ])
    ->triggerLabel('Legal')
    ->items([ /* ... */ ]);

#Fluent item API (FooterMenuItem)

FooterMenuItem::make(string $label)
    ->icon(?string $icon)                         // Heroicon name, etc.
    ->url(string|Closure|null $url)             // Resolved to string for links
    ->openUrlInNewTab(bool|Closure $open = true)
    ->visible(bool|Closure $visible)
    ->badge(string|int|Closure|null $badge, string|Closure|null $color = null)
    ->badgeTooltip(string|Closure|null $tooltip)

Resolved row shape (useful inside custom Blade): label, icon, url, open_in_new_tab, badge, badge_color, badge_tooltip.

#Array-based items

Arrays are normalized to FooterMenuItem internally. Supported keys:

Key Aliases Notes
label Required, string.
icon Optional string or Closure.
url String, Closure, or null (# when null).
open_in_new_tab openUrlInNewTab, new_tab Boolean or Closure.
visible Boolean or Closure.
badge String, int, Closure, or null.
badge_color badgeColor Optional string or Closure.
badge_tooltip badgeTooltip Optional string or Closure.

Example:

FooterMenuPlugin::make()->items([
    [
        'label' => 'Imprint',
        'icon' => 'heroicon-o-identification',
        'url' => fn () => route('legal.imprint'),
        'new_tab' => true,
        'badge' => '!',
        'badge_color' => 'danger',
        'badge_tooltip' => 'Action required',
    ],
]);

#Dynamic items with Closure

FooterMenuPlugin::make()->items(fn () => [
    FooterMenuItem::make('Dashboard')
        ->url(fn () => url('/'))
        ->visible(fn () => auth()->user()?->isAdmin() ?? false),
]);

#Custom Blade view

Point the plugin at your own view:

FooterMenuPlugin::make()
    ->view('components.my-footer-menu');

Your view is included with the following variables (non-exhaustive):

Variable Description
$plugin The FooterMenuPlugin instance.
$layout 'sidebar' or 'topbar'.
$heading Resolved heading string or null.
$triggerLabel Resolved trigger label.
$triggerIcon Resolved trigger icon or null.
$items Array of resolved item rows (see shape above).
$topbarAfterUserMenu booltrue when the topbar UI is rendered after the user menu (inside .fi-topbar-end). Useful if your custom markup needs different spacing.

When a custom view is set, the plugin still renders the outer shell (sidebar group / dropdown); your view replaces the default list of links only.


#Behaviour & layout

#Sidebar (default navigation)

  • Registered on PanelsRenderHook::SIDEBAR_FOOTER.
  • Renders below other sidebar footer content (e.g. user menu when shown in the sidebar), matching Filament’s footer hook order.
  • Uses Filament sidebar group / item classes so spacing matches the main navigation.

#Top navigation

  • When the panel uses top navigation, the plugin does not render in the sidebar footer hook for that panel state.
  • Primary placement: PanelsRenderHook::USER_MENU_AFTER — output sits inside .fi-topbar-end, so Filament’s gap-x-4 applies between the user menu and your trigger (no overlap with the avatar).
  • Fallback: if there is no user menu in the topbar (userMenu(false) or user menu only in the sidebar), the plugin renders on PanelsRenderHook::TOPBAR_END instead, with extra margin so the trigger does not collide with adjacent controls.

The topbar trigger is an x-filament::icon-button with a circular hit area and hover styles consistent with Filament.

#Visibility and tenancy

The plugin does not render when:

  • the user is not authenticated in the current panel context, or
  • the panel has tenancy enabled and no tenant is resolved yet, or
  • ->visible(false) (or a Closure resolving to false) is set on the plugin.

Use ->visible() for feature flags, permissions, or environment-specific menus.


#Translations

The package ships with English and German language files under the filament-navigation-footermenu translation namespace.

Example:

__('filament-navigation-footermenu::footermenu.default_trigger_label');

Publish if you need to override strings per app.


#Tailwind / Vite (Filament theme)

This package’s Blade views use Tailwind utility classes (for example px-6, pb-3, flex) alongside Filament’s fi-* classes. Filament’s default pre-built panel CSS is compiled from Filament’s own sources only; it does not scan vendor/cyberline/filament-navigation-footermenu, so those utilities may be missing in the browser unless your app compiles a custom Filament theme that includes this package in Tailwind’s content scan.

#Required steps (Filament v4+ with Vite)

  1. Create a panel theme CSS file (e.g. resources/css/filament/{panel-id}/theme.css). The Filament stub pattern is:

    @import '../../../../vendor/filament/filament/resources/css/theme.css';
    
    @source '../../../../app/Filament/**/*';
    @source '../../../../resources/views/filament/**/*';
    @source '../../../../vendor/cyberline/filament-navigation-footermenu/resources/views/**/*.blade.php';
    

    Adjust relative paths if your file lives elsewhere.

  2. Register the theme on your panel in PanelProvider:

    return $panel
        ->viteTheme('resources/css/filament/admin/theme.css'); // path to your theme.css
    
  3. Add the theme to Vite in vite.config.js (Laravel Vite input array) so it is built with npm run build / npm run dev.

  4. Rebuild assets after upgrading this package, editing its views, or changing Tailwind classes in the theme (npm run build, or keep npm run dev running).

#If you publish views

After php artisan vendor:publish --tag=filament-navigation-footermenu-views, add an @source line for your app copy so Tailwind scans the published blades, for example:

@source '../../../../resources/views/vendor/filament-navigation-footermenu/**/*.blade.php';

You can keep or remove the vendor @source depending on whether you still load views from the package.

#Optional: avoid a custom theme

You can avoid relying on extra Tailwind utilities by using only Filament’s documented fi-* patterns and inline styles the default bundle already includes, or by shipping a tiny non-Tailwind CSS file — but the default package views expect a theme build that scans them as above.


#License

MIT — see LICENSE.md.

Neue Version verfügbar.