Skip to content

CLI commands

The extension registers two Shopware console commands. nice-translate:run creates a translation job from the shell, and nice-translate:providers reports which providers you configured.

Both commands are available as soon as Shopware installs and activates the extension. Start them from the Shopware project root, like each other bin/console command.

nice-translate:run

Create a translation job and optionally watch its progress.

bash
bin/console nice-translate:run --to=de-DE

The command assembles the same job configuration as the translation wizard and gives it to the message queue. It translates nothing itself.

Options

OptionDescriptionRepeatableDefault
--entityThe entity to translate, for example product, category, snippetYesproduct
--toThe target locale code, for example de-DE, or all for each non-system languageYesrequired, no default
--fromThe source locale codeNothe system language
--providerdeepl, google, openai, anthropic, gemini, mistral or managedNothe Default provider setting, otherwise deepl
--modemissing fills the empty fields only, all overwrites the existing translationsNomissing
--scopeall processes each record, missing processes only the records with a minimum of one eligible missing target fieldNoall
--watch, -wPoll the job and show a progress bar until it finishesNo (flag)off

Repeat --entity and --to once for each value: --entity=product --entity=category --to=de-DE --to=fr-FR. Supported content lists the technical entity names that --entity accepts.

The scope selects records, and the mode selects fields. --scope decides which records go into the job. --mode decides whether the run writes a translated field inside those records again.

Validation and error messages

The command stops before it creates a job in these cases:

SituationMessage
You gave no --toProvide at least one target locale, e.g. --to=de-DE (repeatable), or --to=all.
--mode is not missing or allInvalid --mode "…". Use "missing" or "all".
--scope is not all or missingInvalid --scope "…". Use "all" or "missing".
--from matches no languageNo language found for source locale "…".
A --to locale matches no languageNo language found for locale(s): …
The requested targets equal the sourceNo target languages resolved — the requested locales only match the source language.
--entity is not a supported content typeThe entity "…" is not supported for translation.
The provider has no key and no active subscription… is not configured. Add an API key in the settings first.
DeepL or Google cannot map a locale in the runThe locale "…" is not supported by ….

--to=all resolves to each language in the shop except the system language. The resolved source language always leaves the target set, therefore --from=en-GB --to=all never tries to translate British English into itself.

Options that the command does not expose

--mode is the only job option that the command sets. Everything else keeps the job defaults, which resolve against your settings:

BehaviourValue used for a CLI job
Protect manual editson
Skip unchanged contenton
Include custom fieldson
Apply glossaryon, and also subject to Apply glossary in Settings → Advanced
Shorten SEO fieldson
Tone and custom instructionsthe values from Settings → Providers
Field selectionnone: each translatable field of the content type, minus the Excluded fields
Service tier (managed provider)Balanced (3 credits per source character)

If you need a different service tier, or a run without the manual-edit protection, start the job from the wizard. You cannot select individual fields in the wizard either. For that, use options.fields on the job endpoint of the Admin API.

The cost estimates come from the wizard only. A CLI job never gets one.

How the command interacts with the queue

The command writes a Queued job row and dispatches a start message to the low-priority transport of Shopware. The queue workers do the actual translation:

bash
bin/console messenger:consume async low_priority --time-limit=60 --memory-limit=512M

The command prints the id of the new job and a reminder:

The job is processed by the message queue. Make sure workers are running (bin/console messenger:consume).

Two consequences follow:

  • Without active workers, the job stays Queued indefinitely, and --watch never returns. See Troubleshooting.
  • If the command cannot dispatch the start message, it is still successful and still prints the job id. The committed Queued row is a durable start marker. The recovery task of the extension dispatches it again on a later tick, if scheduled-task:run operates.

--watch

With --watch, the command polls the job row every two seconds and updates a progress bar. After the job reaches a final status, the command prints a summary table with the columns Status, Processed, Failed, Skipped, Total, Characters and Cost:

text
 ----------- ----------- -------- --------- ------- ------------ -------------
  Status      Processed   Failed   Skipped   Total   Characters   Cost
 ----------- ----------- -------- --------- ------- ------------ -------------
  completed   1240        0        86        1326    412903       10.3226 USD
 ----------- ----------- -------- --------- ------- ------------ -------------

If the job recorded an error message, the command prints it as a warning below the table.

Exit codes: the command returns a failure exit code only when the final status is failed. A job that ends as completed_with_errors or cancelled still exits successfully. A build step that must react to individual record failures must therefore examine the job itself. --watch has no timeout. It waits until the job finishes, or until the job row disappears (The translation job no longer exists., failure exit code).

Examples

Fill the missing German and French translations for products and categories with DeepL, and stay attached to the run:

bash
bin/console nice-translate:run --entity=product --entity=category --to=de-DE --to=fr-FR --provider=deepl --watch

A nightly catch-up for everything that is still untranslated, into each language except the system language, with the configured default provider. --scope=missing keeps the job small, because it skips the records that are already complete:

bash
bin/console nice-translate:run --to=all --scope=missing

Translate all product copy from British English into German again with Anthropic Claude, and overwrite the existing German values. The hand-edited translations stay, because the manual-edit protection is on:

bash
bin/console nice-translate:run --entity=product --from=en-GB --to=de-DE --provider=anthropic --mode=all

Translate the storefront snippets into Dutch through modernice All-in-One. A snippet set must exist for the source locale and the target locale, and without them the extension skips the snippets:

bash
bin/console nice-translate:run --entity=snippet --to=nl-NL --provider=managed

Start a catch-up for imported categories inside a deployment script, and let the step fail when the job fails:

bash
bin/console nice-translate:run --entity=category --to=all --scope=missing --watch

nice-translate:providers

List translation providers and their configuration status.

bash
bin/console nice-translate:providers

The plain output is a table with one row for each registered provider, in registration order:

ColumnContent
IDThe provider id that you pass to --provider
ProviderThe provider label that the Administration shows
Configuredyes when a key is stored; for managed, yes means that the subscription is active
text
 ----------- ---------------------- ------------
  ID          Provider               Configured
 ----------- ---------------------- ------------
  deepl       DeepL                  yes
  google      Google Translate       no
  openai      OpenAI (ChatGPT)       no
  anthropic   Anthropic Claude       yes
  gemini      Google Gemini          no
  mistral     Mistral                no
  managed     modernice All-in-One   no
 ----------- ---------------------- ------------

The output also contains the custom providers that another plugin registers. See Custom providers.

--test

bash
bin/console nice-translate:providers --test

--test validates the stored credentials against the provider APIs and adds two columns:

ColumnValues
Credentialsvalid or invalid, each with and the message of the provider when there is one; skipped (not configured) for the providers without a key; error — <message> when the check itself threw
Quota<used> / <limit>, or <used> / unlimited when the provider reports no limit, or - when the provider exposes no quota

Only DeepL and modernice All-in-One report a quota. DeepL returns the characters used and the character limit of the key. The managed provider returns the used credits and the included credits. The extension validates Google Translate, OpenAI, Anthropic, Gemini and Mistral against their model or language listing endpoints, and those endpoints report no quota.

The command tests the keys that you already saved. The Test connection button in Settings → Providers tests the key that the field contains, saved or not.

Permissions and execution context

Console commands operate outside the Administration, in the system context of Shopware. The roles nice_translate.viewer and nice_translate.editor from Permissions (ACL) apply to the Administration and the Admin API. They do not restrict the CLI. Each person with shell access to the shop can create translation jobs.

WARNING

A CLI job has no Administration user as its creator. The Translation job finished Flow Builder trigger therefore carries no mail recipient for these jobs. A Send mail action must address a fixed recipient instead of the job creator. See Events & Flow Builder.

Jobs from the command line appear in Catalogues → AI Translation → Jobs like each other job. They have the same progress, the same error list, and the same Retry failed items and Revert all translations commands.

modernice extensions for Shopware 6. Shopware is a trademark of shopware AG — this documentation is not affiliated with shopware AG.