DeepL Client

Talk to the DeepL API directly from PHP – override language mapping, tune request options, or mock the client in tests.

Used internally by DeepLStrategy. Instantiate it directly when building a custom Strategy, overriding language mapping, or stubbing translation in tests.

Construction

use JohannSchopplich\ContentTranslator\DeepL;

$client = DeepL::instance();

DeepL::instance() returns a shared client; new DeepL() builds a fresh one. The constructor throws AuthException('Missing DeepL API key') when johannschopplich.content-translator.DeepL.apiKey is empty.

public function __construct(Closure|null $remote = null, Closure|null $delay = null)

public static function instance(): self
public static function reset(): void
remote
Closure | null
Replaces the HTTP request.
delay
Closure | null
Replaces the retry delay.

Methods

translate

public function translate(string $text, string|TranslationLanguage $targetLanguage, string|TranslationLanguage|null $sourceLanguage = null): string

Convenience wrapper around translateMany([$text], …).

translateMany

public function translateMany(array $texts, string|TranslationLanguage $targetLanguage, string|TranslationLanguage|null $sourceLanguage = null): array

Translates any number of texts in one call.

$translations = DeepL::instance()->translateMany(
    ['Hello', 'Goodbye', 'Thank you'],
    'de',
    'en'
);
// ['Hallo', 'Auf Wiedersehen', 'Danke']

Error Handling

The client maps DeepL HTTP responses to typed exceptions:

StatusExceptionMessage
400LogicExceptionBad request – check parameters
403AuthExceptionAuthorization failed
404LogicExceptionAPI endpoint not found
413LogicExceptionRequest size limit exceeded
429, 529LogicExceptionToo many requests (after retries)
456LogicExceptionQuota exceeded
500/503/504LogicExceptionServer error (after retries)

429 and 5xx responses are retried a few times before the error is raised. Every other error status throws on the first response.

A 200 whose body does not answer every text throws LogicException.

Language Code Resolution

A Kirby language code and its LC_ALL locale resolve to a DeepL target code as described under Supported Languages; a target code DeepL cannot name throws LogicException unless mapped via targetLanguageOverrides, while an unnamed source is omitted and DeepL detects it.

Kirby codeLC_ALLDeepL receives
de-chde_DE.UTF-8DE-CH
dede_CH.UTF-8DE-CH
enen_GB.UTF-8EN-GB
eses_MX.UTF-8ES-419
denoneDE
caes_ES.UTF-8CA
To map a Kirby language code to a DeepL target code yourself, see Language Code Overrides.

Request Options

Custom request options merge into every translate call. See DeepL request body parameters.

site/config/config.php
return [
    'johannschopplich.content-translator' => [
        'DeepL' => [
            'apiKey' => 'your-deepl-api-key',
            'requestOptions' => [
                'formality' => 'more',
                'glossary_id' => 'YOUR_GLOSSARY_ID',
            ],
        ],
    ],
];
tag_handling=html is sent only for texts carrying markup, so plain text keeps its <, >, and ' unescaped. Setting tag_handling in requestOptions pins it for every text.