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

Translatable Laravel Package

marshmallow/translatable

A Laravel package for adding translations to Eloquent models. Use a trait to mark translatable attributes, store per-locale values, and retrieve localized content with fallback support, keeping multilingual model data simple and integrated with Laravel.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package takes a relational, polymorphic translation store approach: translations live in a dedicated translatables table keyed by translatable_type, translatable_id, and locale, rather than as JSON columns on the parent table. This is the classic EAV-lite trade-off — it normalizes locale data, keeps content tables narrow, allows per-locale indexing, and lets each translated field be queried independently, at the cost of joins on every localized read.
  • Fit is best for editorial/admin-managed content in Laravel Nova: a handful of locales, human-authored copy, moderate read volume. It is a poor fit for high-QPS public read paths without a caching layer in front of it, or for content that needs full-text search across locales.
  • It is tightly coupled to Laravel Nova by design (resource fields), which is itself a paid, separately-versioned product. That coupling — not the database model — is the dominant architectural constraint.

Integration feasibility

  • Low friction on paper: composer require, publish migration, apply a trait to models, add a Nova field to resources. No service providers to wire manually beyond discovery, no external services, MIT license means no procurement cycle.
  • Real blockers are elsewhere: verifying a version compatibility matrix across Laravel, PHP, and Nova; confirming the migration is publishable and re-runnable; confirming the trait composes with existing casts, accessors, and any current translation approach (e.g., Spatie Translatable or hand-rolled JSON columns).
  • Backfilling existing JSON translations into the new table is custom work not provided by the package — budget a one-off migration script and a dual-write/shadow-read period if content already exists.

Technical risk

  • Sustainability is the headline risk. 2 stars, 0 dependents, a single-maintainer footprint, and a low composite score (5.44) mean effectively zero community validation. There is no evidence of production usage at scale, no downstream packages to surface regressions, and a non-trivial chance of abandonment.
  • Nova version churn is a recurring breaking-change source; a lagging package can pin the whole admin panel to an older Nova major.
  • Schema/query risk: polymorphic foreign keys cannot be enforced by the database, so orphaned translation rows are possible; without a unique index on (translatable_type, translatable_id, locale, key) duplicates will silently accumulate.
  • Behavioral unknowns: fallback-locale semantics, null vs. empty-string handling, eager-loading support (N+1 protection), and whether translated attributes can be sorted/filtered in Nova index views all need explicit verification.
  • Mitigant: MIT license means we can fork and vendor the package if upstream stalls — acceptable only if we accept ownership of that fork.

Key questions

  1. Which exact Laravel / PHP / Nova versions are supported, and is there a CI matrix proving it?
  2. Is there test coverage, and does it cover Nova resource rendering or only Eloquent behavior?
  3. How are missing translations and fallback locales resolved — per-field, per-locale, global?
  4. Does the trait support eager loading and does the Nova index avoid N+1 per row?
  5. Are uniqueness constraints and indexes included in the published migration?
  6. Can translated fields be filtered/sorted in Nova index views, and at what query cost?
  7. Is the package usable outside Nova (API serialization, model-level accessors), or is it admin-only?
  8. What is the maintainer's stated support commitment and release cadence?

Integration Approach

Stack fit

  • Target: Laravel + Nova monolith or modular monolith, MySQL/Postgres, admin-driven content, small locale set (2–10). Strong fit there.
  • Anti-fit: headless/API-first products, content published to CDN, or any surface needing locale-aware search/sort at scale. In those cases the EAV join cost and lack of built-in caching make a JSON-column or per-locale-column design preferable.

Migration path

  1. Spike (2–3 days): install in a throwaway branch, apply the trait to one low-risk model, exercise create/edit/read in Nova across two locales, and measure the query profile of a Nova index page.
  2. Schema: publish and review the migration; add the composite unique index and covering indexes on (translatable_type, translatable_id, locale) before any data lands.
  3. Backfill: write a one-off artisan command to transform existing JSON/column data into rows; run it against a production snapshot and diff outputs.
  4. Dual-write / shadow-read: keep the old columns authoritative, write both stores, and read from the new store in a non-production environment to validate parity.
  5. Cutover and cleanup: flip reads, monitor for one release cycle, then drop the legacy columns.

Compatibility

  • Pin the package to an exact version in composer.json; do not float the constraint. Add a CI job that runs the test suite against the pinned Nova/Laravel combination so an upstream bump is caught at PR time rather than at deploy.
  • Treat the Nova major version as the gating dependency: upgrade Nova first on a branch, confirm the package is compatible, and only then merge.

Sequencing

  • Land the migration and trait on one model behind a feature flag → validate in staging with real locale data → expand to remaining models by content criticality → retire legacy translation columns last. Keep the feature flag until at least one full release has shipped clean.

Operational Impact

Maintenance

  • Expect to own this. With one maintainer and no dependents, the realistic posture is "vendor-with-intent-to-fork": mirror the repo internally, track upstream, and budget a few days per year for patching, largely driven by Nova upgrades rather than by the package itself.
  • Code surface is small (a trait, a model/relation, Nova fields, one migration), so fork cost is low — that is the package's main redeeming operational quality.

Support

  • No SLA, no commercial backing, community-only issue tracker. Internal support must come from the team that adopts it; nominate an owner before adoption rather than after.

Scaling

  • Read cost grows with locales and translated fields: each localized fetch is a join, and a Nova index listing translated columns risks one query per row plus per-field resolution. Mandatory mitigations: eager-load the relation, cache rendered translations in Redis keyed by model/locale/version, and invalidate on model save.
  • Write cost is one row per field per locale — fine at editorial volume, noisy if translations are machine-generated in bulk.
  • Unbounded growth of translatables means it should be included in data-retention and vacuum/optimize routines from day one.

Failure modes

  • Orphaned rows after model deletion (polymorphic FK not enforceable) → add a model deleting observer or a scheduled cleanup command.
  • Duplicate translations if the unique index is omitted → silent last-write-wins in Nova, hard to diagnose.
  • Silent fallback gaps: missing locale renders blank or falls back unexpectedly, which content editors read as a bug.
  • Upstream abandonment coinciding with a Nova major release → admin panel frozen on an unsupported version.
  • Cache staleness once caching is introduced → translations appear correct in Nova but stale on the public site.
  • Migration rollback leaving half-populated tables → ensure the backfill command is idempotent and re-runnable.

Ramp-up

  • Developer ramp-up is genuinely light: any engineer fluent in Eloquent relations and Nova fields is productive in half a day; the trait/field API is conventional.
  • Content-editor ramp-up is the larger cost — locale switching, fallback visibility, and publish-state semantics need documentation and, ideally, a short Loom plus a sandbox resource before rollout.
  • Recommend a written internal runbook covering: adding a translated field, adding a locale, running the backfill, and invalidating the translation cache. That runbook, not the package docs, becomes the real onboarding artifact.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin