---
title: "DeepLStrategy"
description: "Translate via DeepL with automatic batching and retries – the default strategy when nothing else is configured."
canonical_url: "https://kirby.tools/docs/content-translator/php-classes/strategies/deepl-strategy"
---

# DeepLStrategy

> Translate via DeepL with automatic batching and retries – the default strategy when nothing else is configured.

Selected automatically when neither `strategy` nor the deprecated `translateFn` is configured. Inject a custom `DeepL` client to override language mapping or stub it out in tests.

## Behavior

Units are sent via `DeepL::translateMany()` (auto-chunked at 50 texts per request). When the upstream request fails, every unit triggers `content-translator.translate:warning` and a `TranslationException` is thrown.

<note>

Selected via `'strategy' => 'deepl'`. Also the last-resort default – chosen whether or not `DeepL.apiKey` is set, with the `AuthException` for a missing key raised lazily on the first `execute()` call.

</note>

## Construction

```php
public function __construct(DeepL|null $deepL = null)
```

<field-group>
<field name="deepL" type="DeepL | null">

Inject a custom `DeepL` client – useful in tests or when you want non-singleton instances. Defaults to `DeepL::instance()`.

</field>
</field-group>

## Usage

<tabs :default-value="config">
<tabs-item label="Via config" value="config">

```php [config.php]
return [
    'johannschopplich.content-translator' => [
        'strategy' => 'deepl',
        'DeepL' => [
            'apiKey' => env('DEEPL_API_KEY'),
        ],
    ],
];
```

</tabs-item>

<tabs-item label="Per call" value="per-call">

```php
use JohannSchopplich\ContentTranslator\Translation\Strategies\DeepLStrategy;
use JohannSchopplich\ContentTranslator\Translator;

Translator::translateText('Hello', 'de', 'en', new DeepLStrategy());
```

</tabs-item>

<tabs-item label="Custom client" value="custom">

```php [config.php]
use JohannSchopplich\ContentTranslator\DeepL;
use JohannSchopplich\ContentTranslator\Translation\Strategies\DeepLStrategy;

return [
    'ready' => fn () => [
        'johannschopplich.content-translator' => [
            'strategy' => new DeepLStrategy(new DeepL()),
        ],
    ],
];
```

</tabs-item>
</tabs>

<warning>

Build the client inside Kirby's `ready` callback, not in the returned array directly. `new DeepL()` reads `DeepL.apiKey` in its constructor, and at the top level of `config.php` the options are still being assembled – the constructor throws `AuthException: Missing DeepL API key` even though the key sits right next to it. `ready` runs once the app is booted and the plugin is autoloaded, so both are in place. The same applies to any `Strategy` instance built in the config.

</warning>

<callout color="info" icon="i-ri-arrow-right-line" to="/docs/content-translator/php-classes/deepl-client">

For request-option tuning (formality, glossary IDs, custom `tag_handling`), see the **DeepL client** reference.

</callout>

---

Every page of this site as Markdown: <https://kirby.tools/sitemap.md>
