# New option: auto-select language by HTTP header

**URL:** https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697
**Category:** Feature
**Created:** [November 17, 2015, 2:34pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697 "2015-11-17T14:34:24Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 17, 2015, 2:34pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/1 "2015-11-17T14:34:24Z")

</div>

I’m running a private, international forum for a club where most content is German and some is mixed. Users can choose their preferred language in their user settings, but this is non-obvious for visitors (and doubly so for most of “my” visitors).

The website we are running selects the display language based on the HTTP `Accept-Language` header field. I’d like to see a new option where I can advise Discourse to auto-select the language based on the header field. Bonus points if users are able to override the automatic detection with their preferred language.  
Is this a viable option?

Thank you for your feedback!

---

<div class="post-metadata">

### Author: ![cpradio](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cpradio/32/4970_2.png) [@cpradio](https://meta.discourse.org/u/cpradio)
#### Post date: [November 17, 2015, 2:36pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/2 "2015-11-17T14:36:19Z")

</div>

This sort of exists.

> [@Variable default interface language for new users](https://meta.discourse.org/t/variable-default-interface-language-for-new-users/33741/14):
>
> I’ve made a plugin for this. [GitHub - scossar/accept-language: A Discourse plugin to set the language for non-logged-in users · GitHub](https://github.com/scossar/accept-language) The logic is that if the site is visited by a non-logged-in user and the site allows user-locales, the locale is set from the request headers. If there is a logged-in user the locale is set from the user’s effective locale. If there is no logged-in user and user locales are disabled, the locale is set from the site default locale. It uses the http\_accept\_langu…

---

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 17, 2015, 2:39pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/3 "2015-11-17T14:39:53Z")

</div>

Awesome! However, in our case, the forum requires a login and uses SSO auth (with the website), so users are always logged in but most do not have the language set by themselves. Is this use case possible with the addon?

---

<div class="post-metadata">

### Author: ![cpradio](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/cpradio/32/4970_2.png) [@cpradio](https://meta.discourse.org/u/cpradio)
#### Post date: [November 17, 2015, 2:41pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/4 "2015-11-17T14:41:52Z")

</div>

Not sure, but you might be able to utilize what the addon is doing to fork it to alter the language for your scenario.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 17, 2015, 8:05pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/5 "2015-11-17T20:05:11Z")

</div>

There is a similar request here: [https://meta.discourse.org/t/setting-user-locale-via-sso/35528](https://meta.discourse.org/t/setting-user-locale-via-sso/35528)

Would it work for you to have the signed-in user’s locale default to the locale from their HTTP headers, but also give them the option to set their locale for Discourse in their user preferences?

If so, it looks like this can be easily done. I have a working prototype for this now. The only downside that I can see for doing it this way is that until the user sets their language preferences with Discourse, the emails they get from the system will be in the forum’s default language.

Another option is to change how Discourse single-sign-on works so that it accepts a `locale` parameter and uses that to create the Discourse user from the SSO parameters.

---

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 17, 2015, 8:26pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/6 "2015-11-17T20:26:55Z")

</div>

Thanks for the link, I wanted to request that, too (however it will probably not help much in my case) …

> [@simon](#):
>
> Would it work for you to have the signed-in user’s locale default to the locale from their HTTP headers, but also give them the option to set their locale for Discourse in their user preferences?

Yes, that’s exactly what I need.

> [@simon](#):
>
> The only downside that I can see for doing it this way is that until the user sets their language preferences with Discourse, the emails they get from the system will be in the forum’s default language.

Huh. What about caching the last “known” language? This obviously needs to be a different field from the user preference.  
Or better yet, have a heuristic based on how often you access the forum with a specific language? That’s increasing complexity a lot, however a simple solution could be to store an array with “known” languages and a weighting (value between 0 and 1), which is updated every time a user logs in: increase weighting for the current language and decrease it for the other ones in the array … well, not _that_ simple.

Or just cache the language the HTTP header field contains and once the user visits with a different language, show a prompt saying something like “We are having trouble identifying your main language. Please choose your preferred language from the list below:” and let that update the user preference. Then we know for sure and the user is informed / will not be surprised if the language changes because he was on vacation for too long …

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 17, 2015, 9:16pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/7 "2015-11-17T21:16:16Z")

</div>

> [@fbender](#):
>
> What about caching the last “known” language?

Another option would be to update the user’s locale preference from their HTTP headers on login.

I think the best/simplest solution for doing this in a plugin is to ask the user to confirm their language preferences from the locale select input. If you are concerned that your users won’t be able to find that in their preferences, it could be added to the header for users who have not yet confirmed their language.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 18, 2015, 4:22am UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/8 "2015-11-18T04:22:17Z")

</div>

Actually, it looks like all system emails are sent in the forum’s default language (they use `config.locale`)

```rb

    # discourse/lib/freedom_patches/translate_accelerator.rb

    def translate(key, *args)
      load_locale(config.locale) unless @loaded_locales.include?(config.locale)
      return translate_no_cache(key, *args) if args.length > 0

      @cache ||= LruRedux::ThreadSafeCache.new(LRU_CACHE_SIZE)
      k = "#{key}#{config.locale}#{config.backend.object_id}"

      @cache.getset(k) do
        translate_no_cache(key).freeze
      end
    end
 

```

Other than dealing with that, this plugin should do close to what you are looking for.

The logic is that if the site-settings allow user locales:

- if there is no logged in user use the local from the accept-language headers
- if there is a logged in user and the user has selected their preferred language in the Discourse preferences, use that language
- if there is a logged in user and the user has not selected a preferred language, use the language from the accept-language header

[https://github.com/scossar/variable-language](https://github.com/scossar/variable-language)

---

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 18, 2015, 8:08am UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/9 "2015-11-18T08:08:31Z")

</div>

I’ll try that plugin and report back here, thanks a lot!

> [@simon](#):
>
> Actually, it looks like all system emails are sent in the forum’s default language (they use config.locale)

Uh-oh, that should be fixed to use the user’s preference if it was selected, @eviltrout .

---

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 19, 2015, 1:51pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/10 "2015-11-19T13:51:15Z")

</div>

I’m sorry but there is an error somewhere:

```plaintext
Started GET "/" for x.x.x.x at 2015-11-19 13:44:56 +0000
Processing by CategoriesController#index as HTML
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `ensure_all_loaded!' for I18n:Module)
/var/www/discourse/plugins/variable-language/plugin.rb:35:in `set_locale'

```

I added the plugin in the container configuration file:

```plaintext
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - mkdir -p plugins
          - git clone https://github.com/discourse/docker_manager.git
          - git clone https://github.com/scossar/variable-language.git

```

… and rebuilt the container. Afterwards, I received a 500 (see log above).

May you have a look at that, please?

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 19, 2015, 4:25pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/11 "2015-11-19T16:25:18Z")

</div>

I think you need to update your version of discourse. `ensure_all_loaded!` was recently added.

Here’s the main method that the plugin is overriding from `application_controller.rb`

```rb
  def set_locale
    I18n.locale = current_user.try(:effective_locale) || SiteSetting.default_locale
    I18n.ensure_all_loaded!
  end

```

---

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 19, 2015, 6:43pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/12 "2015-11-19T18:43:53Z")

</div>

I’m on 1.4.2. Was this added in 1.5?

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 19, 2015, 6:54pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/13 "2015-11-19T18:54:49Z")

</div>

Yes, before that it was using `I18n.fallbacks.ensure_loaded!`. If you can’t update to 1.5 you could probably get the plugin to work by changing its `set_locale` method to this:

```rb
    def set_locale
      if SiteSetting.allow_user_locale
        if !current_user
          I18n.locale = locale_from_http_header
        else
          if current_user.preferred_locale?
            I18n.locale = current_user.preferred_locale
          else
            I18n.locale = locale_from_http_header
          end
        end
      else
        I18n.locale = SiteSetting.default_locale
      end
      I18n.fallbacks.ensure_loaded!
    end

```

I haven’t tested this though.

---

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 20, 2015, 8:29am UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/14 "2015-11-20T08:29:31Z")

</div>

Thanks, I think I can wait until 1.5, hoping it will release around New Year.

On the other hand, would it be possible to make the plugin downwards-compatible by checking for the existance of `ensure_all_loaded` and falling back to `fallbacks.ensure_loaded` otherwise?

---

<div class="post-metadata">

### Author: ![gerhard](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/gerhard/32/119479_2.png) [@gerhard](https://meta.discourse.org/u/gerhard)
#### Post date: [November 20, 2015, 9:59am UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/15 "2015-11-20T09:59:20Z")

</div>

> [@fbender](#):
>
> Thanks, I think I can wait until 1.5, hoping it will release around New Year.

Don’t get your hopes up, unless you are celebrating New Year’s Day in March. 😉

> [@Discourse Version 1.5](https://meta.discourse.org/t/discourse-version-1-5/30609/1):
>
> Planned release date
> 
> early March, 2016

---

<div class="post-metadata">

### Author: ![Aymane\_Shuichi](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/aymane_shuichi/32/63024_2.png) [@Aymane\_Shuichi](https://meta.discourse.org/u/Aymane_Shuichi)
#### Post date: [November 20, 2015, 10:03am UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/16 "2015-11-20T10:03:53Z")

</div>

What about it , content wise ?  
I wouldn’t recommend a website layout in French when the content is Arabic. Which is very likely to happen.

---

<div class="post-metadata">

### Author: ![fbender](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fbender/32/116736_2.png) [@fbender](https://meta.discourse.org/u/fbender)
#### Post date: [November 21, 2015, 4:15pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/17 "2015-11-21T16:15:44Z")

</div>

That depends on what you want or how your community is structured. Especially when your community is private.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 21, 2015, 5:05pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/18 "2015-11-21T17:05:10Z")

</div>

It might not make sense for most discussion forums, but it makes sense for forums that are providing a service to clients who may speak different languages.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 21, 2015, 5:09pm UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/19 "2015-11-21T17:09:27Z")

</div>

> [@fbender](#):
>
> On the other hand, would it be possible to make the plugin downwards-compatible by checking for the existance of ensure\_all\_loaded and falling back to fallbacks.ensure\_loaded otherwise?

Sure, I’ll do that in the next couple of days. Also, I found a problem with the plugin where it is causing an error when the site is accessed without the accept-language headers being set. I’ll fix that too.

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [November 23, 2015, 2:38am UTC](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697/20 "2015-11-23T02:38:55Z")

</div>

I’ve updated this. I haven’t tested it on 1.4.2. Let me know if there are any problems. You may need to clear your browser cache to get a new locale from the headers.

There is an issue with the `login_required_welcome_message` being cached in the first locale that accesses it. I assume that’s not a problem if you are using SSO.

[Next page](https://meta.discourse.org/t/new-option-auto-select-language-by-http-header/35697.md?page=2)
