Discourse Translator

:discourse2: Summary Discourse Translator translates posts on Discourse using Microsoft, Google, or Yandex translation APIs.
:hammer_and_wrench: Repository Link https://github.com/discourse/discourse-translator
:open_book: Install Guide How to install plugins in Discourse

Features

  • Each post is only translated once per locale which saves you :moneybag:
    • Note that language detection is also run once for every post. Be careful when enabling this on old and large forums.
  • Access Token is cached server side for faster translations.
  • Translations are rate limited to 3 per minute by default (admins can configure this value)

Translation Services Supported

Configuration Steps

Microsoft
  1. Follow the steps in Microsoft Translator API on Azure to obtain a subscription key. You may pick from any of the available subscription offers.

  2. In your Discourse, under Admin > Settings > Plugins, enter the subscription key that you’ve obtained from the steps above.

  1. In your Discourse, under Admin > Settings > Basic Setup, enable allow user locale.
Google Translator
  1. Go to https://console.developers.google.com

  2. Click on My Project

  1. Click on the :heavy_plus_sign: to create a new project

  1. Enter your project name and click create

  2. Select Enable API and search for Google Cloud Translator API. Look for the enable button and click it to enable the API. Note that there is no free tier for the Google Translator API so it may prompt you to enable billing.

  3. Once you’re done, click on credentials in the left menu

  1. Click create credentials and select API key. Copy the API Key and paste it into the translator google api key site setting in Discourse.

  2. In Discourse, under Admin > Settings > Basic Setup, enable allow user locale.

Settings

Name Description
translator enabled Allow inline translation of posts.
translator The provider of the translation service.
translator azure subscription key Azure Subscription Key
translator azure region Azure Region
translator azure custom subdomain Required if using a Virtual Network or Firewall for Azure Cognitive Services. Note: Only enter the custom subdomain not the full custom endpoint.
translator aws region AWS Region
translator aws key id AWS Key ID
translator aws secret access AWS secret access key
translator aws iam role AWS IAM Role
translator google api key Google API Key
translator yandex api key Yandex API Key
translator libretranslate endpoint LibreTranslate Endpoint
translator libretranslate api key LibreTranslate API Key
max translations per minute The number of translations per minute a regular user can perform.
restrict translation by group Only allowlisted groups can translate
restrict translation by poster group Only allow translation of posts made by allowlisted users

Known Issues

  • Does not translate text within polls generated by discourse-poll plugin.
  • Images are enlarged upon translating.

:discourse2: Hosted by us? This plugin is available on our Enterprise plan.

Last edited by @nat 2026-08-18T10:38:55Z

Check documentPerform check on document:
104개의 좋아요
Advice for bilingual communities
Inline translation of posts into another language
Language Translation
Can we have have one post with two different language
Plugin for signatures?
Translate plugin installed, but no translate button
LibreTranslate Plugin -- Free and Open Source Translation API
Discourse Translator plugin is not showing for non-logged in users
DeepL integration for Translator plugin
What exactly are the effects of "allow user locale"
Moving up the translator icon
How do I get the forum here in German
How do you use Discourse AI? Tell us and make it even better!
Is Google translate really so expensive?
Anyone migrated to version 3 of Microsoft Translator API yet?
Localized email templates
Image zoom is not working
Anyone Using Discourse Translator Plugin on small forum, Cost/month?
Mute ALL other languages
Make a multi-language forum
FYI, Full translation of Discourse including posts is possible
How to handle users that don't really read the answers they get?
Translating text in polls
How to install a plugin on Discourse-hosted-Discourse?
Yandex Translation Service
Using Discourse and LibreTranslate without AI
Include translated posts in search?
Translate email notifications and digests into user preferred locale language
What exactly are the effects of "allow user locale"
Google Translate shows "blank" page
Changing default language will not change the site TITLE or DESCRIPTION!
Translate email notifications and digests into user preferred locale language
Translation from Lugandan yields uncaught 500 error (in a different Discourse)
Getting user profile custom field via JS
No errors, instance not coming back up after rebuild
Javascript pop up block help
Help which plugin is in the screenshot
Simple idea for translator-assisted bilingual forum
MKJ's Opinionated Discourse Deployment Configuration
Yandex Translation Service
Translates to user's local language
Übersetzung wie hier auf Meta
DeepL integration for Translator plugin
DeepL support for Discourse Translator
Virtual Keyboard hides critical editor buttons for 3.3.0-beta
Virtual Keyboard hides critical editor buttons for 3.3.0-beta
Is Automatic Translation for Most Content Now Official?
Everything is translated, help!
Translation support about the topic content
Translates to user's local language
Structuring a multilingual community
Implementing In-House Translation Features on Discourse

A post was split to a new topic: I’m looking for such a solution to use a LLM to translate my forum’s top posts

A post was split to a new topic: Adding an option for a separate configuration for the language detection service

A post was split to a new topic: Are forums hosted by Discourse using a local instance of LibreTranslate?

I’m using LibreTranslate self-hosted which has worked well in the past, but I’m now getting a lot of repeated “Job exception: The translator service is currently not available” errors. I’ve checked the URL which has been working OK in the past. If I access the URL then the LibreTranslate web page displays. There’s no API/token required because my LibreTranslate instance is private with no access from the Internet.

The backtrace shows:

Message (548 copies reported)

Job exception: The translator service is currently not available.

Backtrace

/var/www/discourse/plugins/discourse-translator/services/discourse_translator/libretranslate.rb:168:in `result'
/var/www/discourse/plugins/discourse-translator/services/discourse_translator/libretranslate.rb:85:in `detect'
/var/www/discourse/plugins/discourse-translator/plugin.rb:120:in `block in execute'
/var/www/discourse/lib/distributed_mutex.rb:53:in `block in synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:49:in `synchronize'
/var/www/discourse/lib/distributed_mutex.rb:34:in `synchronize'
/var/www/discourse/plugins/discourse-translator/plugin.rb:119:in `execute'
/var/www/discourse/app/jobs/base.rb:305:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.0.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.0.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
/var/www/discourse/app/jobs/base.rb:292:in `block in perform'
/var/www/discourse/app/jobs/base.rb:288:in `each'
/var/www/discourse/app/jobs/base.rb:288:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:202:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:170:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:177:in `block in invoke'
/var/www/discourse/lib/sidekiq/pausable.rb:132:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:179:in `block in invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:182:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:169:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:113:in `local'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq.rb:44:in `block in <module:Sidekiq>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:263:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:13:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_retry.rb:80:in `global'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:124:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/job_logger.rb:39:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:123:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:168:in `process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:78:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/processor.rb:68:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:8:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-6.5.12/lib/sidekiq/component.rb:17:in `block in safe_thread'

Any thoughts on how I can fix this?

2개의 좋아요

‘Hindi’ locale option isn’t available in ‘Discourse’ yet. But ‘Hindi’ translation is available by different services (I’m using ‘Microsoft Azure’).

Then how can we setup to translate all/any non-Hindi post into ‘Hindi’ even when discourse interface continues to be in English? Is this even possible?

1개의 좋아요

Trying cross-posting this question to their discourse forum as well.

3개의 좋아요

저희 포럼에 이 번역기를 추가하는 것에 대해 생각 중입니다. 하지만 두 가지 주요 우려 사항이 있습니다:

1. 번역을 수정할 수 있나요?
특정 용어가 일관되게 번역되도록 보장해야 합니다. 이를 위해 사용 가능한 번역을 확인하고 필요 시 수정할 수 있는 기능이 필요합니다.

2. 게시물이 '재번역’되는 시점은 언제인가요?
일부 포럼 게시물은 자주 수정됩니다. 오탈자 수정이 과도한 번역 비용으로 이어지지 않도록 어떻게 보장할 수 있을까요? 또한, 새로운 변경 사항이 번역에 정확히 반영되도록 어떻게 확인할 수 있을까요?

3개의 좋아요

벤더(Microsoft/Google) 수준에서 수정해야 하므로 가능하지 않을 것 같습니다. 단, 번역된 내용이 단어 치환 기능의 대상이라면 해당 기능을 사용할 수 있습니다.

다만 다음과 같은 기능 요청을 드립니다:

  1. 첫 번째 게시글이 다른 언어로 작성된 경우 영어로 자동 번역합니다.
  2. 전체 스레드를 한 번에 번역할 수 있는 버튼을 제공합니다.
  3. 사용자 수준에서 전체 포럼에 대한 자동 번역 기능을 활성화합니다. 즉, 사용자가 프로필에서 루마니아어만 사용한다고 설정하면 모든 콘텐츠가 루마니아어로 번역됩니다. 여러 언어를 사용한다고 설정한 경우, 해당 언어가 아닌 게시글만 번역됩니다.
2개의 좋아요

사이트 관리자로서 이 글을 보고 놀랐습니다:

이 숨겨진 설정은 어디에 있나요? :smiling_face_with_sunglasses:

1개의 좋아요
./launcher enter app
rails c
SiteSetting.automatic_translation_backfill_rate = <원하는 값>
exit
exit

하지만 더 최신 버전에서는 더 이상 존재하지 않는 것 같습니다.

2개의 좋아요

이런 것들은 어떻게 배우나요? :sweat_smile: 네, 감사합니다! 확실하도록 팀의 답변을 기다리겠습니다.

1개의 좋아요

두 가지 방법: 검색과 ask.discourse.com를 사용하는 것입니다

3개의 좋아요
3개의 좋아요

제목이 번역된 주제의 알림이 알림 바에서 번역되지 않는 것으로 보입니다:

1개의 좋아요

또한 내 게시물이 링크를 통해 잘못된 언어로 번역되었습니다.


편집기에서 확인해보니, 실제로 제가 작성한 내용은 다음과 같습니다:

번역할 때 원박스(oneboxing)도 작동하지 않는 것을 확인했습니다.

1개의 좋아요

스크린샷에 있는 알림은 게시물의 주제 제목 원문이 사용되었으므로, 현재로서는 “올바른” 상태입니다. 향후 알림(주제 제목)이 번역되도록 조치할 예정입니다.

위 게시물에 대해서는 기계 번역이 오류를 일으켜 "스페인어(es)"로 잘못 감지되었고, 이후에도 번역 품질이 좋지 않았습니다. 현재는 수정이 완료되었습니다. 더 나은 프롬프트를 사용하여 번역 과정을 개선하고 있습니다.

2개의 좋아요

discourse-translator 플러그인을 설치할 때 이 오류가 발생했습니다. 제 discourse 버전은 3.5.0.beta1입니다.

I, [2025-04-24T01:33:20.510994 #1]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
        82: from /usr/local/bin/bundle:25:in `<main>'
        81: from /usr/local/bin/bundle:25:in `load'
        80: from /usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.5.18/exe/bundle:20:in `<top (required)>'
     ....
        10: from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/lazy_load_hooks.rb:87:in `with_execution_control'
        9: from /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/activesupport-7.2.2.1/lib/active_support/lazy_load_hooks.rb:94:in `block in execute_hook'
        8: from /var/www/discourse/config/application.rb:249:in `block in <class:Application>'
        7: from /var/www/discourse/lib/plugin.rb:6:in `initialization_guard'
        6: from /var/www/discourse/config/application.rb:249:in `block (2 levels) in <class:Application>'
        5: from /var/www/discourse/config/application.rb:249:in `each'
        4: from /var/www/discourse/lib/plugin/instance.rb:629:in `notify_after_initialize'
        3: from /var/www/discourse/lib/plugin/instance.rb:629:in `each'
        2: from /var/www/discourse/lib/plugin/instance.rb:631:in `block in notify_after_initialize'
        1: from /var/www/discourse/plugins/discourse-translator/plugin.rb:40:in `block in activate!'
/var/www/discourse/plugins/discourse-translator/lib/discourse_translator/inline_translation.rb:86:in `inject': protected method `register_topic_preloader_associations' called for an instance of Plugin::Instance (NoMethodError)

이 문제를 어떻게 수정할 수 있을까요?

1개의 좋아요

안녕하세요, 플러그인을 설치하기 전에 먼저 Discourse를 업데이트하면 이 오류를 완화할 수 있습니다.

register_topic_preloader_associations 메서드가 protected에서 public으로 변경되었습니다.

4개의 좋아요

감사합니다. Discourse를 최신 버전으로 업그레이드한 후에 성공적으로 설치했습니다.

2개의 좋아요