jeffersongoncalves/filament-how-it-works
A Filament plugin for adding "how it works" help and onboarding content to your admin panel, letting you attach explanatory guides, hints, or walkthroughs to pages and resources so users understand features without leaving the interface.
Install
composer require jeffersongoncalves/filament-how-it-works:"^1.1"
Requires PHP 8.1+, Laravel 10/11+ and a matching Filament 3.x minor — check the composer.json of the tagged release before upgrading a panel that pins Filament tightly.
Register the plugin in the panel provider where the "how it works" content should appear:
use JeffersonGoncalves\FilamentHowItWorks\HowItWorksPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(HowItWorksPlugin::make());
}
Where to look first
vendor/jeffersongoncalves/filament-how-it-works/config/ — the plugin's publishable config (labels, visibility, ordering).vendor/jeffersongoncalves/filament-how-it-works/resources/lang/ — as of 1.1.0 this now holds 17 locales, and it is the source of truth for which keys are translatable.src/HowItWorksPlugin.php + any Page/Widget it registers) — small surface area, readable in a few minutes.First use case: drop the plugin onto an existing panel, let it render the default steps/instructions block, then move the step titles and descriptions into your own translation keys so the 1.1.0 locales actually benefit your users.
Publishing (optional but usually wanted):
php artisan vendor:publish --tag=filament-how-it-works-config
php artisan vendor:publish --tag=filament-how-it-works-translations
Only publish translations if you intend to override them — see Gotchas.
Panel-scoped registration. Register per panel rather than globally so a admin panel and a customer-facing app panel can present different onboarding copy. Filament resolves plugins per panel, so ->plugin(...) inside one provider keeps the other panels untouched.
Translation overrides instead of forks. With 1.1.0 shipping ar, az, de, es, fa, fr, hi, it, ja, nl, pl, pt, ru, tr, uk, uz, zh_CN, the day-to-day pattern is:
// lang/vendor/filament-how-it-works/de/how-it-works.php
return [
'heading' => 'So funktioniert es',
// only override the keys you need; the rest fall back to the package file
];
Publish once, trim the file down to the keys you changed, and keep the vendor path (lang/vendor/<package-namespace>/<locale>/…) intact so Laravel's package translation loader keeps merging.
Your own step content should be translatable too. The package only translates its own strings. Store step titles/descriptions as keys (__('onboarding.steps.invite.title')) in the config, not literal strings, otherwise a German user sees a German heading above English steps.
Locale switch driven by the user. Typical flow: app()->setLocale($user->locale) in a middleware, then the plugin automatically picks up the matching package locale. Test with de, ja and ar (RTL) — those three expose alignment, wrapping and direction bugs fastest.
Multi-locale test matrix. Add a Pest/PHPUnit case that loops the 17 locales, boots the panel and asserts the page renders 200 and the expected heading key resolves — cheap regression coverage for future translation PRs.
Docs/screenshot workflow. Because this is a "how it works" surface, it is often the first thing new admins see. Keep the published config in your repo (not just in vendor/) so copy changes go through code review.
zh_CN vs zh-CN. The shipped directory uses the underscore form Laravel expects (zh_CN). If your app sets app()->setLocale('zh-CN'), the package translations will silently fall back to en. Normalise the locale string, or add a zh-CN alias directory containing a single require-ing file.
RTL is not automatic in your own markup. Filament sets document direction from the locale, but any custom Blade you inject into the plugin's view needs logical properties (ms-*, ps-*) rather than ml-*/pl-*. ar and fa are now first-class — verify them.
Published translations freeze at 1.1.0. Once lang/vendor/... exists, new package keys added in a later release won't appear for that locale. Re-publish and diff (git diff) after every upgrade, or skip publishing and override only via a custom namespace.
Long strings break layouts. German and Russian labels run ~30–40% longer; Japanese/Chinese wrap differently. Check fixed-width step cards and button groups at de, ru, ja before shipping.
Clear caches after touching translations. php artisan optimize:clear (and view:clear if you published views). Translated strings are cached by the translator and by config/view caches; a stale bootstrap/cache is the usual cause of "the translation file is right but the page is English."
Missing keys fall back silently. A typo in an override file produces English, not an error. Verify with Lang::has('filament-how-it-works::how-it-works.heading', 'de') in tinker when a locale looks wrong.
Locale ≠ user preference. If you rely on Filament's locale switcher, remember it writes to the session, not the user record; persist it yourself if onboarding copy must stay stable across devices.
Upgrade path is low-risk. 1.1.0 is additive (translations + CI/docs); no deprecations are announced. Still pin ^1.1 and run your panel's rendered-page tests after bumping, since plugin registration order can change navigation grouping if the release also touched service-provider wiring.
Extension points to prefer: publishing the config (content/visibility), publishing translations (i18n), and Blade view overrides as a last resort — overridden views are the most likely thing to break on the next minor.
How can I help you explore Laravel packages today?