diff --git a/core/modules/language/config/language.types.yml b/core/modules/language/config/language.types.yml
index 2b77d89967f0bc8b0d08da00d5d7fc4ff050bf48..4d48251fdfe9fddada96f3f93e79147ecaeceb4d 100644
--- a/core/modules/language/config/language.types.yml
+++ b/core/modules/language/config/language.types.yml
@@ -4,3 +4,14 @@ all:
   - language_url
 configurable:
   - language_interface
+negotiation:
+  language_content:
+    enabled:
+      language-interface: 0
+  language_url:
+    enabled:
+      language-url: 0
+      language-url-fallback: 1
+  language_interface:
+    enabled:
+      language-url: 0
diff --git a/core/modules/language/config/schema/language.schema.yml b/core/modules/language/config/schema/language.schema.yml
index ab74403fc220dcebc3c2caf0c16ed2e972b100f0..7b2ceb31834b37c8da06cfaa9e38be3816d3131b 100644
--- a/core/modules/language/config/schema/language.schema.yml
+++ b/core/modules/language/config/schema/language.schema.yml
@@ -1,5 +1,22 @@
 # Schema for the configuration files of the Language module.
 
+language_type_negotiation:
+  type: mapping
+  label: 'Language negotiation per type setting'
+  mapping:
+    enabled:
+      type: sequence
+      label: 'Enabled negotiators'
+      sequence:
+        - type: integer
+          label: Weight
+    method_weights:
+      type: sequence
+      label: 'Negotiator weights'
+      sequence:
+        - type: integer
+          label: Weight
+
 language.types:
   type: mapping
   label: 'Language types'
@@ -16,6 +33,12 @@ language.types:
       sequence:
         - type: string
           label: 'Language type'
+    negotiation:
+      type: sequence
+      label: 'Language negotiation per type settings'
+      sequence:
+        - type: language_type_negotiation
+          label: 'Language negotiation per type setting'
 
 language.negotiation:
   type: mapping
diff --git a/core/modules/language/language.install b/core/modules/language/language.install
index fedc2b479399fe6d9e1fdd4ec418af1118dd3644..27541cac9cc8781a7f3be4f3bce95eede45789a1 100644
--- a/core/modules/language/language.install
+++ b/core/modules/language/language.install
@@ -5,39 +5,10 @@
  * Install, update and uninstall functions for the language module.
  */
 
-use Drupal\Core\Language\Language;
-use Drupal\language\ConfigurableLanguageManagerInterface;
-use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
-
-/**
- * Implements hook_install().
- *
- * Enable URL language negotiation by default in order to have a basic working
- * system on multilingual sites without needing any preliminary configuration.
- */
-function language_install() {
-  $language_manager = \Drupal::languageManager();
-  if ($language_manager instanceof ConfigurableLanguageManagerInterface) {
-    $negotiator = \Drupal::service('language_negotiator');
-    $types = $language_manager->getLanguageTypes();
-    $negotiator->updateConfiguration($types);
-    // Enable URL language detection for each configurable language type.
-    foreach ($types as $type) {
-      $negotiator->saveConfiguration($type, array(LanguageNegotiationUrl::METHOD_ID => 0));
-    }
-  }
-}
-
 /**
  * Implements hook_uninstall().
  */
 function language_uninstall() {
-  // Clear variables.
-  foreach (\Drupal::languageManager()->getDefinedLanguageTypes() as $type) {
-    variable_del("language_negotiation_$type");
-    variable_del("language_negotiation_methods_weight_$type");
-  }
-
   // Re-initialize the language system so successive calls to t() and other
   // functions will not expect languages to be present.
   drupal_language_initialize();
diff --git a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php
index 9de37262434be6164f035637f788f3fd55c0079f..951836c55e16d371cba7e4fa8431b81690341cf1 100644
--- a/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php
+++ b/core/modules/language/lib/Drupal/language/ConfigurableLanguageManager.php
@@ -169,8 +169,15 @@ public function getDefinedLanguageTypesInfo() {
   /**
    * Stores language types configuration.
    */
-  public function saveLanguageTypesConfiguration(array $config) {
-    $this->configFactory->get('language.types')->setData($config)->save();
+  public function saveLanguageTypesConfiguration(array $values) {
+    $config = $this->configFactory->get('language.types');
+    if (isset($values['configurable'])) {
+      $config->set('configurable', $values['configurable']);
+    }
+    if (isset($values['all'])) {
+      $config->set('all', $values['all']);
+    }
+    $config->save();
   }
 
   /**
diff --git a/core/modules/language/lib/Drupal/language/Form/NegotiationConfigureForm.php b/core/modules/language/lib/Drupal/language/Form/NegotiationConfigureForm.php
index c5b2a667d46a4ccb2032d717834355bf6e22c066..24ae048af9135c42753026252f54cdc4d22754e7 100644
--- a/core/modules/language/lib/Drupal/language/Form/NegotiationConfigureForm.php
+++ b/core/modules/language/lib/Drupal/language/Form/NegotiationConfigureForm.php
@@ -150,8 +150,7 @@ public function submitForm(array &$form, array &$form_state) {
       }
 
       $method_weights_type[$type] = $method_weights;
-      // @todo convert this to config.
-      variable_set("language_negotiation_methods_weight_$type", $method_weights_input);
+      $this->config('language.types')->set('negotiation.' . $type . '.method_weights', $method_weights_input)->save();
     }
 
     // Update non-configurable language types and the related language
@@ -213,8 +212,8 @@ protected function configureFormTable(array &$form, $type)  {
     }
 
     $negotiation_info = $form['#language_negotiation_info'];
-    $enabled_methods = variable_get("language_negotiation_$type", array());
-    $methods_weight = variable_get("language_negotiation_methods_weight_$type", array());
+    $enabled_methods = $this->config('language.types')->get('negotiation.' . $type . '.enabled') ?: array();
+    $methods_weight = $this->config('language.types')->get('negotiation.' . $type . '.method_weights') ?: array();
 
     // Add missing data to the methods lists.
     foreach ($negotiation_info as $method_id => $method) {
diff --git a/core/modules/language/lib/Drupal/language/LanguageNegotiator.php b/core/modules/language/lib/Drupal/language/LanguageNegotiator.php
index f2a74f6c7ce744cf359475498059db7e8196f04c..1c8fd94f33d138e15429ede26cd27d1f4e915753 100644
--- a/core/modules/language/lib/Drupal/language/LanguageNegotiator.php
+++ b/core/modules/language/lib/Drupal/language/LanguageNegotiator.php
@@ -36,7 +36,7 @@ class LanguageNegotiator implements LanguageNegotiatorInterface {
   /**
    * The configuration factory.
    *
-   * @var \Drupal\Core\Config\config
+   * @var \Drupal\Core\Config\ConfigFactory
    */
   protected $configFactory;
 
@@ -138,7 +138,7 @@ public function initializeType($type) {
     if ($this->currentUser && $this->request) {
       // Execute the language negotiation methods in the order they were set up
       // and return the first valid language found.
-      foreach ($this->getConfiguration($type) as $method_id => $info) {
+      foreach ($this->getEnabledNegotiators($type) as $method_id => $info) {
         if (!isset($this->negotiatedLanguages[$method_id])) {
           $this->negotiatedLanguages[$method_id] = $this->negotiateLanguage($type, $method_id);
         }
@@ -166,13 +166,16 @@ public function initializeType($type) {
   }
 
   /**
-   * {@inheritdoc}
+   * Gets enabled detection methods for the provided language type.
+   *
+   * @param string $type
+   *   The language type.
+   *
+   * @return array
+   *   An array of enabled detection methods for the provided language type.
    */
-  protected function getConfiguration($type) {
-    // @todo convert to CMI https://drupal.org/node/1827038 and
-    //   https://drupal.org/node/2102477
-    drupal_bootstrap(DRUPAL_BOOTSTRAP_VARIABLES, FALSE);
-    return variable_get("language_negotiation_$type", array());
+  protected function getEnabledNegotiators($type) {
+    return $this->configFactory->get('language.types')->get('negotiation.' . $type . '.enabled') ?: array();
   }
 
   /**
@@ -218,8 +221,8 @@ protected function negotiateLanguage($type, $method_id) {
   public function getNegotiationMethods($type = NULL) {
     $definitions = $this->negotiatorManager->getDefinitions();
     if (isset($type)) {
-      $config = $this->getConfiguration($type);
-      $definitions = array_intersect_key($definitions, $config);
+      $enabled_methods = $this->getEnabledNegotiators($type);
+      $definitions = array_intersect_key($definitions, $enabled_methods);
     }
     return $definitions;
   }
@@ -242,8 +245,8 @@ public function getNegotiationMethodInstance($method_id) {
    * {@inheritdoc}
    */
   public function getPrimaryNegotiationMethod($type) {
-    $config = $this->getConfiguration($type);
-    return empty($config) ? LanguageNegotiatorInterface::METHOD_ID : key($config);
+    $enabled_methods = $this->getEnabledNegotiators($type);
+    return empty($enabled_methods) ? LanguageNegotiatorInterface::METHOD_ID : key($enabled_methods);
   }
 
   /**
@@ -254,8 +257,8 @@ public function isNegotiationMethodEnabled($method_id, $type = NULL) {
     $language_types = !empty($type) ? array($type) : $this->languageManager->getLanguageTypes();
 
     foreach ($language_types as $type) {
-      $config = $this->getConfiguration($type);
-      if (isset($config[$method_id])) {
+      $enabled_methods = $this->getEnabledNegotiators($type);
+      if (isset($enabled_methods[$method_id])) {
         $enabled = TRUE;
         break;
       }
@@ -267,13 +270,13 @@ public function isNegotiationMethodEnabled($method_id, $type = NULL) {
   /**
    * {@inheritdoc}
    */
-  function saveConfiguration($type, $method_weights) {
+  function saveConfiguration($type, $enabled_methods) {
     $definitions = $this->getNegotiationMethods();
     $default_types = $this->languageManager->getLanguageTypes();
 
     // Order the language negotiation method list by weight.
-    asort($method_weights);
-    foreach ($method_weights as $method_id => $weight) {
+    asort($enabled_methods);
+    foreach ($enabled_methods as $method_id => $weight) {
       if (isset($definitions[$method_id])) {
         $method = $definitions[$method_id];
         // If the language negotiation method does not express any preference
@@ -281,15 +284,14 @@ function saveConfiguration($type, $method_weights) {
         $types = array_flip(!empty($method['types']) ? $method['types'] : $default_types);
         // Check whether the method is defined and has the right type.
         if (!isset($types[$type])) {
-          unset($method_weights[$method_id]);
+          unset($enabled_methods[$method_id]);
         }
       }
       else {
-        unset($method_weights[$method_id]);
+        unset($enabled_methods[$method_id]);
       }
     }
-
-    variable_set("language_negotiation_$type", $method_weights);
+    $this->configFactory->get('language.types')->set('negotiation.' . $type . '.enabled', $enabled_methods)->save();
   }
 
   /**
@@ -303,7 +305,7 @@ function purgeConfiguration() {
     $this->negotiatorManager->clearCachedDefinitions();
     $this->languageManager->reset();
     foreach ($this->languageManager->getDefinedLanguageTypesInfo() as $type => $info) {
-      $this->saveConfiguration($type, $this->getConfiguration($type));
+      $this->saveConfiguration($type, $this->getEnabledNegotiators($type));
     }
   }
 
diff --git a/core/modules/language/lib/Drupal/language/LanguageNegotiatorInterface.php b/core/modules/language/lib/Drupal/language/LanguageNegotiatorInterface.php
index 0654fdec798b55fcab9ce65793e7954831a34631..d12fd6fab21600a8ab8eda0d418d19e804f8f747 100644
--- a/core/modules/language/lib/Drupal/language/LanguageNegotiatorInterface.php
+++ b/core/modules/language/lib/Drupal/language/LanguageNegotiatorInterface.php
@@ -196,10 +196,10 @@ public function isNegotiationMethodEnabled($method_id, $type = NULL);
    *
    * @param string $type
    *   The language type.
-   * @param array $method_weights
+   * @param array $enabled_methods
    *   An array of language negotiation method weights keyed by method ID.
    */
-  function saveConfiguration($type, $method_weights);
+  function saveConfiguration($type, $enabled_methods);
 
   /**
    * Resave the configuration to purge missing negotiation methods.
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageNegotiationInfoTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageNegotiationInfoTest.php
index 471dab28ee0ffd0d3757827880c61d106bbca7cb..58cbd722adabf2a9b90162ad939792658616fb96 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageNegotiationInfoTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageNegotiationInfoTest.php
@@ -91,7 +91,7 @@ function testInfoAlterations() {
     // negotiation settings with the proper flag enabled.
     \Drupal::state()->set('language_test.language_negotiation_info_alter', TRUE);
     $this->languageNegotiationUpdate();
-    $negotiation = variable_get("language_negotiation_$type", array());
+    $negotiation = \Drupal::config('language.types')->get('negotiation.' . $type . '.enabled') ?: array();
     $this->assertFalse(isset($negotiation[$interface_method_id]), 'Interface language negotiation method removed from the stored settings.');
     $this->assertNoFieldByXPath("//input[@name=\"$form_field\"]", NULL, 'Interface language negotiation method unavailable.');
 
@@ -131,7 +131,7 @@ function testInfoAlterations() {
 
     // Check that unavailable language negotiation methods are not present in
     // the negotiation settings.
-    $negotiation = variable_get("language_negotiation_$type", array());
+    $negotiation = \Drupal::config('language.types')->get('negotiation.' . $type . '.enabled') ?: array();
     $this->assertFalse(isset($negotiation[$test_method_id]), 'The disabled test language negotiation method is not part of the content language negotiation settings.');
 
     // Check that configuration page presents the correct options and settings.
@@ -173,7 +173,7 @@ protected function checkFixedLanguageTypes() {
     $configurable = $this->languageManager->getLanguageTypes();
     foreach ($this->languageManager->getDefinedLanguageTypesInfo() as $type => $info) {
       if (!in_array($type, $configurable) && isset($info['fixed'])) {
-        $negotiation = variable_get("language_negotiation_$type", array());
+        $negotiation = \Drupal::config('language.types')->get('negotiation.' . $type . '.enabled') ?: array();
         $equal = count($info['fixed']) == count($negotiation);
         while ($equal && list($id) = each($negotiation)) {
           list(, $info_id) = each($info['fixed']);
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index bc43db297da489948bd79acf30dcfae62b8d84b4..6dc144c9fd46f2b9845e2448cdb986e569f4f543 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -242,7 +242,9 @@ function testUILanguageNegotiation() {
 
     // Unknown language prefix should return 404.
     $definitions = \Drupal::languageManager()->getNegotiator()->getNegotiationMethods();
-    variable_set('language_negotiation_' . Language::TYPE_INTERFACE, array_flip(array_keys($definitions)));
+    \Drupal::config('language.types')
+      ->set('negotiation.' . Language::TYPE_INTERFACE . '.enabled', array_flip(array_keys($definitions)))
+      ->save();
     $this->drupalGet("$langcode_unknown/admin/config", array(), $http_header_browser_fallback);
     $this->assertResponse(404, "Unknown language path prefix should return 404");