Open source
Translatable for Laravel
composer require roundly-consulting/translatable-for-laravelOverview
A native translatable-attributes layer for Eloquent. Each translatable attribute is a plain locale map stored in a single json/jsonb column, and reads resolve the current locale through a configurable fallback chain so content never renders blank. Around it: hardened write paths, a Translatable facade with validation and search helpers for admin forms, translation-status reporting, opt-in change events and per-locale slugs through sluggable-for-laravel. MIT-licensed and built only on Laravel and Roundly’s own packages — zero third-party dependencies.
What you get
One column per attribute
Each translatable attribute is a plain JSON locale map in a single jsonb column — add a locale without a migration.
Fallback chain
None, Fallback or Any — reads fall back to the fallback locale, then to any value, so content never renders blank.
Hardened write path
Locale keys are validated on every write, values must be scalars, and strict mode rejects unsupported locales.
One facade, injectable manager
Locales, fallback resolution, input normalisation, validation rules, PATCH updates and search on one facade — or inject its manager.
Translation status
Missing locales per field, a completeness score for progress bars, a missing-locale scope and a drop-in Blade badge.
Per-locale slugs
sluggable-for-laravel builds a slug per locale from the same locale source of truth — two traits, no cast.
Opt-in change events
One TranslationsChanged event per save — queue an AI fill of missing locales without overriding the model.
Documentation
Installation
Install via Composer and optionally publish the config and validation language lines — there are no migrations to publish.
Configuration
Every config key, its default and env variable — fallback locale, fallback mode, strict locales and the supported-locale source.
Schema and storage
Add jsonb locale-map columns with the translatable() Blueprint macro; values are stored as a plain JSON object with no wrapper.
Translatable models
Add the HasTranslations trait and the Translatable contract, list attributes in $translatable, and optionally override fallback per model.
The Translatable facade
Every locale-map helper on one facade — supported locales, locale checks, fallback resolution, admin input, rules, search and usingLocale().
DI and actions
Inject TranslationManager instead of calling the facade — the same API as an explicit dependency. There are no action classes: it’s pure computation.
Reading and writing
Read the current locale through the fallback chain, target a locale explicitly, and write single values or whole locale maps.
Fallback modes
Choose how far reads fall back — exact locale only, the fallback locale, or any available value — globally or per model.
Input and validation
Hardened write paths, raw input normalised with fromInput(), single-locale checks, locale-map validation rules and PATCH-style updates.
Serialization
toArray(), toJson(), JSON responses and API Resources emit each attribute’s resolved locale value, not the raw map.
Translation status
Missing locales per field, whole-model completeness for progress bars, status exclusions and a drop-in Blade status badge.
Querying and search
Driver-agnostic per-locale scopes, a missing-locale scope for fill queues, and literal, case-insensitive search across locales.
Events
Opt in to one TranslationsChanged event per save — queue an AI fill of missing locales or bust caches without overriding the model.
Per-locale slugs
Per-locale slugs via sluggable-for-laravel — two traits, two interfaces, no cast — sharing the same locale source of truth.
Artisan about
The package’s php artisan about section — locale count and source, fallback mode and switches, never your locale list.
Exceptions
Every package error extends TranslatableException — malformed locale keys, non-scalar values and non-translatable attributes.
Testing
No fake by design — pin locales and fallback via config or a manager swap, assert with plain Pest, run the suite on SQLite, PostgreSQL or MySQL.
Requirements
PHP 8.4+ with ext-json, Laravel 12 or 13 and any Laravel-supported database; three Roundly packages install automatically.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.