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 Translation Manager Laravel Package

asignua/filament-translation-manager

A Filament plugin for managing Laravel translation files from your admin panel. Browse, edit, add, and organize translations across locales in a simple UI, keeping language files tidy without touching PHP arrays by hand.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Locale launch / market-readiness gating. The "Missing in" filters plus per-group counts turn "are we ready to ship Ukrainian?" into a queryable number instead of a spreadsheet. A PM can set a coverage threshold per locale and hold a release on it, or consciously ship partially translated and accept the gap.
  • Build vs. buy (buy). This is a commodity internal tool: a translations resource on spatie/laravel-translation-loader's language_lines, a code scanner, JSON import/export, a quick-translate page, and a language switcher. Building that in-house is weeks of engineering for zero differentiation. The package is schema-coupled to a library the team likely already uses, so the "buy" cost is a config file, not a data migration.
  • Roadmap: who translates, and how. JSON export/import per language is a clean hand-off format for a translation agency or an MT pipeline, and the quick-translate page covers the "one string changed in a demo, fix it now" case. That supports a real decision: do we staff internal editors, contract an agency, or wire MT — the package stays neutral and supports all three.
  • Localization debt triage. orphaned_at lets you quantify dead strings ("we're carrying 1,400 keys no code references") and then decide whether to clean up. Crucially, --prune defaults to mark, not delete, so this analysis is safe to run in production and the destructive behaviour is a separate, deliberate opt-in (prune.mode=delete).
  • Editorial sign-off and quality ownership. confirmed_at distinguishes "a machine/key-fill put text here" from "a human vouched for this string," and confirmed rows are excluded from "Missing." That's the difference between a coverage metric you can put in a board deck and one you can't. It also gives you a per-locale reviewer workflow without buying a TMS.
  • Respecting editorial intent as a product rule. A locale an editor cleared is stored as null and the scan never refills it; the scan is additive and never overwrites edited text. This means "run the scan" is a safe, repeatable operation you can put on a schedule or a button — not a change-freeze event.
  • Scope control by product surface. Config groups limits the resource, counts, quick translate, and scan to selected namespaces, and skip_group_like_keys filters out validation.*-style noise. You can roll this out to one feature area first and exclude vendor/validation strings from the editor's view.
  • Support and CS workflows. Search covers the key and the text->locale of every configured locale (not raw JSON), so a support agent can find the copy behind a screen without knowing the key naming convention. This is a small feature with outsized impact on non-engineer adoption.
  • Embed vs. standalone admin. config('table'), Locales::resolveUsing(), TranslationManagerPlugin::resource(), navigation closures, and the scopeQuery() / extraColumns() / extraRecordActions() hooks decide whether this lives inside the existing admin panel and inherits its permissions, or sits beside it. That's an architecture call the PM should be in on, because it determines whether editors need a second login.
  • Access control as a default-secure decision. The manageTranslations and deleteTranslations gates are closed unless you define them, and delete is gated. Translation text is user-facing copy with SEO and legal exposure; "no one can mass-delete strings by accident" is a launch requirement, not a nicety.

When to Consider This Package

Consider adopting when:

  • You are on (or willing to adopt) spatie/laravel-translation-loader and its language_lines table. The package is explicitly built on that schema; the migration stubs read config('table'), so a rename is supported but a different schema is not.
  • Your admin surface is a Filament-style panel — resource, header action, record actions, plugin registration, navigation closures are all first-class here.
  • You have a DB-backed translation store and more than a handful of locales or strings. The payoff is the scan (finding every __(), trans(), trans_choice(), @lang, Lang::get() and lang-file string), the missing/orphaned views, and the editor UI — this is overhead for a single-locale app with 80 strings.
  • You want translator-facing tooling without a TMS contract: export/import, quick translate, confirm/filter, per-locale coverage.
  • You already have an existing language_lines table — the make_language_lines_keys_binary stub retrofits utf8mb4_bin onto it. This is the single most valuable migration in the release: it makes the unique (group, key) pair agree with the scanner's byte-exact comparison, which is exactly the class of bug (two keys that look identical, one silently shadowing the other) that erodes trust in a translation tool.

Look elsewhere when:

  • You need real translation-management workflow: per-string revision history, comments/threads, multi-reviewer approval chains, translator roles and assignments, translation memory, or vendor/MT API sync. confirmed_at is a single flag, not an audit trail.
  • You need file-based (lang/ only) translations with no database — the scan reads lang files, but the product is the language_lines resource.
  • You are not on Laravel, or you have a large in-house localization platform already.
  • You need runtime locale negotiation, geo/IP detection, or per-user locale persistence beyond the opt-in switcher; that switcher is a convenience, not an i18n strategy.
  • You need very high-volume automated translation (tens of thousands of keys, continuous sync). Scan and import chunk at 200 rows per transaction and flush spatie's cache once per group — correct and safe, but still an admin-triggered operation, not a pipeline component.

Adoption caveats to plan for (v1.0.0):

  • This is a first release. Pin the version and pilot on one product surface before making it the team's only translation path.
  • Rehearse the binary-keys stub on a staging copy of the real table. It alters an existing table's collation and adds a unique-pair constraint; if duplicate keys already exist, that migration is where you'll find out. The runtime skip-and-count behaviour protects the import, not the migration.
  • Set import.max_size and decide scan.max_key_length deliberately — null (unlimited) is the default and permissive.
  • Define the gates before rollout; if you don't, nothing is manageable and nobody can delete, which reads as "broken" to the first editor who tries.
  • status.enabled lets you ship without the confirmed/orphaned columns at all. That's a useful phased-rollout lever: turn on the resource first, add status once editors are used to the tool.

How to Pitch It (Stakeholders)

To executives: This is the last piece of tooling that stands between us and launching in a new market without an engineer in the loop. Today every copy change is a ticket. With this, editors see exactly which strings are missing for Polish or Turkish, translate them in the admin panel we already run, mark them confirmed, and the strings ship — no deploy, no developer. It adds no SaaS line item and no new vendor; it sits on the translation table we already have. The safety story is deliberately conservative: destructive pruning is off by default, deletes are permission-gated and off until we turn them on, and the scanner is additive — it never overwrites text a human edited, and it never refills a field an editor deliberately cleared. Ask: a two-week pilot on one surface and one locale, with a coverage target we agree up front; we report coverage and orphaned-key counts at the end and decide on full rollout.

To engineering: It's a Filament resource plus an artisan scanner over spatie/laravel-translation-loader, so no new schema to design and no second source of truth. The implementation shows real care about the things that bite: group/key are utf8mb4_bin so the unique index agrees with the scanner's byte comparison (with a stub to fix an existing table); duplicate collisions are skipped and counted rather than fatal; scan and import write in 200-row transactions with the cache flushed once per group via deferringCacheFlush() rather than per row, while model events still fire per row; the language switcher applies the locale after the session starts via the panel's persistent auth middleware instead of in boot(); quick translate locks $recordId and scopes the lookup; imports are size-capped; and the missing-scope queries use JSON paths (text->uk) verified against the MySQL, MariaDB, PostgreSQL and SQLite grammars. The obvious review work is the one-time collation migration on a copy of production — everything else is config. Ask: one engineer-day to pilot it, stage-test the binary-keys migration, and set groups, gates, import.max_size and scan.max_key_length to our conventions. If it holds, it's a config entry in the panel provider and the team stops hand-editing translation rows.

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.
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
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin