jeffersongoncalves/filament-simple-analytics
Filament Simple Analytics is a Laravel/Filament plugin that adds lightweight analytics views to your admin panel, helping you monitor key site metrics from a simple, configurable dashboard.
The 3.1.0 release adds one fluent method to the plugin: Plugin::make()->navigationGroup(string|Closure). Everything else is unchanged, so existing installs keep working — the translated default group is still applied when you don't call it.
Minimal setup:
navigationGroup() method is only wired up against the core 3.1 navigation API; on core 3.0 the call is not supported.public function panel(Panel $panel): Panel
{
return $panel
->plugin(
Plugin::make()
->navigationGroup('Reports'),
);
}
php artisan filament:optimize-clear, or optimize:clear) and reload the panel.Look first at: the Plugin class itself (to see what other fluent setters exist — label, sort, icon are commonly siblings), then the panel provider where the plugin is registered. The core package's navigation registration is the second stop, since 3.1.0's behaviour is defined there.
First real use case: your panel already has a "Reports" or "Insights" group and the plugin's translated group ("Analytics", "Statistiken", …) is creating a second, near-duplicate header in the sidebar. One call fixes it.
Static string for single-panel apps. The common case is one panel with an established group name. Pass the literal string and you're done — no closure needed.
Closure for config- or locale-driven grouping. Use the closure form when the group name comes from config, a translation key, or tenancy:
Plugin::make()->navigationGroup(
fn () => config('analytics.navigation_group', 'Reports')
)
This keeps the group name out of code and lets you override per environment without touching the provider.
Per-panel grouping in multi-panel apps. The plugin is registered per panel, so register a separate instance in each provider with a group name appropriate to that panel's audience (e.g. 'Reports' for the admin panel, 'Settings' for a tenant panel). Don't try to share one configured instance across panels.
Align with sibling resources. Once the plugin lives in a real group, give it a sort order that matches its neighbours so it doesn't appear above or below where you'd expect. If the plugin exposes navigationSort() / navigationLabel() / navigationIcon() in your version, set them in the same fluent chain — keeps the intent in one readable place:
Plugin::make()
->navigationGroup('Reports')
->navigationSort(10)
Upgrade workflow. Bump filament-analytics-core to ^3.1 first and run your test suite, then publish the plugin bump and start adopting navigationGroup(). Doing both in one commit makes it hard to tell whether a nav regression came from core or from your new group call.
Test it. Filament panel tests can assert the rendered navigation contains the expected group. A cheap regression test — "the plugin page renders under my custom group" — catches core-version drift after future upgrades.
Version lockstep is the real risk. 3.1.0 explicitly requires filament-analytics-core 3.1. If your composer.json pins core to 3.0.*, Composer will either refuse the plugin update or you'll end up with a plugin that calls a method the installed core doesn't provide. Bump core first; check composer why filament-analytics-core if the resolver surprises you.
This is opt-in, not a breaking change. If you never call navigationGroup(), you keep the translated group exactly as before. Don't schedule a migration for it; adopt it where the nav genuinely looks wrong.
Duplicate group headers are the symptom to look for. Filament matches groups by their resolved string. A translated default ("Analytics") and your custom "Reports" will both render. Set the group once, consistently, and check for hard-coded strings elsewhere that re-introduce the old label.
Keep the closure cheap. Navigation is built on every panel page render. A closure that hits the database, resolves tenancy, or calls a slow service will tax every request. Read from config or a cached value instead.
Watch closure return types. The method accepts string|Closure; a closure returning null or an empty string is undefined territory — if it happens to fall back to the translated group in your version, don't rely on it. Return a non-empty string or don't call the method.
Cache clearing is not optional. Filament caches panel and navigation metadata. After changing the group, run php artisan filament:optimize-clear before concluding the call "doesn't work" — this is the single most common false negative when debugging nav changes.
Config caching. If your group name comes from config(), remember php artisan config:cache in production freezes it; a closure reading config still resolves against the cached values, so deploy-time changes require a cache rebuild.
Extension points beyond grouping. Grouping alone rarely fixes a nav entry. Pair it with the plugin's label/icon/sort setters (where exposed) rather than post-processing the navigation in a service provider — the fluent API is the supported path and survives upgrades better than reaching into Filament's navigation builder.
How can I help you explore Laravel packages today?