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 Translatable Strings Laravel Package

wotz/filament-translatable-strings

Filament Translatable Strings adds a simple Filament admin interface for managing Laravel translation strings. Browse, search, and edit language lines across locales without touching files, making multilingual app maintenance faster and easier for developers and content teams.

View on GitHub
Deep Wiki
Context7

Getting Started

Because this is a single-star, zero-dependent package with no ecosystem track record, the first step is not composer require — it's a 10-minute source audit.

Before installing, read:

  1. composer.json — check the Filament major version constraint (^3.0 vs ^4.0), Laravel/PHP floor, and whether it pulls in anything heavy.
  2. src/*ServiceProvider.php — see what it registers: a Filament plugin, a resource, migrations, commands, or all four.
  3. config/filament-translatable-strings.php (after publishing) — the locales whitelist, translation paths, and storage driver are almost always here.
  4. database/migrations/ — determines whether translations live in the DB or are written back to lang/*.php files. This single fact drives your entire workflow.
  5. README.md for the plugin registration line and any artisan commands.

Install and wire up:

composer require wotz/filament-translatable-strings
php artisan vendor:publish --tag="filament-translatable-strings-config"
php artisan vendor:publish --tag="filament-translatable-strings-migrations"
php artisan migrate

Register the plugin in your panel provider (exact class name per README — typically):

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            \Wotz\FilamentTranslatableStrings\FilamentTranslatableStringsPlugin::make(),
        ]);
}

First use case: give a non-technical editor a UI to fix marketing copy in lang/en/*.php and lang/de/*.php without a PR. Start narrow — one locale pair, one namespace (lang/en/pages.php) — verify the resource lists your existing keys, edit one string, and confirm the change round-trips to the file or DB. Only then widen the scanned paths. If the round-trip is lossy (comments stripped, ordering scrambled), stop and reconsider before letting editors loose.

Pin the version exactly ("wotz/filament-translatable-strings": "1.x.y") — with one star and no dependents, a minor bump is effectively an unreviewed breaking change.

Implementation Patterns

Establish the source of truth first. There are two architectures this package can plausibly use, and they demand opposite workflows:

  • DB-backed (edits stored in a translatable_strings table, read back via a loader): the DB becomes authoritative; lang/*.php is seed data. Deploy must run a seed/sync command or translations diverge between environments. Back up the table like any other content.
  • File-backed (writes directly into lang/**/*.php): git remains authoritative. Treat the Filament UI as a convenience editor on staging, then commit the diff. Never let two editors write simultaneously on a shared filesystem without backup.

Confirm which one you have before designing anything else — the README and the presence/absence of a migration will tell you.

Seeding and scanning. Most packages in this space ship a scan command that walks lang/ (or your __() calls) and imports keys. Wire it into your deploy script once, idempotently:

php artisan translatable-strings:scan   # verify actual command name in README
php artisan migrate --force

Run it after config:cache so the scanner sees production locale paths, not your local ones.

Editor workflow. The healthy loop is: developer adds __('pages.hero.title') in a Blade file → scan picks up the new key → translator fills the German cell in Filament → export/commit (file mode) or cache flush (DB mode). Document this loop for your team; the package provides the UI, not the process.

Authorization. A translation resource exposes every string in your app, including error messages and internal labels. Register a policy or use canAccess() scoped to a translator/admin role (Filament Shield pairs well). Never leave it open to all panel users.

Cache invalidation on save. If your app caches translations (Spatie's loader, custom Cache::remember('lang.'.$locale)), add an observer or model event that flushes the relevant locale key on save. Without it, editors save a string, reload, and see the old value — the #1 support ticket for these tools.

Locale strategy. Restrict the Filament locale switcher to the locales you actually maintain. Editing the fallback locale through the UI is how you get an English string silently overwriting a translation when a key is missing.

CI guardrail. Add a check that lang/en keys are a superset of every other locale, e.g. a small artisan command comparing array_dot(require ...) output. This catches strings added by developers who never opened the Filament UI.

Customization. Filament resources are meant to be extended: subclass the package resource, override table(), form(), getNavigationGroup(), and register yours instead of the package's if the config allows. Publish views (--tag=...-views) before editing them so upgrades don't blow them away.

Gotchas and Tips

  • Treat it as unvetted code. One star, zero dependents, a future-dated release. Read the migration and the save path before production. There is no security review, no CVE history, and no community debugging behind you.
  • PHP-file writing is fragile. If the package writes back to lang/*.php, expect lost comments, reordered keys, and quoting bugs on strings containing ', \, or $. Test with adversarial strings (It's 100% "free" — $5) before trusting it. Prefer DB mode or a JSON-based single file if offered.
  • Key-vs-string formats. JSON translations ({"Welcome": "Willkommen"}) and PHP array files (['welcome' => '...']) behave differently. Scanners frequently handle only one. Verify both if you use both.
  • Vendor namespaces get missed. __('vendor::messages.foo') and nested messages.validation.required keys are common blind spots in scanners — confirm they appear in the resource.
  • Placeholders and plurals. Nothing typically stops a translator from deleting :name or breaking {0} none|{1} one|[2,*] many. Add validation in a custom form field or accept that broken strings reach production.
  • Filament version drift. Plugin registration and resource method signatures changed between Filament v3 and v4. Check the constraint in composer.json against your installed version; a mismatch surfaces as a Class not found or a missing navigation item, not a helpful error.
  • Config cache. After publishing config, php artisan config:clear locally and config:cache in deploy — the scanned paths and locale list are read from config and will silently be the old values otherwise.
  • Missing navigation item debugging. If the resource doesn't appear: confirm the plugin is registered on the correct panel, check canAccess()/policy, check shouldRegisterNavigation(), and run php artisan filament:optimize-clear (or filament:cache-components --clear).
  • Web-user write permissions. File-backed mode needs the PHP process to write inside lang/. That's a deploy-time permissions problem that only appears in production — and a security surface worth avoiding entirely. Prefer an export command plus a CI commit.
  • Extension points to look for: a configurable storage driver (file vs DB), a publishable resource you can subclass, a scanner you can bind your own implementation to, and events fired on save (hook cache flushing there rather than patching the resource).
  • Exit plan. Before adopting, sketch how you'd remove it: if it's DB-backed with a custom loader, you'll need to migrate content back to files. Keep a plain lang/ directory in sync at all times so the package is always disposable.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core