Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Tour Laravel Package

jibaymcs/filament-tour

Bring Driver.js powered guided tours to your Filament panels. Register tours on any page with the HasTour trait and define steps with titles, descriptions, and element targets to elegantly onboard users.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Filament Tour is a thin, opinionated presentation layer: page classes opt in via the HasTour/HasHighlight traits, tours are composed with a fluent Tour::make()->steps(Step::make(...)) builder, and the whole graph is serialized to JSON and handed to DriverJS on the client. That fits our stack well if we treat tours as content/configuration rather than application logic. The package owns almost no server-side behavior — no persistence, no migrations, no domain coupling — which makes it cheap to adopt and cheap to remove. The main architectural coupling is undesirable-by-design: steps target raw CSS selectors (.fi-avatar, .fi-header-heading) against Filament's internal DOM. That is a contract with Filament's markup, not with its public API, and it is the single largest design concern.

Integration feasibility. Straightforward: Composer install pinned to the Filament major (^2.0–^5.0), register FilamentTourPlugin::make() in the panel provider, optionally publish config/views, add the trait plus a tours() method to a page. Extensibility is reasonable — JSON tours loadable from disk or URL, and filament-tour::open-tour / open-highlight Livewire events allow custom triggers (buttons, conditional logic, role-based gating). The trait-based registration means tours live next to the page they describe, which is good for locality and bad for page-class bloat if we author many tours.

Technical risk.

  • Maintainership is the dominant risk. The README carries an explicit, unprompted maintainer notice: "Due to a heavy workload, I'm unable to continue fixing and improving Filament-Tour." That is a public stall declaration on a package that is inherently coupled to a fast-moving framework (Filament ships breaking DOM and asset-pipeline changes every major, and often within minors). The 2026-05-05 release date and changelog contradict the notice somewhat, so verify activity directly rather than trusting metadata. Zero listed dependents plus 124 stars means a very thin user base — we will be early adopters absorbing undiscovered defects.
  • Filament-version treadmill. v2→v5 support implies version-branched code and asset registration paths (Filament v2 script includes vs. v3+ FilamentAsset). Every Filament upgrade becomes a gated dependency upgrade for us. If the package stalls, tours become an upgrade blocker for the admin panel.
  • DOM-selector fragility. Filament v4/v5 introduced significant markup changes; custom themes, Vite builds, and even minor Filament releases will silently break selectors. Failures are quiet (step highlights nothing, or attaches to body) rather than loud.
  • "Only once" is client-side only. only_visible_once is enforced via localStorage per browser, not per user. Clearing storage, private browsing, ITP/blocked storage, or a second device all replay or suppress tours unpredictably. There is no server-side seen-state and therefore no reporting.
  • Remote JSON tours are an untrusted content path. Tour::make(url: ...) fetches and renders arbitrary JSON, and description() accepts HtmlString. If the URL or JSON ever becomes configurable by a non-developer, that is a stored-XSS and SSRF surface. Only allow developer-committed, sanitized sources.
  • Documentation inconsistency. The published config exposes only only_visible_once, yet the documented event-listener recipe reads Config::get('filament-tour.tour_prefix_id'). Either that key is undocumented or the example is stale — a bad signal for a package we would be pinning.

Key questions. Is the package actually receiving fixes for Filament v4/v5 (commit history, open issues, PR latency), or is it effectively in maintenance-freeze? Will we accept owning a fork? Do tours need to be measured (completion rates, drop-off) or is this purely onboarding polish — because nothing here emits analytics. Does the "seen once" semantic need to be per-user-account across devices, and if so, is a custom Livewire listener + DB column acceptable overhead? Which tours are business-critical enough to require regression coverage on every Filament upgrade?

Integration Approach

Stack fit. Good, with one caveat. We are on a standard Filament panel with Livewire/Alpine and a Vite-built custom theme; DriverJS is a mature, dependency-light library and the package's job is mostly registration and serialization. The caveat is SPA navigation — Filament panels navigate via wire:navigate, and DOM-targeting tours triggered on page load are exactly the class of feature that races page swaps. Expect to spend integration effort on when tours fire (page mount/rendered hooks, event-driven opens) rather than on the API itself.

Migration path. Low switching cost in both directions. Adoption is additive: one Composer dependency, one plugin registration, one trait per page. Exit is equally cheap — the tour/step definition objects are simple value objects, so we can port them to a bespoke DriverJS wrapper (driver.js + a small Blade partial + a Livewire component) in roughly 3–5 engineering days, since we are only reimplementing the builder-to-JSON translation. Recommendation: do not architect around this package's traits. Author tours in our own TourDefinition registry (a plain PHP array/JSON committed to the repo, loaded via Tour::make(json: ...)), so that if we fork or replace the package, no page classes change. That converts the maintainer risk into a contained swap.

Compatibility. Pin the Composer constraint to the exact Filament major we run and treat it as a lockstep pair in our upgrade checklist. Confirm DriverJS asset registration works inside our Vite theme (not just Filament's default stack) — that is the most common integration break. Verify the filament-tour::loaded-elements event fires as documented, since our conditional tour logic depends on it. Check for a translation path for button labels and step copy; if absent, override via published views and set nextButtonLabel/previousButtonLabel/doneButtonLabel explicitly per locale.

Sequencing.

  1. Spike (1–2 days): install in a staging panel on our exact Filament version and theme; ship one tour and one highlight; confirm assets, selectors, SPA navigation behavior, and localStorage behavior in Safari private mode.
  2. Decision gate: decide fork-and-own vs. consume-as-is based on commit/issue responsiveness observed during the spike. Default assumption should be we own it.
  3. Pattern definition: tour registry + selector conventions (prefer stable, app-owned selectors we control — e.g. add data-tour="..." attributes to our own Blade/table columns — over .fi-* internals). This is the single highest-leverage mitigation available.
  4. Pilot: 2–3 tours on highest-friction onboarding workflows, gated by role via ->visible(fn () => ...) and a config flag, with an event-driven open for conditional logic.
  5. Instrumentation: wire dispatchOnNext events into our existing analytics so we can see step-level completion and abandonment.
  6. Generalize: only then expose tour authoring to designers/writers as JSON.

Operational Impact

Maintenance. Budget for a fork from day one. Concretely: an owner in the platform team, a standing ticket at every Filament upgrade, and no more than a few days per year of touch time — but the cost is scheduled coupling, not hours. The absence of a second maintainer and near-zero dependent base means no community safety net; we should mirror the repo and be prepared to patch. Also budget for selector drift after any theme refresh; treat the tour suite as a tested artifact, not fire-and-forget content.

Support. No vendor channel — GitHub issues only, on a project whose maintainer has publicly stepped back. Internal first-line support will field "the tour shows up every time" (storage cleared / private browsing / new device) and "the tour highlights nothing" (selector drift) — both are predictable and should be pre-answered in an internal runbook. Because only_visible_once is client-side, we cannot resolve "I already dismissed this" complaints authoritatively without adding our own per-user persistence.

Scaling. Server-side cost is negligible: tour JSON is generated per page render and cached with the page. Client-side cost is one additional JS bundle (DriverJS + package) on panel pages; keep it off pages with no tours if asset registration allows. Two real scaling limits: (a) the "seen once" signal does not scale across users, devices, or tenants — if tours are part of an onboarding compliance story, localStorage is inadequate; (b) remote-URL JSON tours add a runtime network dependency per render — cache or commit them to the repo instead. For multi-tenant panels, remember selectors and tours are global; tenant-specific UI means tenant-specific selector breakage.

Failure modes. Ranked by likelihood × impact:

  • Selector silently misses (high/high) — step shows over an unrelated region or nothing at all; user confusion, no error surfaced.
  • Filament upgrade breaks the package (medium/high) — JS module error can degrade the whole panel's Alpine bundle, not just tours. Mitigation: feature-flag the plugin and be able to disable it via config in one deploy.
  • Uncloseable tour traps users (low/severe) — ->uncloseable() combined with a broken selector is a hard block on a production page. Policy: never ship uncloseable tours outside tightly-scoped first-run flows; always keep an escape path.
  • Tour replays endlessly (medium/medium) — storage unavailable or blocked.
  • JSON content injection (low/severe) — only if tour JSON ever comes from a non-committed source; forbid it.
  • Conditional-open race with Livewire navigation (medium/low) — tour fires mid-navigation and highlights a stale DOM.

Ramp-up. Developer learning curve is short — half a day for the fluent API, one to two days to internalize the targeting and event model. Docs are above average for a community plugin (traits, JSON examples, full method references, a CSS-selector dev tool that is correctly disabled in production) but carry at least one internal inconsistency and a maintainer-abandonment banner that will spook stakeholders. Product/design ramp-up is the real work: someone must decide which workflows are worth a tour, write step copy, localize it, and own it after launch. Recommend naming a content owner before the pilot, and setting the expectation that tours are a maintained artifact requiring re-verification each release cycle — otherwise the feature quietly rots into a source of user-facing bugs within two Filament upgrades.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera