Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Microsoft Translator Laravel Package

matthiasnoback/microsoft-translator

PHP client for the Microsoft Translator API that lets you translate text between languages through a clean, object-oriented interface. It handles authentication, HTTP requests, and responses, making it easy to add translation features to any PHP or Laravel application.

Deep Wiki
Context7

Getting Started

  1. Install the package and an HTTP layer. This library is deliberately thin: it builds API requests and parses responses, but it does not ship an HTTP client. You must provide PSR-18 (psr/http-client) and PSR-17 (psr/http-factory) implementations:

    composer require matthiasnoback/microsoft-translator guzzlehttp/guzzle
    

    (Symfony’s symfony/http-client with psr18 adapters works equally well.)

  2. Collect credentials from Azure. In the Azure portal create a Translator resource (Cognitive Services). Copy the key and the region (e.g. westeurope). The region is not optional — it is required by the V3 API and is a common source of 401s.

  3. Wire up the client. The package exposes a MicrosoftTranslator\Client that is constructed with an API key, a region, and PSR-18/PSR-17 dependencies (check the constructor signature in src/Client.php for the exact order in your installed version):

    use GuzzleHttp\Client as HttpClient;
    use GuzzleHttp\Psr7\HttpFactory;
    use MicrosoftTranslator\Client;
    use MicrosoftTranslator\ApiCall\Translate;
    
    $factory = new HttpFactory();
    
    $client = new Client(
        new HttpClient(),
        $factory,          // PSR-17 request factory
        $factory,          // PSR-17 stream factory
        config('services.microsoft_translator.key'),
        config('services.microsoft_translator.region'),
    );
    
    $result = $client->execute(
        new Translate('en', 'nl', ['Hello world'])
    );
    
    echo $result->getTranslation();
    
  4. First real use case: translate an array of UI strings from a source language to a target language. Because the API accepts arrays, translating a batch is a single call — this is the fastest win compared with looping over individual strings.

  5. Where to look first.

    • src/ApiCall/ — one class per API endpoint (Translate, TranslateArray, Detect, GetLanguages, etc.). This is your map of what is supported.
    • The tests directory — the most reliable, runnable examples of how each API call is constructed and how responses are read.
    • README.md — the only narrative documentation; read it once, then treat the source as the reference.

Implementation Patterns

Wrap the client in your own service. Do not sprinkle new Translate(...) calls through controllers. Create a TranslationService (or Translator facade) that owns the MicrosoftTranslator\Client, chooses the correct ApiCall object, and returns a normalized result your domain understands:

class TranslationService
{
    public function __construct(private Client $client) {}

    public function translate(string $text, string $from, string $to): string
    {
        $result = $this->client->execute(new Translate($from, $to, [$text]));

        return $result->getTranslation();
    }
}

Bind everything in the container. Register the PSR-18 client, the PSR-17 factories, and MicrosoftTranslator\Client as singletons in a Laravel service provider. Keep the key and region in config/services.php backed by .env, never inline. This makes the code testable and lets you swap in a mock client.

Batch aggressively, but chunk. The API is designed for arrays; sending 50 strings in one request is dramatically cheaper and faster than 50 requests. Enforce a chunk size in your service (see limits below) and array_chunk() the input before building Translate/TranslateArray calls.

Detect before translate when the source is unknown. Chain an ApiCall\Detect call and pass the resulting language code into the Translate call. Cache the detected language per string — detection is a second billed request.

Cache translated strings. Translation is deterministic for a given source/target/text, so a key like sha1("{$from}|{$to}|{$text}") stored in Redis or the database is a genuine cost saver. Invalidate only when you deliberately change terminology or the target language.

Push bulk work onto a queue. For catalog imports, documentation translation, or any batch larger than a handful of strings, dispatch a job per chunk. This keeps request latency out of the user path and gives you a natural place to implement retry/backoff.

Integrate with Laravel’s HTTP client for testing. Because the package depends only on PSR-18, you can inject GuzzleHttp\Client backed by a MockHandler, or use Symfony’s MockHttpClient, and assert the outgoing request body and URL without hitting Azure. Alternatively, mock MicrosoftTranslator\Client itself in feature tests and reserve fake responses for the unit tests of your service.

Extend for missing endpoints. The library covers the common V3 endpoints but not necessarily every one. If you need an endpoint that has no ApiCall class, implement the ApiCall interface (or subclass an existing call) to provide the HTTP method, path, and JSON payload; the Client will execute it like any other call. This is the intended extension point.

Decorate the client for cross-cutting concerns. If you need logging, metrics, or retry logic, write a decorator around your own TranslationService (or around the client) rather than modifying the package. This keeps upgrades safe.

Gotchas and Tips

  • Region is mandatory and a frequent 401 cause. Azure returns 401 for a valid key sent with the wrong or missing Ocp-Apim-Subscription-Region header. Double-check the region matches the resource, not the data center you assume.
  • The library does no retries, no caching, and no rate limiting. A 429 or transient 5xx surfaces as an exception (or an error response, depending on the call). Wrap execute() in your service and add exponential backoff; respect any Retry-After header.
  • Respect the request limits. The Translator V3 API caps requests at roughly 100 array elements and 50,000 characters per request (and per-element length limits). Validate and chunk before calling, or you will get 400s that are hard to trace back to a single oversized string.
  • Errors are exceptions, not silent empties. Catch Throwable around execute() in the service layer, log the request context (source, target, batch size — never the key), and decide whether to fail the job, skip the batch, or return the original text. For UI-facing translation, silently returning the source string is often better than showing an error.
  • Language codes must be valid BCP-47 codes. en, nl, pt-br, zh-Hans. Use a GetLanguages call (or a checked-in snapshot of the result) to validate codes at boot/test time rather than discovering a typo in production.
  • Auto-detection is billed and occasionally wrong on short strings. Don’t detect one-word labels; send a small sample of the batch if you need a hint. Cache detection results.
  • HTML/XML content needs the right content type. If you translate markup, pass the content type parameter supported by the Translate call, otherwise tags get mangled. Plain text is the default; don’t assume it is safe for rich content.
  • Empty strings and whitespace produce surprising results. Filter empty entries before batching; the API may return empty or shifted results, and the array indexes in the response correspond to the request array, so a filtered batch must be mapped back carefully.
  • Response shape is array-indexed. When translating a batch, keep the input order and map results back by index (or by a wrapper value such as an ID if the endpoint supports it). Never assume the API reorders.
  • This package is intentionally minimal and low-traffic (39 stars). Pin the version in composer.json, read the changelog before upgrading, and be prepared to patch or wrap it. The 2024-08-23 release is recent enough to be usable, but the maintenance cadence is not that of a large vendor SDK.
  • Testing: the fastest reliable test strategy is a fake PSR-18 client returning canned Azure JSON. Avoid calling the live API in CI; keys are billed per character and tests become flaky.
  • Key rotation: read the key from config at runtime, not at class-construction time buried in a singleton you cannot rebuild, so you can rotate credentials without a deploy if you use a secrets manager.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log