lexik/translation-bundle
Symfony bundle to import translation files (xliff, yml, php) into a database, edit and add translations through a GUI, export them back to files, and check that every translation domain is fully translated. It overrides the translator service with a database loader.
This is not a Laravel package — that is the first thing to price in. lexik/translation-bundle is a Symfony bundle: it registers a compiler pass, overrides the translator service with a DatabaseLoader, and ships Doctrine ORM entities plus Twig controllers for the editing grid. In a Laravel codebase none of that is reusable — no service provider, no container override, no Eloquent models. The evaluation below is therefore split into two honest tracks: adopt (only if Symfony is actually in the stack) and mine as a reference design (the realistic Laravel path).
Illuminate\Translation\LoaderInterface implementation reading from a translations table, registered on the translator, plus Artisan import/export commands and a Filament/Nova/Livewire admin screen. This is the defensible path, and the reference design de-risks it.col-* class collision breaking column show/hide). Still points at a dead Travis CI badge. Assume a bus factor of roughly one and plan for internal ownership.Stack fit. Laravel's translator resolves keys through file loaders only; there is no first-class database loader. The port is small and well-bounded: a LoaderInterface implementation, a translation_keys/translations schema (key, locale, domain, value, timestamps), registration via the translator's loader map, and a cache layer in front of it. That is a couple of days to prototype, one to two weeks to productionise with tests and cache invalidation.
Migration path. Mirror the bundle's proven sequence rather than inventing one:
php artisan translations:import).translations:export and wire it into the release checklist so files are regenerated from the DB before each deploy. This is the non-negotiable control that keeps git honest.Compatibility. If you genuinely adopt upstream, you need Symfony 6/7/8, Doctrine ORM, PHP 8.1+, and you'll have to require the UI dependencies yourself (symfony/form, twig-bundle, security-csrf, asset) — that has been true since v6.0. In Laravel, avoid pulling Doctrine in as a second ORM; use Eloquent against the same conceptual schema so the bundle's docs remain a readable blueprint.
Sequencing and effort.
updated_by, updated_at). Do not ship an unauthenticated or role-unaware editor.Maintenance. If adopted as a dependency, you inherit an under-resourced upstream: expect to read source for edge cases, and expect compatibility patches (not features) as the primary release content. If ported to Laravel, you own ~500–1,000 lines plus an admin screen forever — modest, but real, and it lands on whichever team owns the admin panel. Budget a recurring line item either way; this is not a set-and-forget package.
Support. Documentation is thin — an Resources/doc/index.md, a testing.md, and a README. Release notes reveal intent more reliably than the docs do (and even contain inline @todo admissions, e.g. overview-page filter links not applying their query parameters). Plan for self-support, and designate one engineer as the internal subject-matter expert.
Scaling. Every request resolves translations through the application; there is no edge/CDN delivery model. With a warm cache (array or Redis, keyed by locale+domain, invalidated on write) this is a non-issue for most products. Without it, you have added a database round-trip to the hot path of every page render. Treat "cache is warmed on deploy and invalidated on edit" as a launch gate, not a follow-up. Multi-region or headless consumers are out of scope for this design.
Failure modes to design against explicitly.
messages.welcome strings in the UI.Ramp-up. Two distinct audiences. Engineers need modest familiarity with Laravel's translator internals (a half-day; it is a small, well-documented surface) plus the import/export runbook. Content editors need a short walkthrough of the grid, the coverage report, and the save-to-export-to-deploy lag — the last one matters most, because the predictable complaint is "I changed it and the site still shows the old text." Publishing expectations up front costs an hour; not doing so costs a month of Slack threads.
Bottom line for the roadmap: use this package to make the files-vs-database decision cheaply and reversibly, not as production infrastructure in a Laravel app. The strategic win is reframing localization as a content-ops responsibility with measurable coverage; the bundle is the reference implementation of that idea, not a dependency you should install.
How can I help you explore Laravel packages today?