Global Configuration
Translation Strategy
At least one translation strategy must be configured. Pick one below – the strategy option selects which one runs.
AI Translation
Context-aware translation via the Kirby Copilot plugin (OpenAI, Anthropic, Google, Mistral).
Available Properties
Set global defaults that apply to both view buttons and sections. These can be overridden in individual blueprints. The following configuration sets DeepL as the translation strategy and defines global defaults for field types, title translation, slug translation, and KirbyTags translation:
return [
'johannschopplich.content-translator' => [
// Translation strategy
'DeepL' => [
'apiKey' => 'your-deepl-api-key'
],
// Global default properties for view buttons and sections
'fieldTypes' => [
'blocks',
'text',
'textarea'
],
'title' => true,
'slug' => true,
'kirbyTags' => [
'link' => ['text', 'title'],
'image' => ['alt', 'caption'],
'file' => ['text', 'title']
]
]
];
Every view button and section property except cascade, label, systemPrompt, and theme can be set here as a project-wide default; the View Button & Section Configuration page describes each one. systemPrompt becomes ai.systemPrompt; cascade, label, and theme stay in the blueprint. Everything below exists only globally.
strategy Mixed
Selects the translation strategy explicitly. Accepts a string preset, a closure, or a Strategy instance. Without this option the plugin uses the deprecated translateFn if one is configured, and DeepL otherwise.
| Value | Resolves to | Panel label |
|---|---|---|
'deepl' | DeepLStrategy – requires DeepL.apiKey | DeepL |
'ai' | CopilotAIStrategy – requires the Kirby Copilot plugin | no toggle |
Closure | Wrapped in CallableStrategy. Signature: fn (string $text, string $target, ?string $source): string | Custom |
Strategy | Used as-is – instance of JohannSchopplich\ContentTranslator\Translation\Strategy | Custom |
The Panel follows this option: a closure or Strategy instance enables the translation buttons without a DeepL.apiKey, and 'ai' makes AI translation the only strategy on offer – with a single strategy there is nothing to pick, so single-language translation starts without a dialog.
return [
'johannschopplich.content-translator' => [
'strategy' => 'deepl', // or 'ai'
]
];
return [
'johannschopplich.content-translator' => [
'strategy' => function (string $text, string $target, ?string $source): string {
return myTranslateApi($text, $target, $source);
},
]
];
use App\Translation\MyApiStrategy;
return [
'johannschopplich.content-translator' => [
'strategy' => new MyApiStrategy(),
]
];
translateFn option is deprecated and will be removed in v4. Migrate by renaming the key to strategy – the closure signature is identical.batchConcurrency Integer
Translations run in parallel to improve performance – the languages of a batch run and the pages and files of a cascade alike. By default, up to 2 run at a time to avoid hitting API rate limits.
Lower it to 1 when the provider returns rate limit errors – the translations then run one after another:
return [
'johannschopplich.content-translator' => [
'batchConcurrency' => 1
]
];
coverage Mixed
Scopes the coverage dashboard in the Languages view to a Pages collection, or removes it with false. See Translation Coverage.
cache Mixed
Points the plugin's own cache at another driver, or turns it off. It backs the coverage rings and the page tree – see Caching.
ai.systemPrompt String
When using AI translation, you can replace the built-in system prompt with a custom one. Set it globally or override it per blueprint.
return [
'johannschopplich.content-translator' => [
'ai' => [
'systemPrompt' => 'You are a medical translator. Preserve clinical terminology and abbreviations.'
]
]
];