DeepL Client
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
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:
| Status | Exception | Message |
|---|---|---|
| 400 | LogicException | Bad request – check parameters |
| 403 | AuthException | Authorization failed |
| 404 | LogicException | API endpoint not found |
| 413 | LogicException | Request size limit exceeded |
| 429, 529 | LogicException | Too many requests (after retries) |
| 456 | LogicException | Quota exceeded |
| 500/503/504 | LogicException | Server 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 code | LC_ALL | DeepL receives |
|---|---|---|
de-ch | de_DE.UTF-8 | DE-CH |
de | de_CH.UTF-8 | DE-CH |
en | en_GB.UTF-8 | EN-GB |
es | es_MX.UTF-8 | ES-419 |
de | none | DE |
ca | es_ES.UTF-8 | CA |
Request Options
Custom request options merge into every translate call. See DeepL request body parameters.
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.