All products

Auto Translate

Translate your Eloquent models automatically, using AI or translation services.

The Whole Fruit Manifesto

This package makes running a multi-lingual Laravel app as easy as running a single-language website. More exactly, it adds AI-powered translation capabilities for projects that use Laravel and spatie/laravel-translatable:

  • Commands: run a command, and all incomplete database entries will be translated to all missing languages;
  • Model events: after an entry gets created/updated, the system can automatically translate that entry;
  • API: translate entries behind-the-scenes, in custom processes;

Put these features together and what you get is:

  • the fastest way to make your Laravel app multi-language - by far!
  • the easiest way for your admin/users to manage their entries (because they only need to worry about 1 language, not multiple);

That's right, this package solves all the remaining difficulties of running a multi-language web app. Big words - we know. But try it out. And best of all? We've made this is a general-purpose Laravel package - it does not depend on Backpack at all. So you can install it on any Laravel 12+ project, and it will just work.

https://github.com/user-attachments/assets/513101da-4048-4b4f-9156-6a78a3d9be30

Features

  • Manual Translation: Artisan command for translating specific models
  • Automatic Translation: Translates models on create/update via observers
  • Provider Abstraction: Swappable translation drivers (OpenAI, DeepL implemented)
  • Smart Caching: Prevents duplicate API calls for identical content
  • Queue Support: Background processing with retry logic
  • Constraint Handling: Preserves HTML tags, placeholders, and brand names
  • Per-Language Translation: Intelligent strategy switching for large content
  • Scalable Token Management: Higher token limits with configurable thresholds

Installation

1. Install via Composer

composer require backpack/auto-translate

# optional - you can publis the config file, if you want to make changes:
php artisan vendor:publish --tag=config --provider="Backpack\AutoTranslate\AddonServiceProvider"

This will publish the configuration file to config/backpack/auto-translate.php.

2. Choose, Install and Setup a Translation Driver

This package supports multiple translation providers. You need to choose one and install its dependencies:

| Driver | Providers | Best For | Cost | |--------|----------|----------|------| | DeepL Driver | DeepL API | Large content (eg. HTML) | High-cost | | OpenAI Driver | OpenAI GPT Models | Small & medium content | Low-cost | | Prism Driver | OpenAI, Anthropic, Ollama, Mistral, DeepSeek, Groq, xAI, custom LLMs | Trying different LLMs for your content | Low-cost | | Custom Driver | Your own implementation | Specific requirements, custom APIs | Varies |

Need another driver? You can create your own custom driver or send us an email - we will consider adding support for AWS Translate, Azure Translate, Google Cloud Translation, ModernMT etc - if people actually need them.

To verify your driver installation:

php artisan auto-translate:drivers

3. Environment File Configuration

Add these variables to your .env file:

# Auto Translation Settings
AUTO_TRANSLATE_ENABLED=true
AUTO_TRANSLATE_DRIVER=openai  # or deepl, or prism
# AUTO_TRANSLATE_QUEUE=translations # in production, it's highly recommended to run the translations on a separate queue

Double-check you have the .ENV variables for your driver (see driver documentation for details):

# Example for OpenAI:
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_TRANSLATE_MODEL=gpt-4o-mini

4. Queue Configuration

Make sure your queue is configured and working:

php artisan queue:work --queue=translations

In production, it's highly recommended to use a different queue for the translations than the one for the rest of the application. That way, one big translation taking 2min will not hold up any other jobs.

5. Set Up Models for Auto-Translation

Important Prerequisites:

  • Your database columns must already be JSON columns (migrated to use spatie/laravel-translatable)
  • This package only helps to automatically populate existing translatable JSON columns
  • You need to have spatie/laravel-translatable properly configured in your project

Method 1: Using the Trait (Recommended)

Add the HasAutoTranslations trait to your models that you will want translated:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
use Backpack\AutoTranslate\Traits\HasAutoTranslations;

class Event extends Model
{
    use HasTranslations, HasAutoTranslations;

    public array $translatable = ['name', 'description'];

    protected $fillable = ['name', 'description', 'date'];
}

Method 2: Using the Configuration File

Alternatively, you can specify which models should be auto-translated in the config file:

// config/backpack/auto-translate.php
'models' => [
    App\Models\Event::class,
    App\Models\Article::class,
    App\Models\Product::class,
],

Verify Your Setup:

Make sure your translatable columns are JSON columns in your database:

// Example migration
Schema::table('events', function (Blueprint $table) {
    $table->json('name')->nullable();
    $table->json('description')->nullable();
});

Usage

There are four ways in which you can auto-translate your Eloquent entries using this package:

1. Command-Line Translation

Use Artisan commands to translate existing database entries, check translation status, and manage bulk operations:

# Check translation status
php artisan auto-translate:status

# Translate all existing entries
php artisan auto-translate:run

# Translate one particular entry
php artisan auto-translate:entry

Perfect for: Migrating existing content, bulk operations, scheduled tasks, one-time translations.

2. Automatic Translation

Set up your models to automatically translate an entry when it's created or updated. Just add a trait to your model and translations happen in the background:

class Event extends Model
{
    use HasTranslations, HasAutoTranslations;
    public array $translatable = ['name', 'description'];
}

// In config: 'enabled_events' => ['created', 'updated']

Perfect for: Hands-off translation management, new projects where you want everything translated automatically.

3. Admin Control with Checkbox Field (Recommended)

If your entries are added by an admin (not the end-user), we found it's best to just add a checkbox at the end of the Create/Update form, that allows the admin to choose whether the AI should auto-translate. That gives them the power to translate when they want... or skip if they don't.

For example, here's how you can achieve that in Backpack:

// remember to use the Facade:
// use Backpack\AutoTranslate\Facades\AutoTranslate;
// then:

CRUD::field('_auto_translate')
    ->type('checkbox')
    ->label('After save, use AI to auto-translate to the other languages')
    ->default(true)
    ->fake(true)
    ->on('saved', function ($entry) {
        if (request()->input('_auto_translate')) {
            $success = AutoTranslate::translate(
                model: $entry,
                overwrite: true,
                immediate: false
            );

            if ($success) {
                \Prologue\Alerts\Facades\Alert::add('info', 'Auto-translation in progress. It could take a few seconds or minutes, depending on the amount of text to translate.')->flash();
            } else {
                \Prologue\Alerts\Facades\Alert::add('warning', 'Auto-translation job failed.')->flash();
            }
        }
    });

Perfect for: Most use cases where you want admin flexibility and control over the translation process.

4. Manual Translation

Use the AutoTranslate Facade directly in your PHP code for complete programmatic control:

use Backpack\AutoTranslate\Facades\AutoTranslate;

// Auto-detects source language (recommended)
AutoTranslate::translate($model);

// Or specify explicit source language
AutoTranslate::translate($model, sourceLocale: 'en');

// Translate in background (queued)
AutoTranslate::translate($model, queue: true);

// Translate specific attributes only
AutoTranslate::translate($model, attributes: ['name', 'description']);

// Translate to specific locales
AutoTranslate::translate($model, locales: ['es', 'fr']);

// Check if service is ready
if (AutoTranslate::isReady()) {
    AutoTranslate::translate($model);
}

Perfect for: Custom workflows, API integrations, conditional translation logic, advanced use cases.

For detailed API documentation, examples, and advanced usage patterns, see Manual Usage Documentation.

Cascade Translation

Automatically translate related models when a parent model is translated.

// When Event is translated, automatically translate its SeatingCategories
AutoTranslate::translate($event, cascade: ['seatingCategories']);

// Or define in your model
class Event extends Model {
    public array $autoTranslateRelationships = ['seatingCategories'];
}

// Command usage
php artisan auto-translate:entry "App\Models\Event" 123 --cascade=seatingCategories

Configuration

The configuration file config/backpack/auto-translate.php provides extensive customization options:

Event Configuration

You can control which model events trigger automatic translation:

// config/backpack/auto-translate.php
'enabled_events' => [], // Default: manual control only

// Examples:
'enabled_events' => ['created'],           // Only on model creation
'enabled_events' => ['updated'],           // Only on model updates
'enabled_events' => ['created', 'updated'], // Automatic on both create and update

Default Behavior: By default, enabled_events is set to an empty array [], which means automatic translation is disabled. This gives you complete control over when translations happen - perfect for use with the checkbox field approach above.

Full Configuration Options

return [
    // Enable/disable auto-translation
    'enabled' => env('AUTO_TRANSLATE_ENABLED', true),

    // Translation driver (openai, deepl, etc.)
    'driver' => env('AUTO_TRANSLATE_DRIVER', 'openai'),

    // Supported locales
    'supported_locales' => explode(',', env('APP_SUPPORTED_LOCALES', 'en,ro,es,bg')),

    // Source locale (defaults to 'auto' for automatic detection)
    'source_locale' => env('AUTO_TRANSLATE_SOURCE_LOCALE', 'auto'),

    // Queue configuration
    'queue' => env('AUTO_TRANSLATE_QUEUE', 'auto-translations'),

    // Cache TTL (30 days default)
    'cache_ttl' => env('AUTO_TRANSLATE_CACHE_TTL', 2592000),

    // Driver configurations
    'drivers' => [
        'openai' => [
            'api_key' => env('OPENAI_API_KEY'),
            'model' => env('OPENAI_TRANSLATE_MODEL', 'gpt-4o-mini'),
            'temperature' => 0.2,
            'max_tokens' => 2000,
        ],
    ],

    // Translation constraints
    'constraints' => [
        'preserve_html_tags' => ['a', 'strong', 'em', 'code', 'ul', 'ol', 'li', 'br', 'p'],
        'preserve_placeholders' => ['{{.*?}}', '%s', '{0}', '[:slug:]'],
        'dont_translate_terms' => ['Backpack', 'Laravel', 'SENZORIAL'],
        'style' => 'neutral, professional, concise',
    ],
];

Architecture

Translation Strategy System

The package includes an intelligent translation strategy system that automatically selects the optimal approach based on content size, ensuring reliable translations for both small and large content.

How It Works

Small Content (< 5000 characters for OpenAI, < 10000 for DeepL):

  • Uses the multi-language approach
  • Translates to all target languages in a single API call
  • Most efficient for short text like titles, names, descriptions

Large Content (≥ threshold):

  • Automatically switches to per-language strategy
  • Makes separate API calls for each target language
  • Prevents API limit errors and improves translation quality
  • Perfect for large content like page content, long descriptions, Terms & Conditions

Oversized Content (> max limit):

  • Returns clear error message indicating content is too large
  • Suggests manual content splitting or reduction
  • Prevents unreliable processing attempts

Configuration

You can customize the thresholds and limits in your configuration:

# OpenAI Settings
OPENAI_MAX_TOKENS=8000                           # Token limit
OPENAI_PER_LANGUAGE_THRESHOLD=5000               # When to switch strategies
OPENAI_MAX_CONTENT_SIZE=50000                    # Maximum content size

# DeepL Settings
DEEPL_PER_LANGUAGE_THRESHOLD=10000               # When to switch strategies
DEEPL_MAX_CONTENT_SIZE=120000                    # Maximum content size (~120KB)

Or in your config file.

Benefits

  • Reliable Processing: No more complex chunking that could break content
  • Clear Limits: Explicit error messages when content exceeds limits
  • Better Translation Quality: AI focuses on one language pair at a time for large content
  • Automatic Strategy Selection: No manual intervention required
  • Backward Compatible: Small content continues using efficient multi-language approach
  • Partial Success Handling: If one language fails, others still succeed
  • Detailed Logging: Track which strategy was used and monitor performance

Caching Strategy

Cache keys follow this format:

auto_tr:{provider}:{model_hash}:{model_id}:{attribute}:{source_locale}:{content_hash}:{targets_hash}

Benefits:

  • Prevents duplicate API calls for identical content
  • Respects overwrite settings
  • 30-day TTL (configurable)
  • Automatic cache invalidation

Error Handling & Reliability

  • Retry Logic: Exponential backoff for transient failures
  • Idempotent Jobs: Safe to retry without side effects
  • Comprehensive Logging: Detailed logs for debugging
  • Graceful Degradation: Continues processing other attributes on failure
  • Usage Tracking: Monitors API costs and performance

Monitoring & Debugging

Check Service Status

$autoTranslateService = app(AutoTranslateService::class);
$stats = $autoTranslateService->getStats();

// Returns:
// [
//     'enabled' => true,
//     'driver' => 'openai',
//     'driver_configured' => true,
//     'cache_enabled' => true,
//     'supported_locales' => ['en', 'ro', 'es', 'bg'],
//     'source_locale' => 'en',
//     'overwrite_default' => false,
// ]

Clear Model Cache

$autoTranslateService = app(AutoTranslateService::class);
$cleared = $autoTranslateService->clearModelCache($event);
echo "Cleared {$cleared} cache entries";

Log Monitoring

Monitor these log channels:

  • Translation job dispatching
  • API call success/failure
  • Cache hit/miss rates
  • Token usage and costs

Adding New Translation Providers

To add a new provider (e.g., DeepL):

  1. Create Driver: Implement AutoTranslatorDriverContract
  2. Update Config: Add driver configuration
  3. Register Driver: Update service provider
  4. Test: Create tests for new driver

Example:

use Backpack\AutoTranslate\Contracts\AutoTranslatorDriverContract;
use Backpack\AutoTranslate\DTOs\AutoTranslateRequest;
use Backpack\AutoTranslate\DTOs\AutoTranslateResult;

class DeepLAutoTranslator implements AutoTranslatorDriverContract
{
    public function translate(AutoTranslateRequest $request): AutoTranslateResult
    {
        // DeepL API integration
    }

    public function getDriverName(): string
    {
        return 'deepl';
    }

    // ... other methods
}

Troubleshooting

Common Issues

  1. Translations not triggering: Check if model uses HasTranslations trait and has $translatable array
  2. API errors: Verify OpenAI API key and model configuration
  3. Queue not processing: Ensure queue worker is running for auto-translations queue
  4. Cache issues: Clear cache or disable caching temporarily for debugging

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

This software is proprietary & closed-source, released under the End-User License Agreement (EULA) for Private Backpack Addons. A copy of that license is also provided inside the source code - you can read that file by using the tabs at the beginning of this page.

Package Access

You don't currently have access to this package. To gain access, go ahead and purchase it. You'll get:

Next 12 months
  • download or install using Composer;
  • all updates (major, minor and patch);
After 12 months
  • can still access all versions and updates you paid;
  • can still install using Composer;
  • no new versions or updates;
Buy for 999 EUR