diff --git a/core/includes/update.inc b/core/includes/update.inc
index 24f8b47..b39eadb 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -469,10 +469,12 @@ function update_prepare_d8_language() {
       $prefixes[$language->language] = $language->prefix;
       $domains[$language->language] = $language->domain;
     }
-    variable_set('locale_translation_plurals', $plurals);
-    variable_set('locale_translation_javascript', $javascript);
-    variable_set('locale_language_negotiation_url_prefixes', $prefixes);
-    variable_set('locale_language_negotiation_url_domains', $domains);
+    state()->set('locale.translation.plurals', $plurals);
+    state()->set('locale.translation.javascript', $javascript);
+    config('language.negotiation')
+      ->set('url.prefixes', $prefixes)
+      ->set('url.domains', $domains)
+      ->save();
 
     // Drop now unneeded columns.
     db_drop_field('languages', 'plurals');
diff --git a/core/modules/locale/config/locale.settings.yml b/core/modules/locale/config/locale.settings.yml
index 36d7890..16b08ff 100644
--- a/core/modules/locale/config/locale.settings.yml
+++ b/core/modules/locale/config/locale.settings.yml
@@ -1,9 +1,12 @@
+cache_strings: '1'
+javascript:
+  directory: 'languages'
 translation:
   use_source: 'remote_and_local'
-  check_disabled_modules: false
+  check_disabled_modules: '0'
   default_filename: '%project-%version.%language.po'
   default_server_pattern: 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po'
-  overwrite_customized: false
-  overwrite_not_customized: true
+  overwrite_customized: '0'
+  overwrite_not_customized: '1'
   update_interval_days: '0'
   path: ''
diff --git a/core/modules/locale/lib/Drupal/locale/LocaleLookup.php b/core/modules/locale/lib/Drupal/locale/LocaleLookup.php
index c2be228..cc515b4 100644
--- a/core/modules/locale/lib/Drupal/locale/LocaleLookup.php
+++ b/core/modules/locale/lib/Drupal/locale/LocaleLookup.php
@@ -78,7 +78,7 @@ protected function resolveCacheMiss($offset) {
     // the exact list of strings used on a page. From a performance
     // perspective that is a really bad idea, so we have no user
     // interface for this. Be careful when turning this option off!
-    if (variable_get('locale_cache_strings', 1)) {
+    if (config('locale.settings')->get('cache_strings')) {
       $this->persist($offset);
     }
     return $value;
diff --git a/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php b/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php
index 4c8b254..618b419 100644
--- a/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php
+++ b/core/modules/locale/lib/Drupal/locale/PoDatabaseWriter.php
@@ -154,7 +154,8 @@ function getHeader() {
    */
   function setHeader(PoHeader $header) {
     $this->_header = $header;
-    $locale_plurals = variable_get('locale_translation_plurals', array());
+    $config = config('locale.settings');
+    $locale_plurals = state()->get('locale.translation.plurals') ?: array();
 
     // Check for options.
     $options = $this->getOptions();
@@ -178,7 +179,7 @@ function setHeader(PoHeader $header) {
           'plurals' => $nplurals,
           'formula' => $formula,
         );
-        variable_set('locale_translation_plurals', $locale_plurals);
+        state()->set('locale.translation.plurals', $locale_plurals);
       }
     }
   }
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
index fd3667c..06269ab 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleImportFunctionalTest.php
@@ -53,7 +53,7 @@ function testStandalonePoFile() {
     $this->importPoFile($this->getPoFile(), array(
       'langcode' => 'fr',
     ));
-
+    $config = config('locale.settings');
     // The import should automatically create the corresponding language.
     $this->assertRaw(t('The language %language has been created.', array('%language' => 'French')), t('The language has been automatically created.'));
 
@@ -61,7 +61,7 @@ function testStandalonePoFile() {
     $this->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array('%number' => 8, '%update' => 0, '%delete' => 0)), t('The translation file was successfully imported.'));
 
     // This import should have saved plural forms to have 2 variants.
-    $locale_plurals = variable_get('locale_translation_plurals', array());
+    $locale_plurals = state()->get('locale.translation.plurals') ?: array();
     $this->assert($locale_plurals['fr']['plurals'] == 2, t('Plural number initialized.'));
 
     // Ensure we were redirected correctly.
@@ -115,7 +115,7 @@ function testStandalonePoFile() {
     $this->assertText(t('No strings available.'), t('String not overwritten by imported string.'));
 
     // This import should not have changed number of plural forms.
-    $locale_plurals = variable_get('locale_translation_plurals', array());
+    $locale_plurals = state()->get('locale.translation.plurals') ?: array();
     $this->assert($locale_plurals['fr']['plurals'] == 2, t('Plural numbers untouched.'));
 
     // Try importing a .po file with overriding strings, and ensure existing
@@ -136,7 +136,7 @@ function testStandalonePoFile() {
     $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
     $this->assertNoText(t('No strings available.'), t('String overwritten by imported string.'));
     // This import should have changed number of plural forms.
-    $locale_plurals = variable_get('locale_translation_plurals', array());
+    $locale_plurals = state()->get('locale.translation.plurals') ?: array();
     $this->assert($locale_plurals['fr']['plurals'] == 3, t('Plural numbers changed.'));
 
     // Importing a .po file and mark its strings as customized strings.
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php
index ed0addd..f1c44dc 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleTranslationTest.php
@@ -215,6 +215,7 @@ function testStringTranslation() {
   function testJavaScriptTranslation() {
     $user = $this->drupalCreateUser(array('translate interface', 'administer languages', 'access administration pages'));
     $this->drupalLogin($user);
+    $config = config('locale.settings');
 
     $langcode = 'xx';
     // The English name for the language. This will be translated.
@@ -258,8 +259,8 @@ function testJavaScriptTranslation() {
     // Trigger JavaScript translation parsing and building.
     _locale_rebuild_js($langcode);
 
-    $locale_javascripts = variable_get('locale_translation_javascript', array());
-    $js_file = 'public://' . variable_get('locale_js_directory', 'languages') . '/' . $langcode . '_' . $locale_javascripts[$langcode] . '.js';
+    $locale_javascripts = state()->get('locale.translation.javascript') ?: array();
+    $js_file = 'public://' . $config->get('javascript.directory') . '/' . $langcode . '_' . $locale_javascripts[$langcode] . '.js';
     $this->assertTrue($result = file_exists($js_file), t('JavaScript file created: %file', array('%file' => $result ? $js_file : t('not found'))));
 
     // Test JavaScript translation rebuilding.
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
index c9ae95a..ee2b0c3 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
@@ -49,7 +49,7 @@ function setUp() {
    */
   function testUninstallProcess() {
     $locale_module = array('locale', 'language');
-
+    $config = config('locale.settings');
     $language = new Language(array(
       'langcode' => 'fr',
       'name' => 'French',
@@ -67,7 +67,7 @@ function testUninstallProcess() {
     // Enable multilingual workflow option for articles.
     language_save_default_configuration('node', 'article', array('langcode' => 'site_default', 'language_show' => TRUE));
     // Change JavaScript translations directory.
-    variable_set('locale_js_directory', 'js_translations');
+    $config->set('javascript.directory', 'js_translations')->save();
     // Build the JavaScript translation file for French.
     $user = $this->drupalCreateUser(array('translate interface', 'access administration pages'));
     $this->drupalLogin($user);
@@ -80,12 +80,13 @@ function testUninstallProcess() {
     $edit = array('strings[' . $string->lid . '][translations][0]' => 'french translation');
     $this->drupalPost('admin/config/regional/translate', $edit, t('Save translations'));
     _locale_rebuild_js('fr');
-    $locale_javascripts = variable_get('locale_translation_javascript', array());
-    $js_file = 'public://' . variable_get('locale_js_directory', 'languages') . '/fr_' . $locale_javascripts['fr'] . '.js';
+    $config = config('locale.settings');
+    $locale_javascripts = state()->get('locale.translation.javascript') ?: array();
+    $js_file = 'public://' . $config->get('javascript.directory') . '/fr_' . $locale_javascripts['fr'] . '.js';
     $this->assertTrue($result = file_exists($js_file), t('JavaScript file created: %file', array('%file' => $result ? $js_file : t('none'))));
 
     // Disable string caching.
-    variable_set('locale_cache_strings', 0);
+    $config->set('cache_strings', 0)->save();
 
     // Change language negotiation options.
     drupal_load('module', 'locale');
@@ -134,13 +135,5 @@ function testUninstallProcess() {
     // Check JavaScript parsed.
     $javascript_parsed_count = count(state()->get('system.javascript_parsed') ?: array());
     $this->assertEqual($javascript_parsed_count, 0, t('JavaScript parsed count: %count', array('%count' => $javascript_parsed_count)));
-
-    // Check JavaScript translations directory.
-    $locale_js_directory = variable_get('locale_js_directory', 'languages');
-    $this->assertEqual($locale_js_directory, 'languages', t('JavaScript translations directory: %dir', array('%dir' => $locale_js_directory)));
-
-    // Check string caching.
-    $locale_cache_strings = variable_get('locale_cache_strings', 1);
-    $this->assertEqual($locale_cache_strings, 1, t('String caching: %status', array('%status' => t($locale_cache_strings ? 'enabled': 'disabled'))));
   }
 }
diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install
index 61d7052..01a698a 100644
--- a/core/modules/locale/locale.install
+++ b/core/modules/locale/locale.install
@@ -21,11 +21,12 @@ function locale_install() {
  * Implements hook_uninstall().
  */
 function locale_uninstall() {
+  $config = config('locale.settings');
   // Delete all JavaScript translation files.
-  $locale_js_directory = 'public://' . variable_get('locale_js_directory', 'languages');
+  $locale_js_directory = 'public://' . $config->get('javascript.directory');
 
   if (is_dir($locale_js_directory)) {
-    $locale_javascripts = variable_get('locale_translation_javascript', array());
+    $locale_javascripts = state()->get('locale.translation.javascript') ?: array();
     foreach ($locale_javascripts as $langcode => $file_suffix) {
       if (!empty($file_suffix)) {
         file_unmanaged_delete($locale_js_directory . '/' . $langcode . '_' . $file_suffix . '.js');
@@ -38,12 +39,9 @@ function locale_uninstall() {
   }
 
   // Clear variables.
-  variable_del('locale_cache_strings');
-  variable_del('locale_js_directory');
   state()->delete('system.javascript_parsed');
-  variable_del('locale_cache_length');
-  variable_del('locale_translation_plurals');
-  variable_del('locale_translation_javascript');
+  state()->delete('locale.translation.plurals');
+  state()->delete('locale.translation.javascript');
 
   // Remove all node type language variables. Node module might have been
   // enabled, but may be disabled, so use a wildcard delete.
@@ -725,30 +723,19 @@ function locale_update_8007() {
 }
 
 /**
- * Rename the option variables of the locale language negotiation.
+ * Update locale variables to config or state systems as appropriate.
  *
  * @ingroup config_upgrade
  */
 function locale_update_8008() {
-  $variable_name_map = array(
-    'locale_language_negotiation_url_part' => 'language_negotiation_url_part',
-    'locale_language_negotiation_url_domains' => 'language_negotiation_url_domains',
-    'locale_language_negotiation_url_prefixes' => 'language_negotiation_url_prefixes',
-    'locale_language_negotiation_session_param' => 'language_negotiation_session_param',
-  );
-  foreach ($variable_name_map as $deprecated_variable_name => $new_variable_name) {
-    // Check if this variable is stored in the db and if so rename it.
-    $value = update_variable_get($deprecated_variable_name);
-    if ($value !== NULL) {
-      update_variable_set($new_variable_name, $value);
-      update_variable_del($deprecated_variable_name);
-    }
-  }
+  update_variables_to_config('locale.settings', array(
+    'locale_cache_strings' => 'cache_strings',
+    'locale_js_directory' => 'javascript.directory',
+  ));
+
   update_variables_to_config('language.negotiation', array(
     'locale_language_negotiation_session_param' => 'session.parameter',
-    'language_negotiation_url_part' => 'url.source',
-    'language_negotiation_url_prefixes' => 'url.prefixes',
-    'language_negotiation_url_domains' => 'url.domains',
+    'locale_language_negotiation_url_part' => 'url.source',
   ));
 }
 
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index d38f0d5..59dfff6 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -448,7 +448,7 @@ function locale_get_plural($count, $langcode = NULL) {
   if (!isset($plural_indexes[$langcode][$count])) {
     // Retrieve and statically cache the plural formulas for all languages.
     if (empty($plural_formulas)) {
-      $plural_formulas = variable_get('locale_translation_plurals', array());
+      $plural_formulas = state()->get('locale.translation.plurals') ?: array();
     }
     // If there is a plural formula for the language, evaluate it for the given
     // $count and statically cache the result for the combination of language
@@ -582,9 +582,10 @@ function locale_system_remove($components) {
  * file if necessary, and adds it to the page.
  */
 function locale_js_alter(&$javascript) {
+
   $language_interface = language(LANGUAGE_TYPE_INTERFACE);
 
-  $dir = 'public://' . variable_get('locale_js_directory', 'languages');
+  $dir = 'public://' . config('local.settings')->get('javascript.directory');
   $parsed = state()->get('system.javascript_parsed') ?: array();
   $files = $new_files = FALSE;
 
@@ -627,7 +628,7 @@ function locale_js_alter(&$javascript) {
   }
 
   // Add the translation JavaScript file to the page.
-  $locale_javascripts = variable_get('locale_translation_javascript', array());
+  $locale_javascripts = state()->get('translation.javascript') ?: array();
   if ($files && !empty($locale_javascripts[$language_interface->langcode])) {
     // Add the translation JavaScript file to the page.
     $file = $dir . '/' . $language_interface->langcode . '_' . $locale_javascripts[$language_interface->langcode] . '.js';
@@ -1200,6 +1201,7 @@ function _locale_invalidate_js($langcode = NULL) {
  *   The language, the translation file should be (re)created for.
  */
 function _locale_rebuild_js($langcode = NULL) {
+  $config = config('locale.settings');
   if (!isset($langcode)) {
     $language = language(LANGUAGE_TYPE_INTERFACE);
   }
@@ -1227,8 +1229,7 @@ function _locale_rebuild_js($langcode = NULL) {
   if (!empty($translations)) {
 
     $data = "Drupal.locale = { ";
-
-    $locale_plurals = variable_get('locale_translation_plurals', array());
+    $locale_plurals = state()->get('locale.translation.plurals') ?: array();
     if (!empty($locale_plurals[$language->langcode])) {
       $data .= "'pluralFormula': function (\$n) { return Number({$locale_plurals[$language->langcode]['formula']}); }, ";
     }
@@ -1239,10 +1240,10 @@ function _locale_rebuild_js($langcode = NULL) {
 
   // Construct the filepath where JS translation files are stored.
   // There is (on purpose) no front end to edit that variable.
-  $dir = 'public://' . variable_get('locale_js_directory', 'languages');
+  $dir = 'public://' . $config->get('javascript.directory');
 
   // Delete old file, if we have no translations anymore, or a different file to be saved.
-  $locale_javascripts = variable_get('locale_translation_javascript', array());
+  $locale_javascripts = state()->get('locale.translation.javascript') ?: array();
   $changed_hash = !isset($locale_javascripts[$language->langcode]) || ($locale_javascripts[$language->langcode] != $data_hash);
   if (!empty($locale_javascripts[$language->langcode]) && (!$data || $changed_hash)) {
     file_unmanaged_delete($dir . '/' . $language->langcode . '_' . $locale_javascripts[$language->langcode] . '.js');
@@ -1286,7 +1287,7 @@ function _locale_rebuild_js($langcode = NULL) {
   // deleted). Act only if some operation was executed that changed the hash
   // code.
   if ($status && $changed_hash) {
-    variable_set('locale_translation_javascript', $locale_javascripts);
+    state()->set('locale.translation.javascript', $locale_javascripts);
   }
 
   // Log the operation and return success flag.
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index a6d56ed..4366871 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -279,7 +279,7 @@ function locale_translate_edit_form($form, &$form_state) {
   if (isset($langcode)) {
     $strings = locale_translate_filter_load_strings();
 
-    $plural_formulas = variable_get('locale_translation_plurals', array());
+    $plural_formulas = state()->get('locale.translation.plurals') ?: array();
 
     foreach ($strings as $string) {
       // Cast into source string, will do for our purposes.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
index 34c8c94..91b954c 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php
@@ -143,7 +143,7 @@ public function testLanguageUpgrade() {
    */
   public function testLanguageUrlUpgrade() {
     $language_domain = 'ca.example.com';
-    db_update('languages')->fields(array('domain' => 'http://' . $language_domain . ':8888'))->condition('language', 'ca')->execute();
+    db_update('languages')->fields(array('domain' => $language_domain))->condition('language', 'ca')->execute();
     $this->variable_set('locale_language_negotiation_url_part', 1);
 
     $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
