Variable default interface language for new users

Just merged both PRs. Thanks @simon :+1:


I just refined this a bit:

This gem was injecting extra middleware and adding stuff on our application controller. I changed it so it has no impact for users not using the feature.


Seems that not all of @simon’s code gets merged into core.

For example, the current:

where effective_locale is:

is missing certain features from @simon’s original plugin code:

In particular, this part:

elsif SiteSetting.accept_language_overrides_default_locale
I18n.locale = locale_from_http_header

So, in other words, a logged in user does not get this auto-language-detection benefit.

@simon’s plugin has not been updated for 2 years and I’m not sure how well it works with the current Discourse version… otherwise it would be perfect.

1 Like

That’s intentional. If ‘allow user locale’ is also enabled, the user’s locale will be set when they register, so it will be set from the accept language header.

Are you sure? Because I’ve seen ALL my users’ interface language being default. Only a few of them knew to change it in profile.

And they all came from invites, not public registration. I’m pretty sure it only asked for:

  1. username
  2. nickname
  3. password

when they first sign on.

Yes, it should work that way when both ‘allow user locale’ and ‘set locale from accept language header’ are enabled. I just tested it with my browser’s preferred language set to french, and it created a user with their preferred locale set to french.

That will be the problem.

1 Like

Yes, the invite sign-on form seems to be different from the public sign-up…

This is the invite sign-on when creating a user:

Language is not specified.

The locale isn’t on the signup form. I haven’t looked at the code for a while, but from what I remember, it’s set from the locale. This means that if the locale has been set from the header, that locale will be set for the user.

Yes, but effective_locale has nothing to do with the accept-language header. Evident from this code:

Sorry, I edited my post. It’s set from the locale, which is set from the header.

Nope. I don’t think so. At least not for invite.redeem.

Check this:

Maybe for new user sign-up.

This is also incorrect. I18n.locale is set from the header only if there is no logged in user. See here:

Now, I suspect that when the user first signs up, current_user is not set, thus kick-starting the whole get-the-language-from-header process, and then the I18n.locale got persisted into the user’s account.

However, this is certain NOT how it is done when a user redeems an invite.

1 Like

Yes, if you look at users_controller you can see how it’s done differently.


Yup. I see it.

UsersController inherits from ApplicationController, which runs set_locale as a before_action.

That kick-starts the whole thing.

But users redeeming an invitation does not go through this.


Judging from this here:

Would this work:

      user = invite.redeem(username: params[:username], name: params[:name], password: params[:password], user_custom_fields: params[:user_custom_fields])
      if user.present?
        user.locale = I18n.locale!


Sorry for my Ruby – I don’t really know it. :sweat_smile:

1 Like

As of this commit from @david, this should work cleanly now :tada:

1 Like

Thank guys so much.
But…there’s another problem for me.:pensive:
I don’t knew how to use this😣

To allow the locale to be set for anonymous (non-logged in) users based on their browser’s language settings, you need to enable both the allow user locale and set locale from accept language header site settings. Both of those settings are found near the top of your site’s “Basic Setup” settings page.

Once those settings are enabled, users who are not logged into the site will have the Discourse user interface automatically set to the preferred language they have set in their browser. If a non-logged-in user decides to create an account on the site, their locale will be automatically set to the locale that is set by their browser. Note that this will only work if their locale is set to a language that Discourse has been translated into.

The set locale from accept language header setting has no effect on users who have already created accounts on the site. Once an account has been created, the Discourse user interface will be displayed in the locale that is set on the user’s preferences page. As long as the allow user locale setting is enabled, existing users can update their locale here:

The set locale from accept language header needs to have a #howto topic written for it. I’m setting myself a reminder for that and will get the topic written soon.


Quick question on this in relation to the translator plugin. Will the translator plugin work in this scenario if the plugin translation restriction is set to Everyone?
(given that the different locale is the thing that triggers the translation button to show up in the first place)

Just an FYI, I don’t think the ‘Everyone’ group works properly with that Translator setting. It’s also not available to anons, so setting it to TL0 is the recommended group for that.

1 Like