lukasccb/laravel-ai-translations

Scan, manage, and AI-translate __() strings stored in the database for Laravel applications.

Maintainers

Package info

github.com/LukasCCB/laravel-ai-translations

pkg:composer/lukasccb/laravel-ai-translations

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.0.1 2026-03-27 18:36 UTC

This package is auto-updated.

Last update: 2026-03-31 13:18:36 UTC


README

Latest Version on Packagist License

A Laravel package that automatically scans your codebase for __() translation strings, stores them in the database, and translates them to any language using AI — powered by Prism.

laravel-ai-translate.png

What It Does

Instead of manually maintaining JSON/PHP translation files for every language, this package:

  1. Scans your entire codebase (Blade, PHP, JS, Vue) for __(), trans(), @lang(), and Lang::get() calls
  2. Stores every unique string in a translations database table
  3. Translates all strings to any target language using AI (OpenAI, Anthropic, etc. via Prism)
  4. Serves translations at runtime by hooking into Laravel's translation system — zero code changes needed

Your existing __('Hello World') calls just work. No file management, no copy-pasting, no manual editing.

Benefits

  • Zero migration effort — works with any existing Laravel app that uses __() strings
  • Database-driven — all translations live in one table, easy to query, export, or edit
  • AI-powered — translate hundreds of strings to any language in minutes, not days
  • Case-sensitive — distinguishes between "paid" and "Paid" as separate entries
  • Database column scanning — also picks up translatable strings stored in your database tables
  • Cached — translations are cached per locale with configurable TTL
  • Auto-invalidation — cache clears automatically when translations are created, updated, or deleted
  • Pluggable AI — swap the default Prism translator for any provider via a simple interface
  • 24 languages included out of the box (en, pt, es, fr, de, it, nl, ru, zh, and more)

Requirements

  • PHP 8.2+
  • Laravel 11, 12, or 13
  • MySQL (recommended, for case-sensitive collation) or SQLite/PostgreSQL
  • Prism (optional — only needed for AI translation commands)

Installation

1. Install the package

composer require lukasccb/laravel-ai-translations

The service provider is auto-discovered. No manual registration needed.

2. Publish the config and migration

php artisan vendor:publish --tag=ai-translations-config
php artisan vendor:publish --tag=ai-translations-migrations

3. Run the migration

php artisan migrate

4. (Optional) Install Prism for AI translations

composer require prism-php/prism

Configuration

After publishing, edit config/translation.php:

return [

    // The source language of your project
    'source_language' => 'en_US',

    // Default batch size for AI translation runs
    'batch_size' => env('TRANSLATION_BATCH_SIZE', 500),

    // Directories and file types to scan
    'scan' => [
        'paths' => [
            resource_path('views'),
            app_path(),
            base_path('lang'),
            resource_path('js'),
        ],
        'extensions' => ['php', 'blade.php', 'js', 'vue'],
        'exclude' => [
            base_path('vendor'),
            base_path('node_modules'),
            // ...
        ],
    ],

    // Database columns that contain translatable strings (read-only)
    'database_scan' => [
        'roles' => ['name', 'description'],
        'settings' => [
            'column'        => 'value',
            'filter_by'     => 'key',
            'filter_values' => ['site_description', 'meta_title'],
        ],
    ],

    // AI translator class (implements TranslatorInterface)
    'translator' => \LukasCCB\AiTranslations\Translators\PrismTranslator::class,

    // AI provider settings (used by PrismTranslator)
    'ai' => [
        'provider'   => env('TRANSLATION_AI_PROVIDER', 'openai'),
        'model'      => env('TRANSLATION_AI_MODEL', 'gpt-4o-mini'),
        'max_tokens' => env('TRANSLATION_AI_MAX_TOKENS', 500),
    ],

    // Cache TTL in seconds (0 = disabled)
    'cache_ttl' => env('TRANSLATION_CACHE_TTL', 3600),

    // Custom locale resolver for the SetLocale middleware (null = use session)
    'locale_resolver' => null,
];

Add these to your .env:

TRANSLATION_AI_PROVIDER=openai
TRANSLATION_AI_MODEL=gpt-4o-mini
TRANSLATION_BATCH_SIZE=500
TRANSLATION_CACHE_TTL=3600

Usage

Step 1: Scan your codebase

php artisan translations:scan

This will:

  • Find every __(), trans(), @lang(), and Lang::get() call in your project
  • Extract translatable strings from configured database columns
  • Insert new strings into the translations table (source language)
  • Automatically clean up orphaned strings that no longer exist in the codebase

Options:

# Custom batch size for DB insertion
php artisan translations:scan --batch=200

# Force mode: re-insert and delete obsolete records
php artisan translations:scan --force

Step 2: Translate to a target language

php artisan translations:start --lang=pt_BR --alias="Portugues (Brasil)"

This sends each source string to the configured AI provider and stores the translation.

Options:

# Limit how many strings to translate in one run
php artisan translations:start --lang=pt_BR --alias="Portugues (Brasil)" --batch=100

# Re-translate everything, even already translated strings
php artisan translations:start --lang=pt_BR --alias="Portugues (Brasil)" --force

Step 3: Auto-translate all languages

If you have multiple target languages already registered:

php artisan translations:auto-translate

This finds all languages with at least one record and translates any missing strings.

Cleanup orphaned strings

php artisan translations:cleanup

Removes translation records (across all languages) for strings that no longer exist in your codebase. This is also called automatically before every scan.

Middleware

Register the SetLocale middleware to automatically set the application locale per request:

// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        \LukasCCB\AiTranslations\Middleware\SetLocale::class,
    ]);
})

By default, it reads from session('locale') and falls back to the configured source_language. You can customize this with a locale resolver:

// config/translation.php
'locale_resolver' => function (\Illuminate\Http\Request $request): ?string {
    return $request->user()?->preferred_locale;
},

Dispatching Translations via Queue

For long-running translation batches, use the built-in job:

use LukasCCB\AiTranslations\Jobs\TranslateLanguageJob;

TranslateLanguageJob::dispatch(
    lang: 'es_ES',
    alias: 'Espanol (Espana)',
    batch: 200,
    force: false,
);

Custom AI Translator

The package uses TranslatorInterface to decouple from any specific AI provider. To use your own:

1. Implement the interface

<?php

declare(strict_types=1);

namespace App\Translators;

use LukasCCB\AiTranslations\Contracts\TranslatorInterface;

class MyCustomTranslator implements TranslatorInterface
{
    public function translate(string $text, string $targetLanguage, string $targetAlias): string
    {
        // Call your preferred API (DeepL, Google, custom LLM, etc.)
        $response = MyTranslationApi::translate($text, $targetLanguage);

        return $response->translatedText;
    }
}

2. Register it in config

// config/translation.php
'translator' => \App\Translators\MyCustomTranslator::class,

That's it. The translations:start and translations:auto-translate commands will use your implementation.

Database Column Scanning

You can scan database columns for translatable content (e.g., role names, setting values). The package reads these columns but never modifies the original tables.

// config/translation.php
'database_scan' => [

    // Simple: scan all rows in these columns
    'roles' => ['name', 'description'],
    'categories' => ['title'],

    // Filtered: only scan specific rows
    'settings' => [
        'column'        => 'value',
        'filter_by'     => 'key',
        'filter_values' => ['site_title', 'site_description'],
    ],
],

How It Works Under the Hood

__('Hello World')
       |
       v
Laravel Translator calls load($locale, '*', '*')
       |
       v
DatabaseTranslationLoader intercepts raw-string group
       |
       v
TranslationResolverService loads from DB (cached)
       |
       v
Returns ['Hello World' => 'Ola Mundo'] for pt_BR
       |
       v
User sees "Ola Mundo"

The package extends Laravel's default FileLoader with a DatabaseTranslationLoader that intercepts raw-string translation calls (namespace='*', group='*') and serves them from the database. File-based translations (validation.required, etc.) continue to work normally.

Source language behavior

  • Source language (e.g., en_US): Returns ALL non-null translated values, regardless of is_translated. This lets you customize display text (e.g., "Liquid Balance" to "Available Balance") without breaking defaults.
  • Other locales: Only returns strings where is_translated = true. Untranslated strings are not served to avoid showing placeholder text.

Available Commands

Command Description
translations:scan Scan codebase and DB columns for __() strings
translations:cleanup Remove orphaned strings no longer in codebase
translations:start Translate source strings to a target language via AI
translations:auto-translate Translate all untranslated strings for all registered languages

Supported Languages

The package ships with 24 pre-defined languages in resources/language-support.json:

Code Language
en_US English (United States)
en_GB English (United Kingdom)
pt_BR Portugues (Brasil)
pt_PT Portugues (Portugal)
es_ES Espanol (Espana)
es_MX Espanol (Mexico)
fr_FR Francais (France)
de_DE Deutsch (Deutschland)
it_IT Italiano (Italia)
nl_NL Nederlands (Nederland)
ru_RU Russian
uk_UA Ukrainian
pl_PL Polski (Polska)
tr_TR Turkce (Turkiye)
sv_SE Svenska (Sverige)
no_NO Norsk (Norge)
da_DK Dansk (Danmark)
fi_FI Suomi (Suomi)
cs_CZ Cestina (Cesko)
ro_RO Romana (Romania)
hu_HU Magyar (Magyarorszag)
el_GR Greek
zh_CN Chinese (Simplified)
zh_TW Chinese (Traditional)

You can translate to any language — this list is just a reference. Pass any ISO locale code to translations:start.

Testing

composer test

Full Example: From Zero to Translated

# 1. Install
composer require lukasccb/laravel-ai-translations
composer require prism-php/prism

# 2. Publish and migrate
php artisan vendor:publish --tag=ai-translations-config
php artisan vendor:publish --tag=ai-translations-migrations
php artisan migrate

# 3. Configure AI provider in .env
# TRANSLATION_AI_PROVIDER=openai
# TRANSLATION_AI_MODEL=gpt-4o-mini

# 4. Scan your project
php artisan translations:scan

# 5. Translate to Portuguese
php artisan translations:start --lang=pt_BR --alias="Portugues (Brasil)"

# 6. Translate to Spanish
php artisan translations:start --lang=es_ES --alias="Espanol (Espana)"

# 7. Done! Your __() calls now return translated strings
# based on the user's locale.

License

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