DeepL & AI Translations
for Whole Pages
One click translates entire pages, including nested blocks. Select target languages in the Panel or automate via CLI.
Overview demonstration of translating content with DeepL in Kirby Panel and CLI: paused
Same Page,
Every Language
Batch Translation
Pick languages and strategy in one dialog
In the default language, tick the target languages and choose DeepL or the AI Kirby Copilot is set up with. Every eligible field comes with it, nested or not.
KirbyTags
Links and images survive translation
In textarea and markdown fields, only the attributes you list, like link text or alt, are translated. URLs, UUIDs, and file names stay untouched.
View Button
Import or translate, one language at a time
In a secondary language, the Translator button imports the default language's content or translates what is in the form. Nothing is saved until you have looked at it.
Luise Frey: Räume der Stille
Translation Coverage
See what still needs translating
The Languages view shows a completion ring per language and a tree of the pages still missing one. Each language tag opens the page in the language that lacks content.
Translation Coverage ×
- Deutsch
- 100%
- All pages translated
- Français
- 64%
- 5 incomplete pages
- Español
- 21%
- 15 incomplete pages
Pages to Translate ×
Automate With the
PHP API
Call the translator on any page from CLI commands, hooks, or your own code.
- CLI CommandsCreate Kirby CLI commands to batch translate pages.
- The Same PipelineCopy, translate, and sync content with the calls the Panel uses.
site/commands/translate-blog.php
// Run: kirby translate-blog
use JohannSchopplich\ContentTranslator\Translation\Strategies\CopilotAIStrategy;
use Kirby\CLI\CLI;
return [
'description' => 'Translate all blog posts to German via AI',
'command' => static function (CLI $cli): void {
$kirby = $cli->kirby();
$source = $kirby->defaultLanguage()->code();
$strategy = new CopilotAIStrategy();
foreach (page('blog')->children() as $post) {
$translator = $post->translator();
$translator->copyContent('de', $source);
$translator->translateContent('de', 'de', $source, $strategy);
$translator->translateTitle('de', 'de', $source);
$cli->out('✓ ' . $post->title());
}
$cli->success('All posts translated!');
}
];
Still Scrolling?
Test the plugin locally on real content. Pay only when you're ready to go live.