outl1ne/nova-translatable
Adds translatable fields to Laravel Nova. Wrap any Nova field with the Translatable class to edit and store values per locale, with locale switching in forms and support for spatie/laravel-translatable models. Simple setup for multilingual admin panels.
Verdict: A narrow, low-risk-to-try but non-trivial-to-own dependency. It remains the de facto community answer for translatable Nova fields, but it sits on a closed-source host (Nova) and a single-maintainer release cadence, so the real cost is upgrade tax, not integration effort. Release 3.1.0 is additive — native Nova Repeatable field support plus build-tooling modernisation — and does not change the verdict, but it does modestly widen the scope of "any input field" and provides the first third-party contribution signal we've seen.
Architecture fit
spatie/laravel-translatable (JSON column per attribute). It does not introduce a new translation store, service layer, or API surface — the domain model stays yours.spatie/laravel-translatable, which most multilingual Laravel apps already run. The Node 24 change is dev-tooling only (asset build) and introduces no runtime dependency.Integration feasibility
composer require, optionally publish config (locale list, default locale, fallback behaviour), then wrap fields. Effort for a pilot resource is measured in hours, not days.nova-repeatable-style package; the release note says "native Nova Repeatable," which is a narrower claim than "any repeatable field package."resolveUsing/fillUsing, and per-locale validation rules (rules must be expressed per locale key, and error messages are attributed to the nested key, which editors find confusing). Repeatable-inside-translatable adds a fourth nesting dimension — validate this explicitly rather than assuming the new support is fully orthogonal to the existing edge cases.Technical risk
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Nova major upgrade breaks field macros/metacomponents before the package catches up | Medium-High | Blocks admin upgrades | Pin Nova; budget a fork-and-patch sprint per major |
| Maintainer abandonment (bus factor 1, low commit volume) | Medium (slightly reduced by 3.1.0 external contribution) | No fixes for new Nova/PHP | MIT licence — pre-approve internal fork rights |
| JSON storage limits querying/sorting/filtering on translated values | High (by design) | Editors lose index filters/sorts on translated columns | Accept; add dedicated search columns if needed |
| Silent fallback masks missing translations | Medium | Ships untranslated copy to production | Add a missing-translation audit/report |
| Locale switcher state loss → edits written to wrong locale | Low-Medium | Content corruption, hard to detect | Train editors; spot-check diffs |
| Repeatable-in-translatable path is new and thinly exercised | Medium | Edge-case breakage in block-style content; harder to isolate from our own config | Spike Repeatable specifically before rollout; treat as the highest-value verification target |
Technical risk headline: none of these are architectural showstoppers; all are operational. The one that should influence the decision is still the Nova-upgrade coupling, because Nova is a paid, closed-source dependency on its own release cadence and this package must chase it. 3.1.0 slightly increases surface area (Repeatable) while slightly decreasing abandonment risk (external contributor) — net neutral on the decision, but it moves Repeatable from "rebuild it ourselves" to "verify it works."
Key questions to resolve before commitment
spatie/laravel-translatable already in the stack, and at which major? Version skew here is the most common install failure.Stack fit
spatie/laravel-translatable on the model. If the existing models already use the HasTranslations trait and JSON columns, fit is near-perfect; if translations currently live in a separate translations table or in per-locale columns, this package is the wrong shape and the migration becomes the project.optimistdigital/ namespace. Confirm which namespace your Nova version expects before adding the constraint.Migration path
VARCHAR column to JSON requires rewriting existing rows into {"en": "…"} form and updating any raw SQL, reporting queries, or exports that read the column as a string.app.locale varies. Freeze the API's locale selection explicitly rather than inheriting request locale.Compatibility
composer.json and record the tested matrix in the repo. Because Nova is closed-source, CI cannot prove compatibility; only staging can.Sequencing
Maintenance
Support
Scaling
Failure modes
Ramp-up
How can I help you explore Laravel packages today?