brunoscode/laravel-translation-handler

This is my package laravel-translation-handler

Maintainers

Package info

github.com/BrunosCode/LaravelTranslationHandler

Homepage

pkg:composer/brunoscode/laravel-translation-handler

Fund package maintenance!

BrunosCode

Statistics

Installs: 2 256

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 1

v2.2.0 2026-05-10 14:21 UTC

README

Manage translations in Laravel across PHP files, JSON files, CSV files, and database — and let an AI agent handle them for you via Laravel Boost MCP tools.

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Requirements

Laravel PHP
12.x 8.2, 8.3, 8.4
11.x 8.2, 8.3, 8.4

Supported Formats

Format Constant Description
php_file TranslationOptions::PHP Standard Laravel PHP translation files
json_file TranslationOptions::JSON JSON translation files
csv_file TranslationOptions::CSV CSV translation files
db TranslationOptions::DB Database-backed translations

Installation

composer require brunoscode/laravel-translation-handler

Publish the configuration file:

php artisan vendor:publish --provider="BrunosCode\TranslationHandler\TranslationHandlerServiceProvider"

AI-Powered Translation Management with Laravel Boost

When Laravel Boost is installed, this package automatically registers 11 MCP tools into Boost's MCP server. This lets any MCP-compatible AI agent (Claude, Cursor, GitHub Copilot, etc.) read and write your translations directly — no manual commands, no copy-pasting.

What the AI can do

  • Browse your translation keys by group and depth level
  • Look up a specific key in any locale
  • Add or update a single translation in any format
  • Add or update a key across all locales at once
  • Translate an entire group in one call (every subkey, every locale)
  • Sync translations between storage formats
  • Delete a single key (optionally for a specific locale only)
  • Delete all keys under a group prefix
  • Sort keys alphabetically in PHP, JSON, and CSV formats
  • Read the full translation configuration

Setup

Install Laravel Boost, then connect your AI assistant to its MCP server. No further configuration is required — the tools register automatically on package detection.

composer require laravel/boost

Available MCP Tools

Format values for format / from / to parameters: php_file, json_file, csv_file, db.

get-translation-config-tool (read-only)

Returns the active configuration: locales, file names, key delimiter, default formats, and storage paths. Useful as a first call to understand the project's translation setup.

No parameters.

list-translations-tool (read-only)

Lists translations from a format with optional filters.

Parameter Type Required Description
format string yes Storage format to read from
locale string no Filter by locale (e.g. en)
group string no Filter by key prefix (e.g. auth returns all auth.* keys)

list-translation-groups-tool (read-only)

Lists unique key groups at a given depth. Use this to explore the key hierarchy before reading or writing translations — especially useful in large projects.

Parameter Type Required Description
format string yes Storage format to read from
level integer no Number of delimiters in the group name. 0 = top-level (e.g. auth), 1 = second-level (e.g. auth.messages). Defaults to 0.
search string no Case-insensitive filter on group names

find-translation-tool (read-only)

Finds a specific translation by key and locale.

Parameter Type Required Description
format string yes Storage format to read from
key string yes Dot-delimited key (e.g. auth.welcome)
locale string yes Locale to look up

set-translation-tool (write)

Sets or updates a single translation value.

Parameter Type Required Description
format string yes Storage format to write to
key string yes Dot-delimited key
locale string yes Target locale
value string yes Translation value
force boolean no Overwrite existing value (default false)

set-all-locales-translation-tool (write)

Sets or updates a translation key for all locales at once. Ideal when the AI generates translations for every supported language in a single step.

Parameter Type Required Description
format string yes Storage format to write to
key string yes Dot-delimited key
values object yes Map of locale → value, e.g. {"en": "Hello", "it": "Ciao"}
force boolean no Overwrite existing values (default false)

set-translation-group-tool (write)

Translates an entire group in a single call. The AI provides a group prefix and an object of subkey → {locale: value}; the tool joins each subkey to the group and writes all locales for all subkeys in one DB transaction.

Parameter Type Required Description
format string yes Storage format to write to
group string yes Group prefix (e.g. auth). Trailing delimiter is tolerated.
translations object yes Map of subkey → locale=>value, e.g. {"welcome": {"en": "Welcome", "it": "Benvenuto"}, "logout": {"en": "Logout", "it": "Esci"}}. Subkeys may contain the delimiter (nested.deep).
force boolean no Overwrite existing values (default false)

sync-translations-tool (write)

Copies translations from one storage format to another.

Parameter Type Required Description
from string yes Source format
to string yes Destination format (must differ from from)
force boolean no Overwrite existing translations in destination (default false)

delete-translation-tool (write)

Deletes a translation key from a storage format. Omit locale to delete the key for all locales.

Parameter Type Required Description
format string yes Storage format to delete from
key string yes Dot-delimited key to delete (e.g. auth.welcome)
locale string no Delete only this locale. Omit to delete all locales for the key.

delete-translation-group-tool (write)

Deletes all translation keys under a group prefix from a storage format.

Parameter Type Required Description
format string yes Storage format to delete from
group string yes Key group prefix to delete (e.g. auth removes all auth.* keys)

sort-translations-tool (write)

Sorts translation keys alphabetically within a storage format. Supports php_file, json_file, and csv_file only.

Parameter Type Required Description
format string yes Storage format to sort (php_file, json_file, or csv_file)
locales array no Restrict sorting to these locales. Omit to sort all locales.
groups array no Restrict sorting to these key group prefixes. Omit to sort all groups.

Recommended workflow for editing translations

Use db as the working format for all writes, then sync to files at the end.

File-based formats (PHP, JSON, CSV) rewrite the entire file on every write operation. The database format writes only the affected rows, making each change significantly faster. Once all edits are done, a single sync pushes everything to the target file format.

1. Read/browse   → db (or any format for read-only queries)
2. Write keys    → always db
3. Finalise      → sync-translations-tool  from: db  to: <target format>

When no database is configured, write directly to the file format but batch all locales for a key into a single set-all-locales-translation-tool call rather than one call per locale.

Example AI workflow

You: "Add a auth.too_many_attempts key in English and Italian to the JSON files."

The AI will:

  1. Call get-translation-config-tool to confirm the locales and format
  2. Call set-all-locales-translation-tool with {"en": "Too many attempts. Please try again later.", "it": "Troppi tentativi. Riprova più tardi."} targeting json_file

You: "Translate the entire auth group into English, Italian, and Spanish."

The AI will call set-translation-group-tool with format: db, group: auth, and a translations object containing every auth subkey mapped to all three locales — written in a single DB transaction.

You: "Migrate all translations from PHP files to the database."

The AI will call sync-translations-tool with from: php_file, to: db.

You: "What translation groups exist at the top level?"

The AI will call list-translation-groups-tool with format: php_file, level: 0.

Quick Start

# Sync translations between formats
php artisan translation-handler:sync php_file json_file

# Import / export using config defaults
php artisan translation-handler:import
php artisan translation-handler:export --force

# List all translations from PHP files
php artisan translation-handler:list php_file

# List translations filtered by locale and group
php artisan translation-handler:list php_file --locale=en --group=auth

# List top-level key groups
php artisan translation-handler:list-groups php_file

# List second-level groups, filtered by search
php artisan translation-handler:list-groups php_file --level=1 --search=messages

# Find a specific translation
php artisan translation-handler:find php_file auth.welcome en

# Get the raw value of a translation
php artisan translation-handler:get php_file auth.welcome en

# Set a specific translation
php artisan translation-handler:set php_file auth.welcome en "Welcome!"

# Delete a translation key (all locales)
php artisan translation-handler:delete php_file auth.welcome

# Delete a translation key for a specific locale
php artisan translation-handler:delete php_file auth.welcome --locale=en

# Delete all keys under a group
php artisan translation-handler:delete-group php_file auth

# Sort all keys alphabetically
php artisan translation-handler:sort php_file

# Sort only specific locales and groups
php artisan translation-handler:sort php_file --locale=en --group=auth

Or use the Facade:

use BrunosCode\TranslationHandler\Facades\TranslationHandler;
use BrunosCode\TranslationHandler\Data\TranslationOptions;

// Copy PHP → JSON (explicit formats)
TranslationHandler::sync(TranslationOptions::PHP, TranslationOptions::JSON);

// Copy JSON → PHP, overwriting existing
TranslationHandler::sync(TranslationOptions::JSON, TranslationOptions::PHP, force: true);

// Import using config defaults
TranslationHandler::import();

// Export using config defaults
TranslationHandler::export();

Commands

Shared Options

These options are available on translation-handler, translation-handler:import, and translation-handler:export:

Option Type Default Description
--force bool false Overwrite existing translations
--fresh bool false Delete existing translations before writing
--file-names array config fileNames Translation file names to process
--locales array config locales Locales to process
--from-path string format default Custom source path
--to-path string format default Custom destination path
--guided bool false Interactive mode, prompts for each option

translation-handler:sync

Sync translations from one format to another. Source and destination are positional arguments.

php artisan translation-handler:sync {from?} {to?} [options]

If from or to are omitted, you will be prompted to choose.

translation-handler (deprecated)

Deprecated. Use translation-handler:sync instead.

php artisan translation-handler {from?} {to?} [options]

translation-handler:import

Import translations. Source and destination are passed via --from and --to options, defaulting to config values (defaultImportFrom, defaultImportTo).

php artisan translation-handler:import [options]

translation-handler:export

Export translations. Source and destination are passed via --from and --to options, defaulting to config values (defaultExportFrom, defaultExportTo).

php artisan translation-handler:export [options]

translation-handler:list

List translations from a storage format. Optionally filter by locale or key group prefix.

php artisan translation-handler:list {from?} {--from-path=} {--locale=} {--group=}
Option Description
--locale Filter by locale (e.g. en)
--group Filter by key group prefix (e.g. auth returns all auth.* keys)

translation-handler:list-groups

List unique translation key groups from a storage format. A group is a key prefix at a given depth level. Optionally filter by search string.

php artisan translation-handler:list-groups {from?} {--from-path=} {--level=0} {--search=}
Option Description
--level Number of delimiters in the group name. 0 = top-level (e.g. auth), 1 = second-level (e.g. auth.messages). Defaults to 0.
--search Case-insensitive filter on group names

translation-handler:find

Find a specific translation by key and locale. Outputs a table with format, key, locale, and value.

php artisan translation-handler:find {from?} {key?} {locale?} {--from-path=}

translation-handler:get

Get the raw value of a single translation.

php artisan translation-handler:get {from?} {key?} {locale?} {--from-path=}

translation-handler:set

Set a single translation value.

php artisan translation-handler:set {to?} {key?} {locale?} {value?} {--to-path=} {--force}

translation-handler:delete

Delete a translation key from a storage format. Omit --locale to delete all locales for the key.

php artisan translation-handler:delete {from?} {key?} {--locale=} {--from-path=}

translation-handler:delete-group

Delete all translation keys under a group prefix from a storage format.

php artisan translation-handler:delete-group {from?} {group?} {--from-path=}

translation-handler:sort

Sort translation keys alphabetically. Works on php_file, json_file, and csv_file only.

php artisan translation-handler:sort {from?} {--from-path=} {--locale=*} {--group=*}
Option Description
--locale Restrict sorting to this locale (repeatable: --locale=en --locale=it)
--group Restrict sorting to this key group prefix (repeatable)

Facade API

use BrunosCode\TranslationHandler\Facades\TranslationHandler;

sync

Copies translations from one format to another. Unlike import/export, from and to are required — no config defaults are used.

TranslationHandler::sync(
    from: string,      // source format
    to: string,        // destination format
    force: bool,       // overwrite existing (default: false)
    fromPath: ?string, // custom source path (default: null)
    toPath: ?string,   // custom destination path (default: null)
): bool;

import / export

Both methods share the same signature. from and to fall back to config defaults (defaultImportFrom/defaultImportTo and defaultExportFrom/defaultExportTo) when omitted.

TranslationHandler::import(
    from: ?string,     // source format (default: config value)
    to: ?string,       // destination format (default: config value)
    force: bool,       // overwrite existing (default: false)
    fromPath: ?string, // custom source path (default: null)
    toPath: ?string,   // custom destination path (default: null)
): bool;

TranslationHandler::export(/* same signature */): bool;

find

Finds a single translation by key and locale. Returns null if not found.

$translation = TranslationHandler::find(
    from: string,      // source format
    key: string,       // dot-delimited key
    locale: string,    // locale to look up
    path: ?string,     // custom path (default: null)
): ?Translation;

listTranslations

Returns a filtered TranslationCollection. Applies locale and/or group prefix filters on top of get().

$translations = TranslationHandler::listTranslations(
    from: string,      // source format
    path: ?string,     // custom path (default: null)
    locale: ?string,   // filter by locale (default: null = all)
    group: ?string,    // filter by key group prefix (default: null = all)
): TranslationCollection;

listGroups

Returns a sorted Collection of unique key group names at a given depth level.

$groups = TranslationHandler::listGroups(
    from: string,      // source format
    path: ?string,     // custom path (default: null)
    level: int,        // 0 = top-level groups, 1 = second-level, … (default: 0)
    search: ?string,   // case-insensitive filter on group names (default: null)
): Collection;

get

$translations = TranslationHandler::get(
    from: string,      // source format
    path: ?string,     // custom path (default: null)
): TranslationCollection;

set

$count = TranslationHandler::set(
    translations: TranslationCollection,
    to: string,        // destination format
    path: ?string,     // custom path (default: null)
    force: bool,       // overwrite existing (default: false)
): int;

Example:

use BrunosCode\TranslationHandler\Collections\TranslationCollection;
use BrunosCode\TranslationHandler\Data\Translation;
use BrunosCode\TranslationHandler\Data\TranslationOptions;

$translation = new Translation('welcome', 'en', 'Welcome!');
$collection = new TranslationCollection([$translation]);

TranslationHandler::set($collection, TranslationOptions::JSON);

deleteKey

Deletes a specific translation key from a format. Pass locale to target a single locale; omit to delete all locales.

$count = TranslationHandler::deleteKey(
    from: string,      // format to delete from
    key: string,       // dot-delimited key
    locale: ?string,   // locale to delete (default: null = all locales)
    path: ?string,     // custom path (default: null)
): int;

deleteGroup

Deletes all keys whose name starts with the given group prefix.

$count = TranslationHandler::deleteGroup(
    from: string,      // format to delete from
    group: string,     // group prefix (e.g. "auth" removes all "auth.*" keys)
    path: ?string,     // custom path (default: null)
): int;

sortKeys

Sorts translation keys alphabetically within a format. Supports php_file, json_file, and csv_file. Optionally restrict by locale and/or group.

$count = TranslationHandler::sortKeys(
    from: string,      // format to sort (php_file, json_file, csv_file)
    locales: array,    // restrict to these locales (default: [] = all)
    groups: array,     // restrict to these group prefixes (default: [] = all)
    path: ?string,     // custom path (default: null)
): int;

delete

$count = TranslationHandler::delete(
    from: string,      // format to delete from
    path: ?string,     // custom path (default: null)
): int;

Options Management

// Get/set individual options
TranslationHandler::setOption('keyDelimiter', '_');
$value = TranslationHandler::getOption('keyDelimiter');

// Replace all options
TranslationHandler::setOptions(new TranslationOptions([...]));

// Reset to defaults
TranslationHandler::resetOptions();

Configuration

The config/translation-handler.php file contains:

General

Option Default Description
keyDelimiter . Delimiter used in translation keys
fileNames ['translation-handler'] Translation file names to process
locales ['en'] Supported locales

Default Formats

Option Default Description
defaultImportFrom php_file Default source format for import
defaultImportTo json_file Default destination format for import
defaultExportFrom json_file Default source format for export
defaultExportTo php_file Default destination format for export

PHP

Option Default Description
phpPath lang_path() Path to PHP translation files
phpFormat false Format PHP output
phpHandlerClass PhpFileHandler::class Handler class

JSON

Option Default Description
jsonPath lang_path() Path to JSON translation files
jsonFileName '' File name (empty = use locale as filename, set = use locale as folder)
jsonNested false Nest output like PHP files
jsonFormat true Pretty-print JSON output
jsonHandlerClass JsonFileHandler::class Handler class

CSV

Option Default Description
csvPath storage_path('lang') Path to CSV files
csvFileName translations CSV file name
csvDelimiter ; CSV delimiter (must differ from keyDelimiter)
csvHandlerClass CsvFileHandler::class Handler class

Database

Option Default Description
dbHandlerClass DatabaseHandler::class Handler class

Contributing

Contributions are welcome! Please submit a pull request or open an issue to discuss what you would like to change.

License

The MIT License (MIT). Please see License File for more information.