hoceineel/filament-sidebar-editor
A Filament plugin for editing your admin panel sidebar without touching code. Customize navigation items, labels, links, and ordering directly from the UI so each project or team can tailor the menu to fit its workflow, keeping Filament's sidebar flexible and easy to manage.
Architecture fit. This is a Filament panel plugin, not a standalone Laravel package. It hooks the panel's navigation lifecycle through SidebarEditorPlugin::make() and wraps whichever NavigationManager is bound via extend(). That is the correct extension point for this class of feature and is the main reason the package is viable: it composes rather than replaces, so other navigation-modifying packages (e.g. permission-filtered menus, custom resource grouping) can still run. The feature surface — per-panel opt-in, four storage drivers, and a plugin-configurable editor page — maps cleanly onto how Filament teams already think about panels, tenancy, and resources.
Integration feasibility. High for a standard Filament admin panel. Four decisions carry most of the effort: (1) choosing a storage driver, (2) access control for the editor, (3) whether layout state needs a migration, and (4) confirming Filament version support. storeGlobally() is zero-migration and the fastest proof of value; storeOnTenant() and storePerUser() almost certainly require a published migration or an added column, which pulls in a deploy step. The plugin's own Testbench workbench and Playwright suite (hide, drag/drop, save, reset, RTL) run in CI, which is a meaningful credibility signal at v0.1.0 — it indicates the interactive surface, not just the happy-path PHP, is exercised.
Technical risk. The dominant risk is that this is 0.1.0. Filament itself has moved between major versions with navigation API changes, and a package that wraps NavigationManager is directly exposed to that churn. Secondary risks:
| Risk | Severity | Notes |
|---|---|---|
| Pre-1.0 API instability | High | Plugin builder methods (storeOnTenant(), fixedMainGroup(), etc.) can change without a deprecation cycle |
| Filament version compatibility | High | Unstated in the notes; wrapping internal navigation behaviour is version-sensitive |
| Hiding ≠ authorizing | High | Nav visibility is cosmetic; page/resource canAccess() must remain the security boundary. Hiding a page must never be treated as access control |
| NavigationManager wrap ordering | Medium | Composes with other packages, but ordering/interaction with other extend() callers is untested by us |
| Layout identifier drift | Medium | Renamed/moved page classes can orphan saved layouts; removed pages drop out automatically, renames likely do not |
| Migration/deploy coupling | Medium | Tenant and per-user drivers imply schema change and backfill/seed decisions |
Key questions.
storeOnTenant() / storePerUser(), and is the layout payload JSON in a single column?authorize() the only gate, and can it be scoped per panel/role without forking?Stack fit. Assumes Laravel + Filament with at least one panel, and a team already using Filament's native navigation. It is a poor fit for projects that build navigation manually or use a custom non-Filament admin surface. It is a strong fit for multi-tenant SaaS admin panels where "each customer sees the modules they bought" is a recurring ask — the tenant driver plus pinned-item lockout protection covers the two classic failure modes (users hiding their own way back in, and tenants seeing modules they aren't entitled to).
Migration path. Greenfield-friendly and low-ceremony for existing panels:
SidebarEditorPlugin::make() on a single non-production panel.storeGlobally() — no schema change, proves the UX and the drag/drop/save loop.authorize() onto the editor page before any real user touches it.storePerUser() or storeOnTenant() only once you've decided the ownership model; treat the accompanying migration as a normal reviewed schema change with a rollback.Because panels without the plugin keep Filament's navigation untouched, migration is incremental per panel — no big-bang cutover.
Compatibility. Verify against your exact Filament minor version in a branch before committing. Also verify interaction with any package already calling NavigationManager::extend() — the release notes claim composition, but that claim needs to be tested against your set of nav-modifying packages, not in the abstract.
Sequencing. Pilot panel (internal/staging) → permissions and role design → schema driver migration → one design-partner tenant → general availability with the editor page feature-flagged via authorize() so it can be switched off without a deploy. Keep Filament's default navigation as the documented fallback throughout.
Maintenance. Low code footprint, but non-trivial version-tracking burden: pin the package version, watch upstream Filament releases, and budget for a compatibility bump each time Filament ships a major. Treat 0.1.0 as "evaluate, don't standardise" — either vendor-lock it or accept that a minor bump may require code changes. The CI-backed test suite lowers the cost of that tracking considerably.
Support. Expect two ticket classes: "I hid something and can't find it" (mitigated by the always-pinned editor page, non-hideable pinned groups, and show everything / reset / discard affordances — this is well-designed) and "the sidebar looks wrong for one user" (a stored-layout or identifier-drift problem, not a bug report you can reproduce without the user's layout payload). Build a small admin/debug affordance early — the ability to inspect and reset a single user's or tenant's saved layout — because otherwise support means writing SQL.
Scaling. Storage is one small record per user or tenant per panel; that scales comfortably into the tens of thousands of rows. The real scaling costs are (a) rendering the editor page for panels with very large page counts — the "N of M shown" counts and live preview imply full-list processing — and (b) any per-request layout read in the navigation path, which sits on every admin page load. Ask for and measure the query pattern before rollout on a large panel; a per-request cached layout read is the difference between invisible and a global latency tax.
Failure modes. Most likely, in order: stale/corrupt layout payload rendering an empty or partial sidebar (needs a hard fallback to Filament defaults); page rename orphaning saved entries (needs an audit + repair path); interaction with another NavigationManager extender producing wrong ordering; schema/migration deployed without backfill; users expecting hidden pages to be access-restricted when they are only visually hidden — this last one is a product failure mode, not a technical one, and should be documented explicitly for admins.
Ramp-up. Low for anyone fluent in Filament — a competent Filament developer should reach a working per-panel editor in under a day, and the workbench plus e2e suite shortens the "how do I run this" phase. The real ramp-up cost is organisational: deciding the ownership model (global vs. per-user vs. per-tenant), defining who may edit, and communicating to admins that hiding is cosmetic. Budget roughly one engineering day for integration and two to three times that for the ownership/permissions design and rollout comms — the code is the easy part.
How can I help you explore Laravel packages today?