How do I set Jitsi caption languages and enable live translation?

Short answer

Set the speaker's recognition language separately from each reader's caption target. Docker stable-11248 exposes the main language lists through .env, but customLanguages needs custom-config.js. Jigasi needs translation enabled and a configured translator; a language dropdown alone does not provide translation. The reported one-way Google translation problem has no confirmed released fix as of 2026-10-06. [S2][S3][S5][S14]

Who this is for

Use this after captions work. Start with the Vosk guide or bridge guide for recognition, or our transcription service for setup help. [S17][S18]

How it works

Recognition converts speech into text. Translation converts that text into another language. Jitsi initializes the speaker’s recognition language from the application language when transcription.useAppLanguage is true. Otherwise it uses transcription.preferredLanguage, with en-US as the fallback for an unsupported selection. [S3]

Each reader selects a caption target under Translate to, or Original. The client publishes translation_language; the spoken language uses transcription_language. Jigasi translates final results into requested targets. Its Whisper adapter is an exception to clean separation: it prefers the participant’s translation target when constructing the recognition hint. [S3][S6][S17]

Language lists are UI choices, not installed models or access controls. Use full speech tags such as pl-PL for Jigasi Google recognition, and translator-supported target codes such as pl. [S3][S14][S17]

Before you start

Checked October 6, 2026: stable-11248, released September 14, remains Docker’s latest release. Steps target it and package Jigasi 1.1-415-g2750d54-1. Preserve authentication, recognition and existing overlays. Recreate outside active meetings. [S1][S4]

Frontend custom languages shipped through Meet PR #16984. Docker’s TRANSCRIPTION_CUSTOM_LANGUAGES change, PR #2234, merged September 22, after stable-11248. Its patch does not add Compose forwarding. Do not expect that variable in stock stable-11248. [S15]

Prepare a translation provider and supported source/target pairs. Google requires its API and billing; Microsoft requires a Translator resource. Confirm participant agreement before sending text to an external provider. [S10][S11]

Steps

  1. Docker stable-11248: configure the client. Put these assignments in .env. This example starts recognition in English and offers three caption targets. [S2]

    dotenv
    ENABLE_TRANSCRIPTIONS=1
    USE_APP_LANGUAGE=false
    PREFERRED_LANGUAGE=en-US
    TRANSLATION_LANGUAGES=['en','de','pl']
    TRANSLATION_LANGUAGES_HEAD=['en']
    JIGASI_TRANSCRIBER_ENABLE_TRANSLATION=1

    USE_APP_LANGUAGE=true initializes speech from the interface language. Settings > General > Language updates the live language, but sends bare codes such as pl; released Google recognition rejects these. Use a full spoken tag before joining, or the API property command below. [S3][S16][S17]

    Use your actual CONFIG; this example uses the handbook default. Add these optional custom speech entries only with matching backend models. [S3][S4]

    Terminal
    CONFIG="$HOME/.jitsi-meet-cfg"
    mkdir -p "${CONFIG}/web"
    cat >> "${CONFIG}/web/custom-config.js" <<'EOF'
    config.transcription.translationEnabled = true;
    config.transcription.customLanguages = {
        ...config.transcription.customLanguages,
        'hsb-DE': 'Upper Sorbian (Germany)',
        'dsb-DE': 'Lower Sorbian (Germany)'
    };
    EOF
    sudo chown 1000:1000 "${CONFIG}/web/custom-config.js"
    sudo chmod 644 "${CONFIG}/web/custom-config.js"

    Preserve existing custom entries. Startup appends this file after generated config.js; rootless web reads it as UID 1000. [S4]

  2. Docker stable-11248: choose one translator. Set its class in .env, preserving your speech service. [S5][S6]

    Google: [S7][S10]

    dotenv
    JIGASI_TRANSCRIBER_CUSTOM_TRANSLATION_SERVICE=org.jitsi.jigasi.transcription.GoogleCloudTranslationService
    GOOGLE_APPLICATION_CREDENTIALS=/run/jigasi/config/google-key.json

    Enable Cloud Translation API and billing. Save private ADC JSON at the chosen filename ${CONFIG}/transcriber/google-key.json; startup copies it. Run sudo chown 1000:1000 "${CONFIG}/transcriber/google-key.json" and sudo chmod 600 "${CONFIG}/transcriber/google-key.json". Do not commit it. [S4][S7][S10]

    Stock transcriber.yml does not forward GOOGLE_APPLICATION_CREDENTIALS. Create this guide-specific overlay, language.yml, and include it in subsequent Compose commands: [S4][S5]

    YAML
    services:
      transcriber:
        environment:
          - GOOGLE_APPLICATION_CREDENTIALS

    Microsoft Translator: its Java implementation shipped through Jigasi PR #636. Docker PR #2251 closed without merging, so use the existing custom-service variable and properties. [S8]

    dotenv
    JIGASI_TRANSCRIBER_CUSTOM_TRANSLATION_SERVICE=org.jitsi.jigasi.transcription.BingTranslationService

    Append these to ${CONFIG}/transcriber/custom-sip-communicator.properties, replacing placeholders with your resource’s key and region. Run sudo chown 1000:1000 "${CONFIG}/transcriber/custom-sip-communicator.properties" and sudo chmod 600 "${CONFIG}/transcriber/custom-sip-communicator.properties". [S4][S8][S11]

    Properties
    org.jitsi.jigasi.transcription.bing.subscription_key=REPLACE_WITH_TRANSLATOR_KEY
    org.jitsi.jigasi.transcription.bing.subscription_region=REPLACE_WITH_RESOURCE_REGION

    LibreTranslate: [S9]

    dotenv
    JIGASI_TRANSCRIBER_CUSTOM_TRANSLATION_SERVICE=org.jitsi.jigasi.transcription.LibreTranslateTranslationService
    JIGASI_TRANSCRIBER_LIBRETRANSLATE_URL=http://libretranslate:5000/translate

    This private language.yml adaptation publishes no host port. The base Compose file supplies the network; LibreTranslate loads the selected models. [S5][S12]

    YAML
    services:
      libretranslate:
        image: libretranslate/libretranslate:v1.9.6
        environment:
          LT_LOAD_ONLY: en,de,pl
        networks:
          - meet.jitsi

    Jigasi sends an empty api_key. A key-required endpoint cannot work unchanged; use a private endpoint accepting keyless requests or modify the adapter. [S9]

  3. Docker stable-11248: apply the selected setup. For Google or the LibreTranslate example, include language.yml; otherwise omit that extra file. Include your other existing overlays too. [S4][S5]

    Terminal
    docker compose -f docker-compose.yml -f transcriber.yml -f language.yml up -d
    docker compose -f docker-compose.yml -f transcriber.yml -f language.yml up -d --force-recreate web transcriber

    Reload and join a fresh meeting. [S3][S4]

  4. Debian/Ubuntu packages, Meet 11248 and Jigasi 1.1-415: edit /etc/jitsi/meet/meet.example.com-config.js. Use the same frontend properties directly, without Docker environment variables: [S3][S13]

    JavaScript
    config.transcription = {
        ...config.transcription,
        enabled: true,
        translationEnabled: true,
        useAppLanguage: false,
        preferredLanguage: 'en-US',
        translationLanguages: ['en', 'de', 'pl'],
        translationLanguagesHead: ['en']
    };

    Add customLanguages inside that object only for a capable backend. In /etc/jitsi/jigasi/sip-communicator.properties, enable translation and select one class from step 2: [S6][S13]

    Properties
    org.jitsi.jigasi.transcription.ENABLE_TRANSLATION=true
    org.jitsi.jigasi.transcription.translationService=org.jitsi.jigasi.transcription.GoogleCloudTranslationService

    For Microsoft, add the same bing properties; for LibreTranslate, set org.jitsi.jigasi.transcription.libreTranslate.api_url to your reachable endpoint. For Google, place GOOGLE_APPLICATION_CREDENTIALS=/etc/jitsi/jigasi/google-key.json in /etc/jitsi/jigasi/config; the JSON filename is chosen here. Protect the saved JSON, then restart: [S7][S8][S9][S10][S13]

    Terminal
    sudo chown jigasi:jigasi /etc/jitsi/jigasi/google-key.json
    sudo chmod 600 /etc/jitsi/jigasi/google-key.json
    sudo systemctl restart jigasi

    Other translators need only the restart command. [S13]

  5. Bridge proxy source 6747f187, either installation: configure its own text translator. This Google example belongs in the proxy environment, with the key replaced locally: [S18]

    dotenv
    ENABLE_TEXT_TRANSLATION=true
    TEXT_TRANSLATION_PROVIDERS_PRIORITY=google
    TEXT_TRANSLATION_GOOGLE_API_KEY=REPLACE_WITH_GOOGLE_TRANSLATION_API_KEY

    Docker: forward these three variables in the proxy’s environment list and recreate it. Packages: update the proxy’s dedicated environment file and recreate its container, following the bridge guide. Other text providers are OpenAI, Gemini and xAI. Translation processes finals, separately from translated audio. [S18]

Configuration reference

Client names below are inside config.transcription. Docker defaults apply to stock stable-11248; package defaults may differ from its generated values. [S2][S3]

Name, Docker mapping Location Default Purpose
CONFIG Docker .env ~/.jitsi-meet-cfg Host configuration folder. [S4]
enabled, ENABLE_TRANSCRIPTIONS Client, .env false Enable feature; Docker also sets disableClosedCaptions to its inverse. [S2]
useAppLanguage, USE_APP_LANGUAGE Client, .env true Initialize speech from app language. [S2][S3]
preferredLanguage, PREFERRED_LANGUAGE Client, .env en-US Initial speech when app-language mode is false. [S2][S3]
translationEnabled Client custom config true Show translation selection UI. [S3]
translationLanguages, TRANSLATION_LANGUAGES Client, .env Docker [] Caption target list. [S2]
translationLanguagesHead, TRANSLATION_LANGUAGES_HEAD Client, .env ['en'] Targets listed first; stock Docker offers English. [S2][S3]
customLanguages, TRANSCRIPTION_CUSTOM_LANGUAGES Client custom config {} Additional accepted speech tags; Docker shortcut unreleased. [S3][S15]
autoTranscribeOnRecord Client custom config false Start transcription with recording. [S3]
autoCaptionOnTranscribe Client custom config false Display captions when transcription starts. [S3]
renderTranscriptDetails, diarize Client custom config false Transcript details and requested diarization; backend-dependent. [S3]
disableStartForAll, DISABLE_START_FOR_ALL Client, .env false Historical nested option emitted by Docker. [S2]
autoCaptionOnRecord, AUTO_CAPTION_ON_RECORD Client, .env false Historical nested option; not modern autoTranscribeOnRecord. [S2][S16]
JIGASI_TRANSCRIBER_ENABLE_TRANSLATION .env 0 Maps to org.jitsi.jigasi.transcription.ENABLE_TRANSLATION, default false. [S5][S6]
JIGASI_TRANSCRIBER_CUSTOM_TRANSLATION_SERVICE .env Unset Maps to org.jitsi.jigasi.transcription.translationService; fallback Google. [S5][S6]
JIGASI_TRANSCRIBER_LIBRETRANSLATE_URL .env Unset Maps to org.jitsi.jigasi.transcription.libreTranslate.api_url; adapter default http://libretranslate:5000/translate. [S5][S9]
org.jitsi.jigasi.transcription.bing.subscription_key, org.jitsi.jigasi.transcription.bing.subscription_region Jigasi properties Empty Microsoft credentials. [S8]
GOOGLE_APPLICATION_CREDENTIALS Process environment Docker /run/jigasi/config/key.json Google ADC JSON path. [S4][S10]
LT_LOAD_ONLY LibreTranslate environment Unset Load selected translation models. [S12]
ENABLE_TEXT_TRANSLATION Bridge proxy environment false Enable caption text translation. [S18]
TEXT_TRANSLATION_PROVIDERS_PRIORITY Bridge proxy environment openai,gemini,xai,google Provider selection order. [S18]
TEXT_TRANSLATION_GOOGLE_API_KEY Bridge proxy environment Unset Google translation credential. [S18]
transcription_language, translation_language Participant properties Initialized speech tag, no target Speech locale and caption target respectively. [S3][S16]

Common mistakes

Only one translation direction works. Issue #635 reports Meet 2.0.10888-1 and Jigasi 1.1.407-g1e3a7ac, with Google recognition and translation. Its exact reported error is: [S14]

Text
UnsupportedOperationException: pl is not a language supported
by the Google Cloud speech-to-text API

The target/STT mix-up is unconfirmed. Released Google recognition rejects bare pl; use pl-PL for speech and inspect participant properties. PR #640 changes recognition locale resolution and remains open. No complete workaround is confirmed; #635 is not fixed as of 2026-10-06. [S14][S17]

Runtime overrides do not update speech language. #16172 was auto-closed without a fix. Initial configOverwrite or URL overrides apply before conference creation; runtime overwriteConfig does not reapply speech language. These fresh-join URLs set English or Polish for that participant, not the whole room: [S3][S16]

Text
https://meet.example.com/language-test#config.transcription.useAppLanguage=false&config.transcription.preferredLanguage=%22en-US%22
https://meet.example.com/language-test#config.transcription.useAppLanguage=false&config.transcription.preferredLanguage=%22pl-PL%22

An embedded app can write the participant property directly. This is source-confirmed, not meeting-tested: [S16]

JavaScript
api.executeCommand('setParticipantProperties', {
    transcription_language: 'de-DE'
});

More choices, same model. Vosk supports loaded models, with per-language routing available through Jigasi. Whisper needs a multilingual model, not .en. Google’s Jigasi adapter has its own accepted-tag list. Bridge support depends on the provider and model; Deepgram’s default Nova-2 multilingual mode covers English and Spanish. [S17][S18]

Verify

For both installations, inspect the served configuration rather than only the host file: [S2][S4][S13]

Terminal
curl -fsS https://meet.example.com/config.js

Expect useAppLanguage: false,, preferredLanguage: 'en-US', and translationLanguages: ['en','de','pl'], for Docker. This proves delivery, not recognition. Refresh and bypass CDN caching. [S2][S4]

Test English and Polish speakers using the fresh-join URLs above. Require translated final captions in both directions, then check Original. This is your acceptance test; no successful meeting was observed for this guide. [S3][S6][S14][S16]

If it still fails

For Docker, run docker compose -f docker-compose.yml -f transcriber.yml logs --tail=200 transcriber, adding your overlays. Packages write /var/log/jitsi/jigasi.log; use sudo journalctl -u jigasi -n 200 --no-pager for service failures. Look for Cannot instantiate custom translation service, which causes fallback to Google, and the exact unsupported-language error above. [S6][S13][S14]

Check provider authentication, enabled APIs, target language support and network access separately from speech recognition. Use the existing transcription troubleshooting page when original captions also fail. [S7][S8][S9][S10][S11]

FAQ

Does changing the Jitsi interface language change captions?

With useAppLanguage=true, it initializes speech language from that interface language. The web settings also update spoken language during a conference; each reader’s translation target is a separate choice. [S3]

Can I add any language with customLanguages?

It extends accepted speech tags, not the interface-language dropdown or installed models. Use a capable backend. [S3][S17]

Can I translate without Google?

Yes. Released Jigasi includes Microsoft and LibreTranslate adapters. Bridge caption translation uses its own providers and configuration. [S8][S9][S18]

Is the one-way Polish translation issue fixed?

No confirmed released fix was found as of October 6, 2026. #635 and PR #640 remain open; testing full speech locale tags is diagnostic guidance, not a guaranteed solution. [S14]

Sources

[S1] Docker latest release, September 14, 2026, release note; stable package index, checked October 6, 2026, official repository.

[S2] Docker web settings, Compose forwarding, September 14, 2026, source code.

[S3] Meet configuration, language selection, settings update, caption picker, SDK language property, September 2026, source code.

[S4] Docker handbook, checked October 6, 2026, official doc; web startup, Jigasi startup, image credentials default, September 14, 2026, source code.

[S5] Transcriber template, transcriber Compose, September 14, 2026, source code.

[S6] Jigasi translator selection, final-result translation, September 11, 2026, source code.

[S7] Google translator, September 11, 2026, source code.

[S8] Microsoft translator, source code; Jigasi PR #636, May 8, 2026, official repository PR; Docker PR #2251, August 17, 2026, unmerged repository PR.

[S9] LibreTranslate adapter, September 11, 2026, source code.

[S10] Google translation setup, ADC lookup, checked October 6, 2026, official docs.

[S11] Microsoft Translator authentication, checked October 6, 2026, official doc.

[S12] LibreTranslate v1.9.6 Compose example, published image, defaults, May 2026, source code and official registry.

[S13] Jitsi package quickstart, official doc, checked October 6, 2026; Jigasi service, sample properties, September 11, 2026, source code.

[S14] One-way translation #635, April 20, 2026, community report; PR #640 and maintainer discussion, June 1, 2026, proposed source change and maintainer comments; statuses checked October 6, 2026.

[S15] Meet custom-language PR #16984, February 25, 2026; request #16856, closed March 26, 2026; Docker PR #2234, merged September 22, 2026, official repository changes and maintainer comments.

[S16] Runtime override #16172, June 2025, community report, auto-closed November 7, 2025; reducer, initialization, API, initial URL config, parser, whitelist, September 2026, source code.

[S17] Vosk models, Whisper models, official docs; Google validation, Vosk routing, Whisper hint, September 11, 2026, source code.

[S18] Proxy configuration, final-caption translation, October 5, 2026; Jicofo caption requests, September 2026, source code; Deepgram languages, checked October 6, 2026, official doc.

Open questions

No real multilingual meeting or provider credentials were tested for this guide. The complete cause and a reliable workaround for #635 remain unconfirmed. Per-speaker frontend language selection reaching bridge recognition needs testing; the proxy’s connection-level language option does not prove that propagation. Test Jigasi Whisper with differing spoken and caption languages before relying on that combination. [S14][S17][S18]

Recently updated