Stop Duplicating Translations Across Projects
How many times have you translated "Save" to Spanish?
If you have 5 Laravel projects, probably 5 times. Same work, repeated. Same story for "Cancel", "Delete", "Loading...", and every validation message your apps share.
The Global Translations Library changes that. Define your common strings once, at the account level, and every project you own inherits them.
The Problem in a Real Laravel App
If you maintain more than one Laravel codebase, you've probably written this file more than once:
// project-a/lang/es/common.php
return [
'buttons' => [
'save' => 'Guardar',
'cancel' => 'Cancelar',
'delete' => 'Eliminar',
'edit' => 'Editar',
'close' => 'Cerrar',
],
'messages' => [
'success' => 'Éxito',
'error' => 'Se ha producido un error',
'loading' => 'Cargando...',
],
];
Then you wrote it again in project B. And project C. Each copy starts identical and drifts from there. Someone shortens the error message in one repo. Someone else translates "Delete" as "Borrar" instead of "Eliminar" in another. A new French translator picks different phrasing for the same button. Now your products disagree with each other in four languages, and nobody notices because the strings live in five separate git repositories.
The math gets ugly fast:
- 5 projects × 50 common strings × 10 languages = 2,500 translations to create and keep in sync. By hand.
With a shared library, it's 50 strings × 10 languages = 500 translations, once. Every project inherits them. That's 80% less work, and it stays consistent because there's a single source of truth.
How the Global Scope Works
In LangSyncer, every translation lives in one of two scopes: Project (visible to one project only) or Global (shared across all projects in your account). The translations documentation covers the full model, but the short version is that a global translation behaves exactly like a project one — same groups, same keys, same draft-and-publish workflow — it's just visible everywhere.
A global entry looks like this:
Group: common
Key: buttons.save
EN: Save
ES: Guardar
FR: Enregistrer
And if you export the common group as JSON, you can see exactly what all your projects share:
{
"common.buttons.save": {
"en": "Save",
"es": "Guardar",
"fr": "Enregistrer"
},
"common.buttons.cancel": {
"en": "Cancel",
"es": "Cancelar",
"fr": "Annuler"
},
"common.messages.loading": {
"en": "Loading...",
"es": "Cargando...",
"fr": "Chargement..."
}
}
One file. One truth. Every app reads from it.
Build Your Library, Step by Step
-
Switch to Global scope. On the translations page, flip the scope from your project to Global. Everything you create here is account-wide.
-
Create a
commongroup. Add the strings that appear in every app: buttons (buttons.save,buttons.cancel), status messages (messages.success,messages.error), navigation labels (nav.home,nav.settings,nav.logout). Use lowercase dot notation, same as you would in a Laravel lang file. -
Let AI fill in the languages. Enter the English value, click AI Autofill, and every empty language field gets translated. Each target language consumes 1 unit of your AI quota, and placeholders like
{name}and:countare preserved automatically. Review the output, adjust where needed. -
Publish. Global translations follow the same versioning workflow as everything else: saves create drafts, and drafts are invisible to your applications until you hit Publish. Add a release note like "Initial common UI library" so future you knows what shipped.
-
Use them in your Laravel apps. Nothing changes in your Blade templates. The keys resolve like any other translation:
<button type="submit">{{ __('common.buttons.save') }}</button>
<a href="{{ route('dashboard') }}">{{ __('common.buttons.cancel') }}</a>
- Promote what you already have. You don't need to retype existing strings. In any project, select translations with the checkboxes and use Bulk Actions > Promote to Global. Conflicting keys (same group and key already global) are skipped by default, or you can resolve them manually.
Override When a Project Needs Different Wording
Shared doesn't mean rigid. Say the global library has common.submit = "Submit", but your job-board project needs "Send Application" on that button.
- Go to the Global scope and select the translation
- Click Actions > Copy to Project and pick the target project
- Edit the value in the project, save, and publish
The project's copy takes precedence over the global value — for that project only. Every other project keeps using "Submit". And if you later delete the project override, the key falls back to the global value automatically. No dead keys, no missing strings.
When Not to Use the Global Library
Honest limits, because not everything belongs in a shared scope:
- You have one project. The global scope adds a layer of indirection with no payoff. Keep everything project-scoped until a second app actually exists.
- Brand-voice strings. Marketing copy, onboarding text, and anything with personality usually should differ between products. Sharing "Save" is a win; sharing your hero headline is a bug.
- Diverging terminology. If product A calls it a "workspace" and product B calls it a "team", strings referencing that concept can't be shared without constant overrides. Once a global key has overrides in most projects, it isn't really common — move it back to project scope.
The indirection is the real cost: a teammate editing translations needs to know whether a string is defined globally or locally. Keep the global library small and genuinely universal, and that cost stays near zero.
Gotchas
- Global translations are drafts until you publish in the Global scope. Creating them isn't enough — projects won't see anything until you hit Publish there.
- Promote to Global skips existing keys by default. If a global key with the same group and key already exists, your project value won't overwrite it unless you uncheck "Skip if translation already exists" and resolve the conflict manually.
- Deleting an override silently reverts to the global value. That's the designed fallback, but it can surprise you if you forgot a global version existed — check the Global scope before deleting project keys.
If you're weighing all this against keeping strings in per-repo lang files, the LangSyncer vs Laravel lang files comparison walks through the trade-offs in more detail.
Every global translation you create removes duplicate work across your entire organization. What starts as a convenience compounds into infrastructure.