jeffersongoncalves/filament-pirsch
Filament Pirsch brings privacy-friendly Pirsch analytics into your Laravel Filament admin panel, adding dashboard widgets and reports for visitors, pageviews, and traffic sources so you can monitor site performance without leaving Filament.
Architecture fit. This package is a Filament panel plugin that contributes a settings page; 3.1.0 adds Plugin::make()->navigationGroup(string|Closure), letting the page be registered into one of the host panel's existing navigation groups instead of the plugin's hard-coded translated group. Architecturally this is a small, well-scoped extension point on the plugin's configuration surface — it does not alter persistence, routing, authorization, or the analytics data path. It improves fit with panels that enforce a curated navigation taxonomy (e.g., grouping all "Settings" or "Insights" items together), which is the common case in multi-plugin admin panels. It is additive and opt-in: absent the call, behaviour is unchanged and the translated default group is retained, so existing panels are unaffected.
Integration feasibility. Trivial to adopt: a single fluent call on the plugin registration in the panel provider, with either a string (a group label, presumably translatable) or a Closure (for conditional/dynamic grouping, e.g. per-tenant or role-dependent labels). Acceptance is a closure that resolves a valid label at render time; the main prerequisite is that the host panel already defines the target group or accepts a new one. No migrations, no data model changes, no asset republishing.
Technical risk. Low, with two watch items:
filament-analytics-core 3.1. Projects pinned below that will get a plugin that either cannot expose the method or fails at runtime/composer resolution. This must be treated as a minimum-version gate rather than an optional nicety.Closure. The signature is documented as string|Closure, but the closure's signature, return contract, and evaluation timing (per-request vs. cached per panel boot) are not specified in the release note. A closure evaluated at boot with tenant context unavailable is a realistic misconfiguration that would surface as a wrong or empty navigation label — a cosmetic-but-visible defect that is hard to trace back to configuration.Key questions. (1) What is the closure signature and when is it evaluated — request time, panel boot, or cached? (2) Is the string value passed through Laravel's translator, and does passing an already-translated string risk double translation? (3) Does the package's composer.json now declare filament-analytics-core: ^3.1, or is the requirement enforced only at runtime? (4) What happens if the named group does not exist in the panel — silent fallback, new group creation, or exception? (5) Is the previous default group still emitted when the argument is an empty string or a closure returning null?
Stack fit. Assumes a Laravel application running Filament (v3-era admin panel conventions) plus filament-analytics-core 3.1+. No additional runtime services, queues, or storage are involved; this is presenter-layer configuration only. Panels with a governed navigation structure benefit most; single-plugin or minimal panels gain little and can leave the default.
Migration path. Additive and reversible. Adoption is one line in the panel provider's plugin registration — Plugin::make()->navigationGroup('Settings'), or a closure for dynamic labelling. Rollback is deleting that call; there is no state to unwind. No published config or view overrides need republishing for this change.
Compatibility. Two dimensions to verify before rollout:
filament-analytics-core >= 3.1 resolves in the target lockfile; if the project pins core at 3.0.x, either bump core first or hold the plugin at its previous line. Check whether the constraint is declared in composer.json (fail fast, preferred) or merely assumed (runtime failure).NavigationGroup semantics before committing.Sequencing. (1) Bump filament-analytics-core to 3.1 in a branch and run the full test suite / a composer update --dry-run to surface constraint conflicts. (2) Upgrade the plugin to 3.1.0 with no configuration change and confirm the settings page still appears in its default group — this isolates upgrade risk from configuration risk. (3) Optionally add navigationGroup(...) in one non-production panel and verify label, ordering, and icon placement. (4) Roll to production panels; if using a closure, ship it behind the same authorization logic that gates the page itself, so labels and visibility cannot diverge.
Maintenance. Near-zero ongoing cost. The API surface added is one fluent method; there is no new configuration file, migration, or scheduled work. The only recurring maintenance is keeping the core dependency floor aligned — a version pin in composer.json is the cheapest way to make that visible to future maintainers and to CI.
Support. Support burden is low but not zero, and it concentrates in two predictable tickets: "the settings page is in the wrong menu group" (configuration, usually a group name that does not match the panel's defined groups) and "class/method not found after upgrade" (core pinned below 3.1). Both are answered by documentation that states the core requirement and enumerates the panel's valid group names. Worth adding a short note to internal runbooks: which group the analytics settings page occupies, and whether it is static or closure-driven.
Scaling. No scaling implications — this is menu rendering per panel request, negligible relative to the analytics queries the package's pages actually execute. If the closure form is used and evaluated per request, cost is a string return; if it is evaluated once per panel boot, it is effectively free. No multi-tenant fan-out concerns beyond ensuring any closure reads tenant context that is already resolved at that point in the request lifecycle.
Failure modes. Ranked by likelihood and blast radius:
Call to undefined method navigationGroup() when core is below 3.1. Blast radius is the entire panel (unbootable admin), which makes the dependency floor the highest-priority check.null/empty, producing a page that renders but is hard to find. Low blast radius, high support cost because it looks like a bug in Filament's navigation rather than in configuration.Ramp-up. Minutes for a developer already fluent in Filament panel configuration; the change is a single documented call. For a team new to Filament, budget a short orientation on how panel navigation groups are declared and ordered, since the value of this feature depends on the host panel having a deliberate group taxonomy. Recommended effort: a half-day spike covering the core bump, a staging deploy, and a visual check of navigation placement — dominated by dependency verification, not by the feature itself.
How can I help you explore Laravel packages today?