PHPackages                             eugene-erg/laravel-google-informal-icu-i18n-translate - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. eugene-erg/laravel-google-informal-icu-i18n-translate

ActiveLibrary[Localization &amp; i18n](/categories/localization)

eugene-erg/laravel-google-informal-icu-i18n-translate
=====================================================

description

1.0.2(1mo ago)13MITPHP

Since Apr 15Pushed 1mo agoCompare

[ Source](https://github.com/EugeneErg/laravel-google-informal-icu-i18n-translate)[ Packagist](https://packagist.org/packages/eugene-erg/laravel-google-informal-icu-i18n-translate)[ RSS](/packages/eugene-erg-laravel-google-informal-icu-i18n-translate/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (3)Dependencies (7)Versions (4)Used By (0)

laravel-google-informal-icu-i18n-translate
==========================================

[](#laravel-google-informal-icu-i18n-translate)

> Laravel integration for Google Translate that automatically translates ICU MessageFormat strings with database caching and informal (conversational) style support.

[![PHP](https://camo.githubusercontent.com/b5d4f7901c58ad1ddfff679966f426cc25a9354bab763846b9a7276c2feab4e0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253545382e322d626c7565)](https://www.php.net/)[![Laravel](https://camo.githubusercontent.com/9d20aebd92d8958ef0b71993fd607d18618e60f3e518b0780e633e981ca284c3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d25354531332e332d726564)](https://laravel.com/)[![License: MIT](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

---

Table of Contents
-----------------

[](#table-of-contents)

- [Description](#description)
- [Architecture &amp; Packages](#architecture--packages)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
    - [Translating plain text](#translating-plain-text)
    - [Translating an ICU pattern with variables](#translating-an-icu-pattern-with-variables)
    - [Translation with automatic language detection](#translation-with-automatic-language-detection)
    - [Working with translation files](#working-with-translation-files)
    - [Manual translation management](#manual-translation-management)
- [Comparison with alternatives](#comparison-with-alternatives)
- [Extending: adding a custom translator](#extending-adding-a-custom-translator)
- [How it works internally](#how-it-works-internally)
- [Error handling](#error-handling)
- [FAQ](#faq)

---

Description
-----------

[](#description)

This package adds automatic machine translation of **ICU MessageFormat** strings to Laravel via the free Google Translate Informal API.

**Key features:**

- Full ICU MessageFormat support — `plural`, `select`, `selectordinal`, nested constructs
- Variables (`{count}`, `{name}`) are never sent to Google Translate — they are replaced with safe placeholders and restored after translation
- Translation results are cached in the database; no repeated requests to Google are made
- Informal / conversational style support (Google Translate Informal API)
- Automatic source language detection
- Built as part of the `eugene-erg/icu-i18n-translator` ecosystem with support for multiple translation providers simultaneously

---

Architecture &amp; Packages
---------------------------

[](#architecture--packages)

This package is a Laravel wrapper over three layers:

```
laravel-google-informal-icu-i18n-translate  ← this package (ServiceProvider, IoC registration)
    └── google-informal-icu-i18n-translate  ← GoogleInformalTranslator + HTTP client for Google
    └── laravel-icu-i18n-translate          ← Eloquent repositories, migrations, base ServiceProvider
            └── icu-i18n-translator         ← core: Translator, TranslatorInterface, ICU parser

```

PackagePurpose`eugene-erg/icu-i18n-translator`Core: ICU parsing, translation orchestration, storage`eugene-erg/laravel-icu-i18n-translate`Eloquent repositories, migrations, base DI`eugene-erg/google-informal-icu-i18n-translate`HTTP client for Google Translate Informal API`eugene-erg/laravel-google-informal-icu-i18n-translate`**This package**: registers the Google translator in the Laravel IoC container---

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 13.3+
- `ext-intl` (required by `MessageFormatter`)
- PSR-18 HTTP client (`guzzlehttp/guzzle` is used by default and pulled in automatically)
- PSR-16 Simple Cache (Laravel's `Cache::store()` is bound automatically)

---

Installation
------------

[](#installation)

### 1. Install via Composer

[](#1-install-via-composer)

```
composer require eugene-erg/laravel-google-informal-icu-i18n-translate
```

### 2. Run migrations

[](#2-run-migrations)

Migrations are provided by the `laravel-icu-i18n-translate` package and create four tables:

```
php artisan migrate
```

Tables created:

TablePurpose`groups`Groups — unique ICU patterns with optional context`translates`Individual translations (one pattern variant, one locale)`group_translates`Mappings: group → translation by key and locale`paths`Translation file tree (used by `addFile` / `getFile`)### 3. Service Provider auto-discovery

[](#3-service-provider-auto-discovery)

Laravel will automatically register both Service Providers:

- `EugeneErg\LaravelIcuI18nTranslate\Providers\ServiceProvider`
- `EugeneErg\LaravelGoogleInformalIcuI18nTranslate\Providers\ServiceProvider`

No manual registration in `config/app.php` is required.

---

Configuration
-------------

[](#configuration)

The public Google Translate API endpoint is used by default:

```
https://translate.googleapis.com

```

To override the URL (e.g. for proxying), set the environment variable in your `.env`:

```
GOOGLE_ICU_I18N_TRANSLATE_API_URL=https://your-proxy.example.com
```

### Cache

[](#cache)

The package uses Laravel Cache to store the list of supported Google languages (cached for 1 day). No additional setup is needed — the default cache driver from your `config/cache.php` is used automatically.

---

Usage
-----

[](#usage)

All methods are available through `EugeneErg\IcuI18nTranslator\Translator`, which is registered in the Laravel IoC container. Standard constructor injection works out of the box:

```
use EugeneErg\IcuI18nTranslator\Translator;

class MyController extends Controller
{
    public function __construct(private Translator $translator) {}
}
```

Or resolve it directly:

```
$translator = app(\EugeneErg\IcuI18nTranslator\Translator::class);
```

---

### Translating plain text

[](#translating-plain-text)

```
$translated = $translator->translateText(
    text: 'Hello, welcome to our service!',
    toLocale: 'ru',
    fromLocale: 'en',  // optional
);

// "Привет, добро пожаловать в наш сервис!"
```

On the first call the string is translated via Google and persisted to the database. On subsequent calls it is returned from the database with no request to Google.

---

### Translating an ICU pattern with variables

[](#translating-an-icu-pattern-with-variables)

ICU MessageFormat supports dynamic variables, pluralisation, and conditional constructs. Variables are fully protected from being sent to Google — they are replaced with placeholders `{{_0_}}`, `{{_1_}}`, etc. before the request, and restored after the response is received.

```
// Simple variable
$result = $translator->translateMessage(
    pattern: 'Hello, {name}!',
    values: ['name' => 'Ivan'],
    toLocale: 'ru',
    fromLocale: 'en',
);
// "Привет, Иван!"

// Pluralisation (plural)
$result = $translator->translateMessage(
    pattern: 'You have {count, plural, one {# message} other {# messages}}.',
    values: ['count' => 5],
    toLocale: 'de',
    fromLocale: 'en',
);
// "Sie haben 5 Nachrichten."

// Conditional selection (select)
$result = $translator->translateMessage(
    pattern: '{gender, select, male {He ordered} female {She ordered} other {They ordered}} a pizza.',
    values: ['gender' => 'female'],
    toLocale: 'fr',
    fromLocale: 'en',
);
// "Elle a commandé une pizza."
```

---

### Translation with automatic language detection

[](#translation-with-automatic-language-detection)

If the source language is unknown, the package will detect it automatically via Google:

```
$result = $translator->translateMessage(
    pattern: 'Bonjour le monde!',
    values: [],
    toLocale: 'en',
    // fromLocale is omitted
);
// "Hello world!"
```

You can also call the translator directly through `TranslatorInterface`:

```
use EugeneErg\IcuI18nTranslator\TranslatorInterface;
use EugeneErg\IcuI18nTranslator\DataTransferObjects\Variable;

/** @var TranslatorInterface $googleTranslator */
$result = $googleTranslator->translateWithDetect(
    pattern: ['Ciao ', new Variable(0), '!'],
    toLocale: 'en',
);

// $result->locale  === 'it'
// $result->pattern === ['Hello ', Variable(0), '!']
```

---

### Working with translation files

[](#working-with-translation-files)

You can import and export entire localisation files (e.g. Laravel PHP arrays):

```
// Import a translation file (format 'php' or your custom format)
$content = file_get_contents(resource_path('lang/en/messages.php'));

$translator->addFile(
    format: 'php',
    name: 'messages',
    content: $content,
    locale: 'en',
    context: null,
);

// Export the file in another language (translated automatically on demand)
$deContent = $translator->getFile(
    format: 'php',
    name: 'messages',
    locale: 'de',
);

file_put_contents(resource_path('lang/de/messages.php'), $deContent);
```

---

### Manual translation management

[](#manual-translation-management)

```
use EugeneErg\IcuI18nTranslator\ValueObjects\GroupId;

// List groups (paginated)
$groups = $translator->getGroups(pageSize: 20, page: 1);

// Get translations for a specific group
$translates = $translator->getTranslates(
    groupId: new GroupId(42),
    locale: 'ru',
);

// Override a translation manually
$translator->setTranslate(
    groupId: new GroupId(42),
    key: '0',        // variant key ('0' for simple strings)
    locale: 'ru',
    pattern: 'Привет, мир!',
);

// Remove a translation from a group
$translator->deleteTranslateFromGroup(
    groupId: new GroupId(42),
    key: '0',
    locale: 'ru',
);
```

---

Comparison with alternatives
----------------------------

[](#comparison-with-alternatives)

FeatureThis package`stichoza/google-translate-php`Laravel built-in i18nICU MessageFormat✅ full❌❌Variable protection during translation✅ automatic⚠️ manual—DB translation cache✅❌—Automatic language detection✅✅❌Plural / Select✅❌⚠️ limitedInformal / conversational style✅❌—Multiple providers simultaneously✅❌—Localisation file import/export✅❌✅Free, no API key required✅✅—> **Note:** The Google Translate Informal API is an unofficial endpoint. It requires no API key but provides no SLA. For high-traffic production use, consider obtaining an official Google Cloud Translation API key and implementing a custom `TranslatorInterface`.

---

Extending: adding a custom translator
-------------------------------------

[](#extending-adding-a-custom-translator)

The package supports registering multiple translation providers. Each provider implements `TranslatorInterface`. Providers are tried in registration order — the first one that declares support for the required language pair via `canTranslate()` is used.

### Implement the interface

[](#implement-the-interface)

```
use EugeneErg\IcuI18nTranslator\TranslatorInterface;
use EugeneErg\IcuI18nTranslator\DataTransferObjects\Variable;
use EugeneErg\IcuI18nTranslator\ValueObjects\Translated;

class DeepLTranslator implements TranslatorInterface
{
    public function translate(
        array $pattern,
        string $fromLocale,
        string $toLocale,
        ?string $context = null,
    ): array {
        // $pattern is an array of strings and Variable objects.
        // Variable objects must NOT be passed to DeepL — only process string elements.
        // ...
        return $translatedPattern;
    }

    public function translateWithDetect(
        array $pattern,
        string $toLocale,
        ?string $context = null,
    ): Translated {
        // ...
        return new Translated(locale: 'en', pattern: $translatedPattern);
    }

    public function canTranslate(string $toLocale, ?string $fromLocale = null): bool
    {
        return in_array($toLocale, ['en', 'de', 'fr', 'ru', 'ja']);
    }
}
```

### Register in a Service Provider

[](#register-in-a-service-provider)

```
use EugeneErg\IcuI18nTranslator\TranslatorInterface;

public function register(): void
{
    $this->app->extend(TranslatorInterface::class . '[]', function (array $translators): array {
        array_unshift($translators, new DeepLTranslator());  // prepend for highest priority
        return $translators;
    });
}
```

---

How it works internally
-----------------------

[](#how-it-works-internally)

When `translateMessage()` is called, the core executes the following steps:

```
1. Parse the ICU pattern → extract variants (plural/select may produce multiple)
2. Look up a group in the DB by original pattern + context + source locale
3. If a translation for toLocale already exists in group_translates → return from DB (cache hit)
4. Otherwise → call GoogleInformalTranslator.translate():
   a. Non-text ICU nodes (variables) are replaced with {{_0_}}, {{_1_}}, ...
   b. The text portion is sent to the Google Translate Informal API
   c. The response is parsed — placeholders are restored as Variable objects
5. The result is persisted to group_translates and translates
6. The final string is formatted by PHP's MessageFormatter (ext-intl) with the provided values

```

---

Error handling
--------------

[](#error-handling)

All exceptions implement `TranslatorExceptionInterface`:

ExceptionCause`UnexpectedTranslateDirectionException`No provider supports the requested language pair`FormatNotFoundException`The requested file format is not registered`FileNotFoundException`The file was not found in the database`GroupNotFoundException`The group was not found`IncorrectTransferPatternException`The ICU pattern is invalid (`MessageFormatter` error)```
use EugeneErg\IcuI18nTranslator\Exceptions\TranslatorExceptionInterface;
use EugeneErg\IcuI18nTranslator\Exceptions\UnexpectedTranslateDirectionException;

try {
    $result = $translator->translateText('Hello', toLocale: 'xx-unknown');
} catch (UnexpectedTranslateDirectionException $e) {
    // No provider supports this locale
} catch (TranslatorExceptionInterface $e) {
    // Any other translator error
}
```

---

FAQ
---

[](#faq)

**Q: Is a Google API key required?**
A: No. An unofficial public endpoint is used. If needed, the URL can be overridden via `GOOGLE_ICU_I18N_TRANSLATE_API_URL`.

**Q: What happens to `{name}` and `{count}` during translation?**
A: They are never sent to Google. The core replaces them with `{{_0_}}`, `{{_1_}}`, etc. before the request and restores them after the response is received.

**Q: Are all `plural` variants translated separately?**
A: Yes. Each variant (`one`, `few`, `other`) is translated independently, ensuring grammatically correct output for every form.

**Q: How do I add DeepL or ChatGPT instead of Google?**
A: Implement `TranslatorInterface` and register it via `extend(TranslatorInterface::class . '[]', ...)` — see the [Extending](#extending-adding-a-custom-translator) section.

**Q: Can the package be used without Laravel?**
A: Yes, by using `eugene-erg/google-informal-icu-i18n-translate` and `eugene-erg/icu-i18n-translator` directly — you will need to wire the dependencies manually via your own DI setup.

---

License
-------

[](#license)

MIT © [EugeneErg](https://github.com/EugeneErg)

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance91

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~29 days

Total

3

Last Release

43d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/899442d4ad0c107f9972542ef053239fcbff4f3c718ab77c9219e6daa02d852d?d=identicon)[EugeneErg](/maintainers/EugeneErg)

---

Top Contributors

[![EugeneErg](https://avatars.githubusercontent.com/u/19587107?v=4)](https://github.com/EugeneErg "EugeneErg (6 commits)")

###  Code Quality

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/eugene-erg-laravel-google-informal-icu-i18n-translate/health.svg)

```
[![Health](https://phpackages.com/badges/eugene-erg-laravel-google-informal-icu-i18n-translate/health.svg)](https://phpackages.com/packages/eugene-erg-laravel-google-informal-icu-i18n-translate)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
