diff --git a/app/assets/javascripts/discourse/controllers/preferences_controller.js b/app/assets/javascripts/discourse/controllers/preferences_controller.js
index f34439265..18d87d9b3 100644
--- a/app/assets/javascripts/discourse/controllers/preferences_controller.js
+++ b/app/assets/javascripts/discourse/controllers/preferences_controller.js
@@ -30,6 +30,12 @@ Discourse.PreferencesController = Discourse.ObjectController.extend({
     return Discourse.SiteSettings.enable_names;
   }.property(),
 
+  availableLocales: function() {
+    return Discourse.SiteSettings.available_locales.split('|').map( function(s) {
+      return {name: s, value: s};
+    });
+  }.property(),
+
   digestFrequencies: [{ name: I18n.t('user.email_digests.daily'), value: 1 },
                       { name: I18n.t('user.email_digests.weekly'), value: 7 },
                       { name: I18n.t('user.email_digests.bi_weekly'), value: 14 }],
diff --git a/app/assets/javascripts/discourse/models/user.js b/app/assets/javascripts/discourse/models/user.js
index b17e8c62a..56df28465 100644
--- a/app/assets/javascripts/discourse/models/user.js
+++ b/app/assets/javascripts/discourse/models/user.js
@@ -170,6 +170,7 @@ Discourse.User = Discourse.Model.extend({
                                'bio_raw',
                                'website',
                                'name',
+                               'locale',
                                'email_digests',
                                'email_direct',
                                'email_always',
diff --git a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars
index b65bbd149..4a0560aa0 100644
--- a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars
@@ -66,6 +66,16 @@
       </div>
     </div>
 
+    <div class="control-group">
+      <label class="control-label">{{i18n user.locale.title}}</label>
+      <div class="controls">
+        {{combobox valueAttribute="value" content=availableLocales value=locale none="user.locale.default"}}
+      </div>
+      <div class='instructions'>
+        {{i18n user.locale.instructions}}
+      </div>
+    </div>
+
     <div class="control-group">
       <label class="control-label">{{i18n user.bio}}</label>
       <div class="controls">
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 091cac085..79d3d48aa 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -109,7 +109,11 @@ class ApplicationController < ActionController::Base
   end
 
   def set_locale
-    I18n.locale = SiteSetting.default_locale
+    I18n.locale = if current_user && current_user.locale.present?
+                    current_user.locale
+                  else
+                    SiteSetting.default_locale
+                  end
   end
 
   def store_preloaded(key, json)
diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb
index 25b92d0ed..8365c3bf6 100644
--- a/app/models/site_setting.rb
+++ b/app/models/site_setting.rb
@@ -23,6 +23,11 @@ class SiteSetting < ActiveRecord::Base
     load_settings(file)
   end
 
+  SiteSettingExtension.class_variable_get(:@@client_settings) << :available_locales
+
+  def self.available_locales
+    LocaleSiteSetting.values.map{ |e| e[:value] }.join('|')
+  end
 
   def self.call_discourse_hub?
     self.enforce_global_nicknames? && self.discourse_org_access_key.present?
diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb
index 7d93ffee7..4b55a2fd9 100644
--- a/app/serializers/user_serializer.rb
+++ b/app/serializers/user_serializer.rb
@@ -47,6 +47,7 @@ class UserSerializer < BasicUserSerializer
   end
 
   private_attributes :email,
+                     :locale,
                      :email_digests,
                      :email_private_messages,
                      :email_direct,
diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb
index ade9dd64c..025f0b376 100644
--- a/app/services/user_updater.rb
+++ b/app/services/user_updater.rb
@@ -27,6 +27,7 @@ class UserUpdater
 
     user.bio_raw = attributes.fetch(:bio_raw) { user.bio_raw }
     user.name = attributes.fetch(:name) { user.name }
+    user.locale = attributes.fetch(:locale) { user.locale }
     user.digest_after_days = attributes.fetch(:digest_after_days) { user.digest_after_days }
 
     if attributes[:auto_track_topics_after_msecs]
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index db9f1095f..dd209023b 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -325,6 +325,11 @@ en:
         enter_email: 'Username found. Enter matching email.'
         prefilled: "Email matches this registered username."
 
+      locale:
+        title: "Interface language"
+        instructions: "The language used by the forum interface. It will change when you refresh the page."
+        default: "(default)"
+
       password_confirmation:
         title: "Password Again"
 
diff --git a/config/locales/client.fr.yml b/config/locales/client.fr.yml
index 3e277d146..af5196b5a 100644
--- a/config/locales/client.fr.yml
+++ b/config/locales/client.fr.yml
@@ -299,6 +299,11 @@ fr:
         enter_email: 'Pseudo trouvé. Entrez l''adresse email correspondante.'
         prefilled: "L'adresse email correspond à ce pseudo enregistré."
 
+      locale:
+        title: "Langue de l'interface"
+        instructions: "La langue utilisée dans l'interface du forum. Le changement se fait lorsque vous rechargez la page."
+        default: "(par défaut)"
+
       password_confirmation:
         title: "Confirmation"
 
diff --git a/db/migrate/20140206044818_add_locale_to_user.rb b/db/migrate/20140206044818_add_locale_to_user.rb
new file mode 100644
index 000000000..c0f2431b3
--- /dev/null
+++ b/db/migrate/20140206044818_add_locale_to_user.rb
@@ -0,0 +1,5 @@
+class AddLocaleToUser < ActiveRecord::Migration
+  def change
+    add_column :users, :locale, :string, limit: 10
+  end
+end
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 00ba7824b..0cfc4ea80 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -44,6 +44,19 @@ describe TopicsController do
 
   end
 
+  describe 'set_locale' do
+    it 'sets the one the user prefers' do
+      SiteSetting.stubs(:allow_user_locale).returns(true)
+
+      user = Fabricate(:user, locale: :fr)
+      log_in_user(user)
+
+      get :show, {topic_id: topic.id}
+
+      I18n.locale.should == :fr
+    end
+  end
+
 end
 
 describe 'api' do