diff --git a/app/assets/javascripts/wizard/components/scheme-preview.js.es6 b/app/assets/javascripts/wizard/components/theme-preview.js.es6
similarity index 95%
rename from app/assets/javascripts/wizard/components/scheme-preview.js.es6
rename to app/assets/javascripts/wizard/components/theme-preview.js.es6
index 484dafab5..2e676e296 100644
--- a/app/assets/javascripts/wizard/components/scheme-preview.js.es6
+++ b/app/assets/javascripts/wizard/components/theme-preview.js.es6
@@ -68,7 +68,7 @@ export default Ember.Component.extend({
   loaded: false,
   logo: null,
 
-  colorScheme: Ember.computed.alias('step.fieldsById.color_scheme.value'),
+  themeId: Ember.computed.alias('step.fieldsById.theme_id.value'),
 
   didInsertElement() {
     this._super();
@@ -84,7 +84,7 @@ export default Ember.Component.extend({
     });
   },
 
-  @observes('colorScheme')
+  @observes('themeId')
   triggerRepaint() {
     Ember.run.scheduleOnce('afterRender', this, 'repaint');
   },
@@ -95,10 +95,10 @@ export default Ember.Component.extend({
     const { ctx } = this;
     const headerHeight = HEIGHT * 0.15;
 
-    const colorScheme = this.get('colorScheme');
-    const options = this.get('step.fieldsById.color_scheme.options');
-    const option = options.findProperty('id', colorScheme);
-    if (!option) { return; }
+    const themeId = this.get('themeId');
+    const choices = this.get('step.fieldsById.theme_id.choices');
+    if (!choices) { return; }
+    const option = choices.findProperty('id', themeId);
 
     const colors = option.data.colors;
     if (!colors) { return; }
diff --git a/app/assets/javascripts/wizard/components/wizard-step.js.es6 b/app/assets/javascripts/wizard/components/wizard-step.js.es6
index 026c4b671..079b333cf 100644
--- a/app/assets/javascripts/wizard/components/wizard-step.js.es6
+++ b/app/assets/javascripts/wizard/components/wizard-step.js.es6
@@ -48,20 +48,6 @@ export default Ember.Component.extend({
     });
   },
 
-  saveStep() {
-    const step = this.get('step');
-    step.save()
-      .then(() => this.sendAction('goNext'))
-      .catch(response => {
-        const errors = response.responseJSON.errors;
-        if (errors && errors.length) {
-          errors.forEach(err => {
-            step.fieldError(err.field, err.description);
-          });
-        }
-      });
-  },
-
   actions: {
     backStep() {
       if (this.get('saving')) { return; }
@@ -77,7 +63,7 @@ export default Ember.Component.extend({
       if (step.get('valid')) {
         this.set('saving', true);
         step.save()
-          .then(() => this.sendAction('goNext'))
+          .then(response => this.sendAction('goNext', response))
           .catch(() => null) // we can swallow because the form is already marked as invalid
           .finally(() => this.set('saving', false));
       } else {
diff --git a/app/assets/javascripts/wizard/controllers/step.js.es6 b/app/assets/javascripts/wizard/controllers/step.js.es6
index e9bd4bce6..3a66e82d9 100644
--- a/app/assets/javascripts/wizard/controllers/step.js.es6
+++ b/app/assets/javascripts/wizard/controllers/step.js.es6
@@ -3,8 +3,13 @@ export default Ember.Controller.extend({
   step: null,
 
   actions: {
-    goNext() {
-      this.transitionToRoute('step', this.get('step.next'));
+    goNext(response) {
+      const next = this.get('step.next');
+      if (response.refresh_required) {
+        document.location = `/wizard/steps/${next}`;
+      } else {
+        this.transitionToRoute('step', next);
+      }
     },
     goBack() {
       this.transitionToRoute('step', this.get('step.previous'));
diff --git a/app/assets/javascripts/wizard/router.js.es6 b/app/assets/javascripts/wizard/router.js.es6
index 31d4aa861..57cea9cf6 100644
--- a/app/assets/javascripts/wizard/router.js.es6
+++ b/app/assets/javascripts/wizard/router.js.es6
@@ -1,9 +1,10 @@
 const Router = Ember.Router.extend({
-  location: Ember.testing ? 'none': 'hash'
+  rootURL: '/wizard',
+  location: Ember.testing ? 'none': 'history'
 });
 
-Router.map(function () {
-  this.route('step', { path: '/step/:step_id' });
+Router.map(function() {
+  this.route('step', { path: '/steps/:step_id' });
 });
 
 export default Router;
diff --git a/app/assets/javascripts/wizard/templates/components/scheme-preview.hbs b/app/assets/javascripts/wizard/templates/components/theme-preview.hbs
similarity index 100%
rename from app/assets/javascripts/wizard/templates/components/scheme-preview.hbs
rename to app/assets/javascripts/wizard/templates/components/theme-preview.hbs
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs b/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
index 4f843aa3e..85dd971b0 100644
--- a/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
+++ b/app/assets/javascripts/wizard/templates/components/wizard-field-dropdown.hbs
@@ -1 +1 @@
-{{combo-box class=inputClassName value=field.value content=field.options nameProperty="label" width="400px"}}
+{{combo-box class=inputClassName value=field.value content=field.choices nameProperty="label" width="400px"}}
diff --git a/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6 b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
index af59f65dd..2e5c9d4f8 100644
--- a/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
+++ b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6
@@ -9,7 +9,7 @@ test("Wizard starts", assert => {
 });
 
 test("Going back and forth in steps", assert => {
-  visit("/step/hello-world");
+  visit("/steps/hello-world");
   andThen(() => {
     assert.ok(exists('.wizard-step'));
     assert.ok(exists('.wizard-step-hello-world'), 'it adds a class for the step id');
diff --git a/app/assets/javascripts/wizard/test/wizard-pretender.js.es6 b/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
index 546f61fd7..c85aceb0a 100644
--- a/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
+++ b/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
@@ -51,7 +51,7 @@ export default function() {
             index: 1,
             fields: [
               { id: 'snack', type: 'dropdown', required: true },
-              { id: 'scheme-preview', type: 'component' }
+              { id: 'theme-preview', type: 'component' }
             ],
             previous: 'hello-world'
           }]
diff --git a/app/controllers/steps_controller.rb b/app/controllers/steps_controller.rb
index f2c62bb52..0a13fde1d 100644
--- a/app/controllers/steps_controller.rb
+++ b/app/controllers/steps_controller.rb
@@ -11,7 +11,9 @@ class StepsController < ApplicationController
     updater.update(params[:fields])
 
     if updater.success?
-      render json: success_json
+      result = { success: 'OK' }
+      result[:refresh_required] = true if updater.refresh_required?
+      render json: result
     else
       errors = []
       updater.errors.messages.each do |field, msg|
diff --git a/app/models/locale_site_setting.rb b/app/models/locale_site_setting.rb
index b1e983abe..1cd924641 100644
--- a/app/models/locale_site_setting.rb
+++ b/app/models/locale_site_setting.rb
@@ -8,12 +8,21 @@ class LocaleSiteSetting < EnumSiteSetting
 
   def self.values
     supported_locales.map do |l|
-      {name: l, value: l}
+      lang = language_names[l] || language_names[l[0..1]]
+      {name: lang ? lang['nativeName'] : l, value: l}
     end
   end
 
   @lock = Mutex.new
 
+  def self.language_names
+    return @language_names if @language_names
+
+    @lock.synchronize do
+      @language_names ||= YAML.load(File.read(File.join(Rails.root, 'config', 'locales', 'names.yml')))
+    end
+  end
+
   def self.supported_locales
     @lock.synchronize do
       @supported_locales ||= Dir.glob( File.join(Rails.root, 'config', 'locales', 'client.*.yml') ).map {|x| x.split('.')[-2]}.sort
diff --git a/app/serializers/wizard_field_choice_serializer.rb b/app/serializers/wizard_field_choice_serializer.rb
new file mode 100644
index 000000000..d364f0bdd
--- /dev/null
+++ b/app/serializers/wizard_field_choice_serializer.rb
@@ -0,0 +1,26 @@
+class WizardFieldChoiceSerializer < ApplicationSerializer
+  attributes :id, :label, :data
+
+  def id
+    object.id
+  end
+
+  def label
+    return object.label if object.label.present?
+
+    # Try getting one from a translation
+    field = object.field
+    step = field.step
+    I18n.t("wizard.step.#{step.id}.fields.#{field.id}.options.#{id}", default: id)
+  end
+
+  def data
+    result = object.data.dup
+    result.delete(:id)
+    result
+  end
+
+  def include_data?
+    object.data.present?
+  end
+end
diff --git a/app/serializers/wizard_field_serializer.rb b/app/serializers/wizard_field_serializer.rb
index 7f69605ee..4a70098a5 100644
--- a/app/serializers/wizard_field_serializer.rb
+++ b/app/serializers/wizard_field_serializer.rb
@@ -1,6 +1,7 @@
 class WizardFieldSerializer < ApplicationSerializer
 
-  attributes :id, :type, :required, :value, :label, :placeholder, :description, :options
+  attributes :id, :type, :required, :value, :label, :placeholder, :description
+  has_many :choices, serializer: WizardFieldChoiceSerializer, embed: :objects
 
   def id
     object.id
@@ -50,24 +51,4 @@ class WizardFieldSerializer < ApplicationSerializer
     description.present?
   end
 
-  def options
-    object.options.map do |o|
-
-      result = {id: o, label: I18n.t("#{i18n_key}.options.#{o}")}
-
-      data = object.option_data[o]
-      if data.present?
-        as_json = data.dup
-        as_json.delete(:id)
-        result[:data] = as_json
-      end
-
-      result
-    end
-  end
-
-  def include_options?
-    object.options.present?
-  end
-
 end
diff --git a/app/services/color_scheme_revisor.rb b/app/services/color_scheme_revisor.rb
index 1e864843f..5db7bb79d 100644
--- a/app/services/color_scheme_revisor.rb
+++ b/app/services/color_scheme_revisor.rb
@@ -21,6 +21,7 @@ class ColorSchemeRevisor
 
       @color_scheme.name    = @params[:name]    if @params.has_key?(:name)
       @color_scheme.enabled = @params[:enabled] if @params.has_key?(:enabled)
+      @color_scheme.theme_id = @params[:theme_id] if @params.has_key?(:theme_id)
       new_version = false
 
       if @params[:colors]
@@ -30,7 +31,7 @@ class ColorSchemeRevisor
       end
 
       if new_version
-        old_version = ColorScheme.create(
+        ColorScheme.create(
           name: @color_scheme.name,
           enabled: false,
           colors: @color_scheme.colors_hashes,
diff --git a/config/locales/names.yml b/config/locales/names.yml
new file mode 100644
index 000000000..60e992501
--- /dev/null
+++ b/config/locales/names.yml
@@ -0,0 +1,559 @@
+---
+aa:
+  name: Afar
+  nativeName: Afaraf
+ab:
+  name: Abkhaz
+  nativeName: аҧсуа бызшәа
+ae:
+  name: Avestan
+  nativeName: avesta
+af:
+  name: Afrikaans
+  nativeName: Afrikaans
+ak:
+  name: Akan
+  nativeName: Akan
+am:
+  name: Amharic
+  nativeName: አማርኛ
+an:
+  name: Aragonese
+  nativeName: aragonés
+ar:
+  name: Arabic
+  nativeName: اللغة العربية
+as:
+  name: Assamese
+  nativeName: অসমীয়া
+av:
+  name: Avaric
+  nativeName: авар мацӀ
+ay:
+  name: Aymara
+  nativeName: aymar aru
+az:
+  name: Azerbaijani
+  nativeName: azərbaycan dili
+ba:
+  name: Bashkir
+  nativeName: башҡорт теле
+be:
+  name: Belarusian
+  nativeName: беларуская мова
+bg:
+  name: Bulgarian
+  nativeName: български език
+bh:
+  name: Bihari
+  nativeName: भोजपुरी
+bi:
+  name: Bislama
+  nativeName: Bislama
+bm:
+  name: Bambara
+  nativeName: bamanankan
+bn:
+  name: Bengali
+  nativeName: বাংলা
+bo:
+  name: Tibetan Standard
+  nativeName: བོད་ཡིག
+br:
+  name: Breton
+  nativeName: brezhoneg
+bs:
+  name: Bosnian
+  nativeName: bosanski jezik
+ca:
+  name: Catalan
+  nativeName: català
+ce:
+  name: Chechen
+  nativeName: нохчийн мотт
+ch:
+  name: Chamorro
+  nativeName: Chamoru
+co:
+  name: Corsican
+  nativeName: corsu
+cr:
+  name: Cree
+  nativeName: ᓀᐦᐃᔭᐍᐏᐣ
+cs:
+  name: Czech
+  nativeName: čeština
+cu:
+  name: Old Church Slavonic
+  nativeName: ѩзыкъ словѣньскъ
+cv:
+  name: Chuvash
+  nativeName: чӑваш чӗлхи
+cy:
+  name: Welsh
+  nativeName: Cymraeg
+da:
+  name: Danish
+  nativeName: dansk
+de:
+  name: German
+  nativeName: Deutsch
+dv:
+  name: Divehi
+  nativeName: Dhivehi
+dz:
+  name: Dzongkha
+  nativeName: རྫོང་ཁ
+ee:
+  name: Ewe
+  nativeName: Eʋegbe
+el:
+  name: Greek
+  nativeName: ελληνικά
+en:
+  name: English
+  nativeName: English
+eo:
+  name: Esperanto
+  nativeName: Esperanto
+es:
+  name: Spanish
+  nativeName: Español
+et:
+  name: Estonian
+  nativeName: eesti
+eu:
+  name: Basque
+  nativeName: euskara
+fa:
+  name: Persian
+  nativeName: فارسی
+ff:
+  name: Fula
+  nativeName: Fulfulde
+fi:
+  name: Finnish
+  nativeName: suomi
+fj:
+  name: Fijian
+  nativeName: Vakaviti
+fo:
+  name: Faroese
+  nativeName: føroyskt
+fr:
+  name: French
+  nativeName: Français
+fy:
+  name: Western Frisian
+  nativeName: Frysk
+ga:
+  name: Irish
+  nativeName: Gaeilge
+gd:
+  name: Scottish Gaelic
+  nativeName: Gàidhlig
+gl:
+  name: Galician
+  nativeName: galego
+gn:
+  name: Guaraní
+  nativeName: Avañe'ẽ
+gu:
+  name: Gujarati
+  nativeName: ગુજરાતી
+gv:
+  name: Manx
+  nativeName: Gaelg
+ha:
+  name: Hausa
+  nativeName: هَوُسَ
+he:
+  name: Hebrew
+  nativeName: עברית
+hi:
+  name: Hindi
+  nativeName: हिन्दी
+ho:
+  name: Hiri Motu
+  nativeName: Hiri Motu
+hr:
+  name: Croatian
+  nativeName: hrvatski jezik
+ht:
+  name: Haitian
+  nativeName: Kreyòl ayisyen
+hu:
+  name: Hungarian
+  nativeName: magyar
+hy:
+  name: Armenian
+  nativeName: Հայերեն
+hz:
+  name: Herero
+  nativeName: Otjiherero
+ia:
+  name: Interlingua
+  nativeName: Interlingua
+id:
+  name: Indonesian
+  nativeName: Indonesian
+ie:
+  name: Interlingue
+  nativeName: Interlingue
+ig:
+  name: Igbo
+  nativeName: Asụsụ Igbo
+ii:
+  name: Nuosu
+  nativeName: ꆈꌠ꒿ Nuosuhxop
+ik:
+  name: Inupiaq
+  nativeName: Iñupiaq
+io:
+  name: Ido
+  nativeName: Ido
+is:
+  name: Icelandic
+  nativeName: Íslenska
+it:
+  name: Italian
+  nativeName: Italiano
+iu:
+  name: Inuktitut
+  nativeName: ᐃᓄᒃᑎᑐᑦ
+ja:
+  name: Japanese
+  nativeName: 日本語
+jv:
+  name: Javanese
+  nativeName: basa Jawa
+ka:
+  name: Georgian
+  nativeName: ქართული
+kg:
+  name: Kongo
+  nativeName: Kikongo
+ki:
+  name: Kikuyu
+  nativeName: Gĩkũyũ
+kj:
+  name: Kwanyama
+  nativeName: Kuanyama
+kk:
+  name: Kazakh
+  nativeName: қазақ тілі
+kl:
+  name: Kalaallisut
+  nativeName: kalaallisut
+km:
+  name: Khmer
+  nativeName: ខេមរភាសា
+kn:
+  name: Kannada
+  nativeName: ಕನ್ನಡ
+ko:
+  name: Korean
+  nativeName: 한국어
+kr:
+  name: Kanuri
+  nativeName: Kanuri
+ks:
+  name: Kashmiri
+  nativeName: कश्मीरी
+ku:
+  name: Kurdish
+  nativeName: Kurdî
+kv:
+  name: Komi
+  nativeName: коми кыв
+kw:
+  name: Cornish
+  nativeName: Kernewek
+ky:
+  name: Kyrgyz
+  nativeName: Кыргызча
+la:
+  name: Latin
+  nativeName: latine
+lb:
+  name: Luxembourgish
+  nativeName: Lëtzebuergesch
+lg:
+  name: Ganda
+  nativeName: Luganda
+li:
+  name: Limburgish
+  nativeName: Limburgs
+ln:
+  name: Lingala
+  nativeName: Lingála
+lo:
+  name: Lao
+  nativeName: ພາສາ
+lt:
+  name: Lithuanian
+  nativeName: lietuvių kalba
+lu:
+  name: Luba-Katanga
+  nativeName: Tshiluba
+lv:
+  name: Latvian
+  nativeName: latviešu valoda
+mg:
+  name: Malagasy
+  nativeName: fiteny malagasy
+mh:
+  name: Marshallese
+  nativeName: Kajin M̧ajeļ
+mi:
+  name: Māori
+  nativeName: te reo Māori
+mk:
+  name: Macedonian
+  nativeName: македонски јазик
+ml:
+  name: Malayalam
+  nativeName: മലയാളം
+mn:
+  name: Mongolian
+  nativeName: Монгол хэл
+mr:
+  name: Marathi
+  nativeName: मराठी
+ms:
+  name: Malay
+  nativeName: هاس ملايو‎
+mt:
+  name: Maltese
+  nativeName: Malti
+my:
+  name: Burmese
+  nativeName: ဗမာစာ
+na:
+  name: Nauru
+  nativeName: Ekakairũ Naoero
+nb:
+  name: Norwegian Bokmål
+  nativeName: Norsk bokmål
+nd:
+  name: Northern Ndebele
+  nativeName: isiNdebele
+ne:
+  name: Nepali
+  nativeName: नेपाली
+ng:
+  name: Ndonga
+  nativeName: Owambo
+nl:
+  name: Dutch
+  nativeName: Nederlands
+nn:
+  name: Norwegian Nynorsk
+  nativeName: Norsk nynorsk
+'no':
+  name: Norwegian
+  nativeName: Norsk
+nr:
+  name: Southern Ndebele
+  nativeName: isiNdebele
+nv:
+  name: Navajo
+  nativeName: Diné bizaad
+ny:
+  name: Chichewa
+  nativeName: chiCheŵa
+oc:
+  name: Occitan
+  nativeName: occitan
+oj:
+  name: Ojibwe
+  nativeName: ᐊᓂᔑᓈᐯᒧᐎᓐ
+om:
+  name: Oromo
+  nativeName: Afaan Oromoo
+or:
+  name: Oriya
+  nativeName: ଓଡ଼ିଆ
+os:
+  name: Ossetian
+  nativeName: ирон æвзаг
+pa:
+  name: Panjabi
+  nativeName: ਪੰਜਾਬੀ
+pi:
+  name: Pāli
+  nativeName: पाऴि
+pl:
+  name: Polish
+  nativeName: język polski
+ps:
+  name: Pashto
+  nativeName: پښتو
+pt:
+  name: Portuguese
+  nativeName: Português
+pt_BR:
+  name: Portuguese
+  nativeName: Português (BR)
+qu:
+  name: Quechua
+  nativeName: Runa Simi
+rm:
+  name: Romansh
+  nativeName: rumantsch grischun
+rn:
+  name: Kirundi
+  nativeName: Ikirundi
+ro:
+  name: Romanian
+  nativeName: limba română
+ru:
+  name: Russian
+  nativeName: Русский
+rw:
+  name: Kinyarwanda
+  nativeName: Ikinyarwanda
+sa:
+  name: Sanskrit
+  nativeName: संस्कृतम्
+sc:
+  name: Sardinian
+  nativeName: sardu
+sd:
+  name: Sindhi
+  nativeName: सिन्धी
+se:
+  name: Northern Sami
+  nativeName: Davvisámegiella
+sg:
+  name: Sango
+  nativeName: yângâ tî sängö
+si:
+  name: Sinhala
+  nativeName: සිංහල
+sk:
+  name: Slovak
+  nativeName: slovenčina
+sl:
+  name: Slovene
+  nativeName: slovenski jezik
+sm:
+  name: Samoan
+  nativeName: gagana fa'a Samoa
+sn:
+  name: Shona
+  nativeName: chiShona
+so:
+  name: Somali
+  nativeName: Soomaaliga
+sq:
+  name: Albanian
+  nativeName: Shqip
+sr:
+  name: Serbian
+  nativeName: српски језик
+ss:
+  name: Swati
+  nativeName: SiSwati
+st:
+  name: Southern Sotho
+  nativeName: Sesotho
+su:
+  name: Sundanese
+  nativeName: Basa Sunda
+sv:
+  name: Swedish
+  nativeName: svenska
+sw:
+  name: Swahili
+  nativeName: Kiswahili
+ta:
+  name: Tamil
+  nativeName: தமிழ்
+te:
+  name: Telugu
+  nativeName: తెలుగు
+tg:
+  name: Tajik
+  nativeName: тоҷикӣ
+th:
+  name: Thai
+  nativeName: ไทย
+ti:
+  name: Tigrinya
+  nativeName: ትግርኛ
+tk:
+  name: Turkmen
+  nativeName: Türkmen
+tl:
+  name: Tagalog
+  nativeName: Wikang Tagalog
+tn:
+  name: Tswana
+  nativeName: Setswana
+to:
+  name: Tonga
+  nativeName: faka Tonga
+tr:
+  name: Turkish
+  nativeName: Türkçe
+ts:
+  name: Tsonga
+  nativeName: Xitsonga
+tt:
+  name: Tatar
+  nativeName: татар теле
+tw:
+  name: Twi
+  nativeName: Twi
+ty:
+  name: Tahitian
+  nativeName: Reo Tahiti
+ug:
+  name: Uyghur
+  nativeName: ئۇيغۇرچە‎
+uk:
+  name: Ukrainian
+  nativeName: українська мова
+ur:
+  name: Urdu
+  nativeName: اردو
+uz:
+  name: Uzbek
+  nativeName: Ўзбек
+ve:
+  name: Venda
+  nativeName: Tshivenḓa
+vi:
+  name: Vietnamese
+  nativeName: Việt Nam
+vo:
+  name: Volapük
+  nativeName: Volapük
+wa:
+  name: Walloon
+  nativeName: walon
+wo:
+  name: Wolof
+  nativeName: Wollof
+xh:
+  name: Xhosa
+  nativeName: isiXhosa
+yi:
+  name: Yiddish
+  nativeName: ייִדיש
+yo:
+  name: Yoruba
+  nativeName: Yorùbá
+za:
+  name: Zhuang
+  nativeName: Saɯ cueŋƅ
+zh:
+  name: Chinese
+  nativeName: 中文
+zh_TW:
+  name: Chinese
+  nativeName: 中文 (TW)
+zu:
+  name: Zulu
+  nativeName: isiZulu
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index c3be14d8a..97ec50c98 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -3216,10 +3216,19 @@ en:
   wizard:
     title: "Discourse Setup Wizard"
     step:
-      forum_title:
+      locale:
         title: "Welcome to your Discourse forum!"
         description: "There are a few things you'll need to configure before inviting more people to the party. Don't worry, you can come back and change these settings at any time, so don't overthink it."
 
+        fields:
+          default_locale:
+            label: "Language"
+            description: "The default language for users browsing your forum"
+
+      forum_title:
+        title: "The Basics"
+        description: "Tell us a little bit about yourself."
+
         fields:
           title:
             label: "Enter a title for your forum"
@@ -3242,10 +3251,10 @@ en:
             label: "Site Contact Username"
             description: "All automated messages will be sent from this user."
       colors:
-        title: "Choose a Color Scheme"
+        title: "Choose a Theme"
         fields:
-          color_scheme:
-            label: "Color Scheme"
+          theme_id:
+            label: "Theme"
             options:
               default: "Simple"
               dark: "Dark"
diff --git a/config/routes.rb b/config/routes.rb
index e86c43efe..af169723d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -56,6 +56,7 @@ Discourse::Application.routes.draw do
   get "wizard" => "wizard#index"
   get "wizard/qunit" => "wizard#qunit"
   get 'wizard/steps' => 'steps#index'
+  get 'wizard/steps/:id' => "wizard#index"
   put 'wizard/steps/:id' => "steps#update"
 
   namespace :admin, constraints: StaffConstraint.new do
diff --git a/db/migrate/20160906200439_add_via_wizard_to_color_schemes.rb b/db/migrate/20160906200439_add_via_wizard_to_color_schemes.rb
index 40c69d416..1fc1881f5 100644
--- a/db/migrate/20160906200439_add_via_wizard_to_color_schemes.rb
+++ b/db/migrate/20160906200439_add_via_wizard_to_color_schemes.rb
@@ -1,5 +1,6 @@
 class AddViaWizardToColorSchemes < ActiveRecord::Migration
   def change
     add_column :color_schemes, :via_wizard, :boolean, default: false, null: false
+    add_column :color_schemes, :theme_id, :string, null: true
   end
 end
diff --git a/lib/wizard.rb b/lib/wizard.rb
index 7e8d46a00..ba0685aea 100644
--- a/lib/wizard.rb
+++ b/lib/wizard.rb
@@ -9,11 +9,15 @@ class Wizard
     @steps = []
   end
 
-  def create_step(args)
-    Step.new(args)
+  def create_step(step_name)
+    Step.new(step_name)
   end
 
   def append_step(step)
+    step = create_step(step) if step.is_a?(String)
+
+    yield step if block_given?
+
     last_step = @steps.last
 
     @steps << step
@@ -31,26 +35,40 @@ class Wizard
 
   def self.build
     wizard = Wizard.new
-    title = wizard.create_step('forum-title')
-    title.add_field(id: 'title', type: 'text', required: true, value: SiteSetting.title)
-    title.add_field(id: 'site_description', type: 'text', required: true, value: SiteSetting.site_description)
-    wizard.append_step(title)
 
-    contact = wizard.create_step('contact')
-    contact.add_field(id: 'contact_email', type: 'text', required: true, value: SiteSetting.contact_email)
-    contact.add_field(id: 'contact_url', type: 'text', value: SiteSetting.contact_url)
-    contact.add_field(id: 'site_contact_username', type: 'text', value: SiteSetting.site_contact_username)
-    wizard.append_step(contact)
+    wizard.append_step('locale') do |step|
+      languages = step.add_field(id: 'default_locale',
+                                 type: 'dropdown',
+                                 required: true,
+                                 value: SiteSetting.default_locale)
 
-    theme = wizard.create_step('colors')
-    scheme = theme.add_field(id: 'color_scheme', type: 'dropdown', required: true)
-    ColorScheme.themes.each {|t| scheme.add_option(t[:id], t) }
+      LocaleSiteSetting.values.each do |locale|
+        languages.add_choice(locale[:value], label: locale[:name])
+      end
+    end
 
-    theme.add_field(id: 'scheme_preview', type: 'component')
-    wizard.append_step(theme)
+    wizard.append_step('forum-title') do |step|
+      step.add_field(id: 'title', type: 'text', required: true, value: SiteSetting.title)
+      step.add_field(id: 'site_description', type: 'text', required: true, value: SiteSetting.site_description)
+    end
 
-    finished = wizard.create_step('finished')
-    wizard.append_step(finished);
+    wizard.append_step('contact') do |step|
+      step.add_field(id: 'contact_email', type: 'text', required: true, value: SiteSetting.contact_email)
+      step.add_field(id: 'contact_url', type: 'text', value: SiteSetting.contact_url)
+      step.add_field(id: 'site_contact_username', type: 'text', value: SiteSetting.site_contact_username)
+    end
+
+    wizard.append_step('colors') do |step|
+
+      theme_id = ColorScheme.where(via_wizard: true).pluck(:theme_id)
+      theme_id = theme_id.present? ? theme_id[0] : 'default'
+
+      themes = step.add_field(id: 'theme_id', type: 'dropdown', required: true, value: theme_id)
+      ColorScheme.themes.each {|t| themes.add_choice(t[:id], data: t) }
+      step.add_field(id: 'theme_preview', type: 'component')
+    end
+
+    wizard.append_step('finished')
 
     wizard
   end
diff --git a/lib/wizard/field.rb b/lib/wizard/field.rb
index 70afc2df8..5b8faf8fc 100644
--- a/lib/wizard/field.rb
+++ b/lib/wizard/field.rb
@@ -1,7 +1,18 @@
 class Wizard
-  class Field
 
-    attr_reader :id, :type, :required, :value, :options, :option_data
+  class Choice
+    attr_reader :id, :label, :data
+    attr_accessor :field
+
+    def initialize(id, opts)
+      @id = id
+      @data = opts[:data]
+      @label = opts[:label]
+    end
+  end
+
+  class Field
+    attr_reader :id, :type, :required, :value, :choices
     attr_accessor :step
 
     def initialize(attrs)
@@ -11,13 +22,15 @@ class Wizard
       @type = attrs[:type]
       @required = !!attrs[:required]
       @value = attrs[:value]
-      @options = []
-      @option_data = {}
+      @choices = []
     end
 
-    def add_option(id, data=nil)
-      @options << id
-      @option_data[id] = data
+    def add_choice(id, opts=nil)
+      choice = Choice.new(id, opts || {})
+      choice.field = self
+
+      @choices << choice
+      choice
     end
 
   end
diff --git a/lib/wizard/step_updater.rb b/lib/wizard/step_updater.rb
index 543f55eff..fe0c0278a 100644
--- a/lib/wizard/step_updater.rb
+++ b/lib/wizard/step_updater.rb
@@ -5,6 +5,7 @@ class Wizard
     def initialize(current_user, id)
       @current_user = current_user
       @id = id
+      @refresh_required = false
     end
 
     def update(fields)
@@ -12,6 +13,12 @@ class Wizard
       send(updater_method, fields.symbolize_keys) if respond_to?(updater_method)
     end
 
+    def update_locale(fields)
+      old_locale = SiteSetting.default_locale
+      update_setting(:default_locale, fields, :default_locale)
+      @refresh_required = true if old_locale != fields[:default_locale]
+    end
+
     def update_forum_title(fields)
       update_setting(:title, fields, :title)
       update_setting(:site_description, fields, :site_description)
@@ -24,7 +31,7 @@ class Wizard
     end
 
     def update_colors(fields)
-      scheme_name = fields[:color_scheme]
+      scheme_name = fields[:theme_id]
 
       theme = ColorScheme.themes.find {|s| s[:id] == scheme_name }
 
@@ -36,7 +43,8 @@ class Wizard
       attrs = {
         enabled: true,
         name: I18n.t("wizard.step.colors.fields.color_scheme.options.#{scheme_name}"),
-        colors: colors
+        colors: colors,
+        theme_id: scheme_name
       }
 
       scheme = ColorScheme.where(via_wizard: true).first
@@ -55,6 +63,10 @@ class Wizard
       @errors.blank?
     end
 
+    def refresh_required?
+      @refresh_required
+    end
+
     protected
 
       def update_setting(id, fields, field_id)
diff --git a/spec/components/step_updater_spec.rb b/spec/components/step_updater_spec.rb
index 336c9fe33..b61e3a288 100644
--- a/spec/components/step_updater_spec.rb
+++ b/spec/components/step_updater_spec.rb
@@ -4,6 +4,24 @@ require_dependency 'wizard/step_updater'
 describe Wizard::StepUpdater do
   let(:user) { Fabricate(:admin) }
 
+  context "locale" do
+    let(:updater) { Wizard::StepUpdater.new(user, 'locale') }
+
+    it "does not require refresh when the language stays the same" do
+      updater.update(default_locale: 'en')
+      expect(updater.refresh_required?).to eq(false)
+    end
+
+    it "updates the locale and requires refresh when it does change" do
+      updater.update(default_locale: 'ru')
+      expect(SiteSetting.default_locale).to eq('ru')
+      expect(updater.refresh_required?).to eq(true)
+    end
+  end
+
+  it "updates the locale" do
+  end
+
   it "updates the forum title step" do
     updater = Wizard::StepUpdater.new(user, 'forum_title')
     updater.update(title: 'new forum title', site_description: 'neat place')
@@ -30,7 +48,7 @@ describe Wizard::StepUpdater do
     it "doesn't update when there are errors" do
       updater.update(contact_email: 'not-an-email',
                      site_contact_username: 'not-a-username')
-      expect(updater).to be_success
+      expect(updater).to_not be_success
       expect(updater.errors).to be_present
     end
   end
diff --git a/spec/components/wizard_spec.rb b/spec/components/wizard_spec.rb
index 610eff92e..72987de69 100644
--- a/spec/components/wizard_spec.rb
+++ b/spec/components/wizard_spec.rb
@@ -15,6 +15,14 @@ describe Wizard do
     let(:step1) { wizard.create_step('first-step') }
     let(:step2) { wizard.create_step('second-step') }
 
+    it "works with a block format" do
+      wizard.append_step('wat') do |step|
+        expect(step).to be_present
+      end
+
+      expect(wizard.steps.size).to eq(1)
+    end
+
     it "adds the step correctly" do
       expect(step1.index).to be_blank
 
diff --git a/spec/components/wizard_step_spec.rb b/spec/components/wizard_step_spec.rb
index 0d6f1df40..54f950722 100644
--- a/spec/components/wizard_step_spec.rb
+++ b/spec/components/wizard_step_spec.rb
@@ -12,12 +12,12 @@ describe Wizard::Step do
     expect(step.fields).to eq([text])
 
     dropdown = step.add_field(id: 'snacks', type: 'dropdown')
-    dropdown.add_option(id: 'candy')
-    dropdown.add_option(id: 'nachos')
-    dropdown.add_option(id: 'pizza')
+    dropdown.add_choice('candy')
+    dropdown.add_choice('nachos', data: {color: 'yellow'})
+    dropdown.add_choice('pizza', label: 'Pizza!')
 
     expect(step.fields).to eq([text, dropdown])
-    expect(dropdown.options.size).to eq(3)
+    expect(dropdown.choices.size).to eq(3)
   end
 
 end
diff --git a/spec/integrity/i18n_spec.rb b/spec/integrity/i18n_spec.rb
index 20b69dfa3..1d99795ed 100644
--- a/spec/integrity/i18n_spec.rb
+++ b/spec/integrity/i18n_spec.rb
@@ -44,7 +44,8 @@ describe "i18n integrity checks" do
   end
 
   it "does not overwrite another language" do
-    Dir["#{Rails.root}/config/locales/*.yml"].each do |f|
+    all = Dir["#{Rails.root}/config/locales/client.*.yml"] + Dir["#{Rails.root}/config/locales/server.*.yml"]
+    all.each do |f|
       locale = /.*\.([^.]{2,})\.yml$/.match(f)[1] + ':'
       IO.foreach(f) do |line|
         line.strip!
diff --git a/spec/services/color_scheme_revisor_spec.rb b/spec/services/color_scheme_revisor_spec.rb
index 8db267690..d9f8a3519 100644
--- a/spec/services/color_scheme_revisor_spec.rb
+++ b/spec/services/color_scheme_revisor_spec.rb
@@ -18,6 +18,11 @@ describe ColorSchemeRevisor do
       expect(color_scheme.reload.name).to eq("Changed Name")
     end
 
+    it "can update the theme_id" do
+      described_class.revise(color_scheme, valid_params.merge(theme_id: 'test'))
+      expect(color_scheme.reload.theme_id).to eq('test')
+    end
+
     it "can enable and disable" do
       described_class.revise(color_scheme, valid_params.merge(enabled: true))
       expect(color_scheme.reload).to be_enabled