kongulov/nova-tab-translatable
A Laravel Nova package that groups translatable fields into locale tabs, making multilingual resource forms cleaner and easier to edit. It keeps each language’s inputs neatly separated for faster, less cluttered translation work.
Architecture fit. This is a presentation-layer wrapper inside Laravel Nova's field system, not a translation engine. It regroups translatable attributes into one tab per locale across Nova's create/update/detail forms, replacing the stacked column of duplicated per-locale inputs. Routing, persistence, validation rules, queues, and domain logic are untouched — the data contract is unchanged. Fit is gated on two preconditions that must already be true: we run Nova for the admin surface, and localized content is persisted in a shape the package can read (typically spatie/laravel-translatable JSON columns). If both hold, blast radius is a handful of fields() methods plus the lockfile. If either fails, the package is irrelevant and evaluation ends there. That profile — real editor benefit, zero data-model commitment, one-line rollback — is exactly the kind of dependency a TPM should be comfortable scoping cheaply rather than routing through a full architecture review.
Integration feasibility. Mechanically trivial: a Composer require, then wrapping an existing field array in a translatable-tabs construct within one resource. No migration, no scheduled job, no public request path, and in the common case no publish or asset-build step. Realistic pilot effort is half a day to a day for a developer who knows Nova. The unknowns are administrative rather than architectural: declared Nova/Laravel/PHP constraint ranges, whether Vue assets ship pre-compiled or drag an npm build into our pipeline, and whether the package hard-pins a translatable-field dependency that conflicts with our current one.
Technical risk. Risk is dominated by supply chain and version coupling, not code complexity:
composer.json. Any compatibility claim derived from that metadata is unsubstantiated.config/app.php locales, the model's $translatable array, and what the package renders as tabs is the most likely source of confusing "wrong tabs" reports.Key questions.
spatie/laravel-translatable, or does it tolerate Nova's native translatable fields and plain JSON columns?Stack fit. Best fit is a Laravel + Nova admin backed by spatie/laravel-translatable JSON columns or a translations table, with a fixed, config-driven locale set — typically marketing/CMS-style resources carrying 2–5 locales where non-technical editors author copy. Adoption is additive: existing field definitions are wrapped and grouped, not replaced. Value scales with locales × translatable fields per resource, so two locales and three fields is not worth the dependency, while five locales across a content-heavy resource (title, body, excerpt, SEO meta, slug, hero copy) is a genuine usability change. It is a poor fit for teams without Nova, teams with one locale and no i18n roadmap, and teams whose real bottleneck is the translation workflow (TMS sync, translator handoff, review cycles) rather than in-admin authoring friction. Drawing that line early is the TPM's highest-value contribution — it is the difference between a productivity win and a distracted sprint, and confusing authoring ergonomics with translation pipeline is the primary way a sprint gets burned here.
Migration path. There is no data migration. Changes are confined to Nova resource fields() methods, and rollback is a file revert plus a Composer removal. That combination — no schema change, trivial reversal — is precisely why a timeboxed single-resource pilot is the correct decision vehicle. The one design constraint worth imposing up front: do not call the package directly from every resource. Wrap it in our own field class or trait so that if the maintainer goes quiet or Nova's next major breaks it, the swap is one file rather than archaeology across every resource. Make that "pin exactly, wrap once, own the tail" posture an explicit gating decision before the item lands on a roadmap, not after a Nova upgrade breaks the admin.
Compatibility. Pin to an exact version and validate its Nova constraint against the installed Nova before merging. Confirm the PHP/Laravel matrix, verify asset-publishing requirements, and test in a staging Nova instance with production-like locale configuration. Confirm whether the package needs spatie/laravel-translatable present or merely tolerates it, and reconcile the declared locale set against both the app config and each model's $translatable array before pilot. Treat the future-dated release marker as unverified until cross-checked against repository tags.
Sequencing. Inventory first: enumerate Nova resources, their translatable fields, locale counts, and editor population, and rank by locales × fields. Then a single low-traffic resource pilot with create, edit, validation-error-in-inactive-tab, and missing-translation paths explicitly exercised. Then a Nova-upgrade dry run to size the maintenance tail before widening scope. Only after those three gates pass does resource-by-resource rollout begin, behind our own wrapper class.
Maintenance. The durable cost is not adoption — it is the implicit commitment to track Nova releases for a package with 84 stars, zero dependents, and one maintainer. Every Nova major becomes a scheduled re-validation event, and someone must own it. Mitigate by pinning an exact version, isolating the dependency behind a single wrapper, and treating the ~200-line fork contingency as realistic rather than theoretical. At this code size, absorbing it in-house is a credible exit and should be priced into the decision up front.
Support. No vendor SLA, no security disclosure process, no verified compatibility matrix across Nova majors, and no community to lean on for edge cases. Internal support is therefore entirely ours: first-line triage lands on our developers, and content-owner questions ("the Serbian tab is missing," "it saved but the field was blank") route back through us. That should be stated plainly to stakeholders rather than discovered in the first incident.
Scaling. Runtime cost is effectively zero — it renders admin forms only and touches no customer-facing request path. Scaling concern is organizational instead: as resources and locales are added, the wrapper surface grows, and any per-resource divergence in how the tabs are declared becomes drift. Standardize on the wrapper class early so growth is mechanical. Non-technical editor populations scale well on this; a growing locale count is where the ergonomic payoff compounds.
Failure modes. Three to watch, in descending order of business impact: (1) silent save of invalid or incomplete localized content because validation errors live in an inactive tab — a data-quality failure, not a crash, and the one to instrument during pilot; (2) breakage on Nova upgrade, which takes the admin editing experience with it; (3) locale-drift rendering, where tabs shown do not match the configured or model-declared locale set, producing "wrong tabs" reports that look like bugs but are configuration. Secondary: unpinned version resolution pulling an incompatible release, and any asset-build assumption that fails in the deploy pipeline.
Ramp-up. Developer ramp-up is minimal — hours for anyone fluent in Nova fields, since the change is confined to fields() methods. Editor ramp-up is a one-click-per-language mental model and needs a short note only, with honest disclosure that validation messages can hide in a tab you are not looking at. The real ramp-up obligation sits with whoever owns the Nova-upgrade tail; assign that owner before rollout, not after. Attach cheap pilot metrics — time-to-publish a localized record, count of secondary-locale fields left empty at save, editor-reported friction — so the go/no-go is defensible rather than subjective, and so the worst-case outcome of the spike remains a half-day spent.
How can I help you explore Laravel packages today?