diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
index 1285cb7..c69b705 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
@@ -60,6 +60,29 @@ public function __construct($string, array $arguments = array(), array $options
   }
 
   /**
+   * Get the string value stored in this translation wrapper.
+   *
+   * @return string
+   *   The string stored in this wrapper.
+   */
+  public function getString() {
+    return $this->string;
+  }
+
+  /**
+   * Get a specific option from this translation wrapper.
+   *
+   * @param $name
+   *   Option name.
+   *
+   * @return mixed
+   *   The value of this option or empty string of option is not set.
+   */
+  public function getOption($name) {
+    return isset($this->options[$name]) ? $this->options[$name] : '';
+  }
+
+  /**
    * Implements the magic __toString() method.
    */
   public function __toString() {
diff --git a/core/modules/config_translation/src/ConfigNamesMapper.php b/core/modules/config_translation/src/ConfigNamesMapper.php
index b681b33..e771d3a 100644
--- a/core/modules/config_translation/src/ConfigNamesMapper.php
+++ b/core/modules/config_translation/src/ConfigNamesMapper.php
@@ -465,7 +465,7 @@ public function hasTranslatable() {
    */
   public function hasTranslation(LanguageInterface $language) {
     foreach ($this->getConfigNames() as $name) {
-      if ($this->localeConfigManager->hasTranslation($name, $language)) {
+      if ($this->localeConfigManager->hasTranslation($name, $language->getId())) {
         return TRUE;
       }
     }
diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc
index 357aaf8..a4677ca 100644
--- a/core/modules/locale/locale.bulk.inc
+++ b/core/modules/locale/locale.bulk.inc
@@ -324,7 +324,7 @@ function locale_translate_batch_refresh(array &$context) {
   }
   elseif ($name = array_shift($context['sandbox']['refresh']['names'])) {
     // Refresh all languages for one object at a time.
-    $count = locale_config_update_multiple(array($name), $context['sandbox']['refresh']['languages']);
+    $count = Locale::config()->updateConfigTranslations(array($name), $context['sandbox']['refresh']['languages']);
     $context['results']['stats']['config'] += $count;
     // Inherit finished information from the "parent" string lookup step so
     // visual display of status will make sense.
@@ -532,7 +532,7 @@ function locale_translate_delete_translation_files(array $projects = array(), ar
  *   The batch definition.
  */
 function locale_config_batch_update_components(array $options, array $langcodes = array(), array $components = array()) {
-  $langcodes = $langcodes ? $langcodes : array_keys(locale_translatable_language_list());
+  $langcodes = $langcodes ? $langcodes : array_keys(\Drupal::languageManager()->getLanguages());
   if ($langcodes && $names = \Drupal\locale\Locale::config()->getComponentNames($components)) {
     return locale_config_batch_build($names, $langcodes, $options);
   }
@@ -606,7 +606,7 @@ function locale_config_batch_refresh_name(array $names, array $langcodes, array
   if (!isset($context['result']['stats']['config'])) {
     $context['result']['stats']['config'] = 0;
   }
-  $context['result']['stats']['config'] += locale_config_update_multiple($names, $langcodes);
+  $context['result']['stats']['config'] += Locale::config()->updateConfigTranslations($names, $langcodes);
   foreach ($names as $name) {
     $context['result']['names'][] = $name;
   }
@@ -639,41 +639,3 @@ function locale_config_batch_finished($success, array $results) {
     }
   }
 }
-
-/**
- * Updates all configuration for names / languages.
- *
- * @param array $names
- *   Array of names of configuration objects to update.
- * @param array $langcodes
- *   (optional) Array of language codes to update. Defaults to all languages.
- *
- * @return int
- *   Number of configuration objects retranslated.
- */
-function locale_config_update_multiple(array $names, array $langcodes = array()) {
-  /** @var \Drupal\language\ConfigurableLanguageManagerInterface $language_manager */
-  $language_manager = \Drupal::languageManager();
-  $locale_config_manager = Locale::config();
-
-  $langcodes = $langcodes ? $langcodes : array_keys(locale_translatable_language_list());
-  $count = 0;
-  foreach ($names as $name) {
-    $wrapper = $locale_config_manager->get($name);
-    foreach ($langcodes as $langcode) {
-      $translation = $wrapper->getValue() ? $wrapper->getTranslation($langcode)->getValue() : NULL;
-      if ($translation) {
-        $locale_config_manager->saveTranslationData($name, $langcode, $translation);
-        $count++;
-      }
-      else {
-        // Do not bother deleting language overrides which do not exist in the
-        // first place.
-        if (!$language_manager->getLanguageConfigOverride($langcode, $name)->isNew()) {
-          $locale_config_manager->deleteTranslationData($name, $langcode);
-        }
-      }
-    }
-  }
-  return $count;
-}
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 971b47d..a109ac4 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -24,6 +24,7 @@
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\language\ConfigurableLanguageInterface;
 use Drupal\Component\Utility\Crypt;
+use Drupal\locale\Locale;
 
 /**
  * Regular expression pattern used to localize JavaScript strings.
@@ -226,7 +227,7 @@ function locale_configurable_language_delete(ConfigurableLanguageInterface $lang
   locale_translate_delete_translation_files(array(), array($language->id()));
 
   // Remove translated configuration objects.
-  \Drupal\locale\Locale::config()->deleteLanguageTranslations($language->id());
+  Locale::config()->deleteLanguageTranslations($language->id());
 
   // Changing the language settings impacts the interface:
   _locale_invalidate_js($language->id());
@@ -313,6 +314,7 @@ function locale_get_plural($count, $langcode = NULL) {
  */
 function locale_modules_installed($modules) {
   $components['module'] = $modules;
+  locale_system_set_config_langcodes($components);
   locale_system_update($components);
 }
 
@@ -329,6 +331,7 @@ function locale_module_preuninstall($module) {
  */
 function locale_themes_installed($themes) {
   $components['theme'] = $themes;
+  locale_system_set_config_langcodes($components);
   locale_system_update($components);
 }
 
@@ -356,6 +359,41 @@ function locale_cron() {
 }
 
 /**
+ * Update default configuration when new modules or themes are installed.
+ *
+ * @param array $components
+ *   An array of arrays of component (theme and/or module) names to import
+ *   translations for, indexed by type.
+ */
+function locale_system_set_config_langcodes(array $components) {
+  // Need to rewrite some default configuration language codes if the default
+  // site language is not English.
+  $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId();
+  if ($default_langcode != 'en') {
+    // If just installed the locale module, we need to update all prior
+    // shipped configuration to the foreign site language. Otherwise keep the
+    // components list received to just update the shipped configuration just
+    // imported.
+    if (isset($components['module']) && in_array('locale', $components['module'])) {
+      $components = array();
+    }
+    $names = Locale::config()->getComponentNames($components);
+
+    foreach ($names as $name) {
+      $config = \Drupal::configFactory()->getEditable($name);
+      // Should only update if still exists in active configuration. If locale
+      // module is enabled later, then some configuration may not exist anymore.
+      if (!$config->isNew()) {
+        $langcode = $config->get('langcode');
+        if (empty($langcode) || $langcode == 'en') {
+          $config->set('langcode', $default_langcode)->save();
+        }
+      }
+    }
+  }
+}
+
+/**
  * Imports translations when new modules or themes are installed.
  *
  * This function will start a batch to import translations for the added
@@ -411,8 +449,6 @@ function locale_system_remove($components) {
   if ($language_list = locale_translatable_language_list()) {
     module_load_include('compare.inc', 'locale');
     \Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');
-    // Delete configuration translations.
-    \Drupal\locale\Locale::config()->deleteComponentTranslations($components, array_keys($language_list));
 
     // Only when projects are removed, the translation files and records will be
     // deleted. Not each disabled module will remove a project, e.g., sub
@@ -1020,19 +1056,14 @@ function _locale_refresh_translations($langcodes, $lids = array()) {
 /**
  * Refreshes configuration after string translations have been updated.
  *
- * The information that will be refreshed includes:
- * - JavaScript translations.
- * - Locale cache.
- *
  * @param array $langcodes
  *   Language codes for updated translations.
  * @param array $lids
  *   List of string identifiers that have been updated / created.
  */
 function _locale_refresh_configuration(array $langcodes, array $lids) {
-  if ($lids && $langcodes && $names = \Drupal\locale\Locale::config()->getStringNames($lids)) {
-    \Drupal::moduleHandler()->loadInclude('locale', 'bulk.inc');
-    locale_config_update_multiple($names, $langcodes);
+  if ($lids && $langcodes && $names = Locale::config()->getStringNames($lids)) {
+    Locale::config()->updateConfigTranslations($names, $langcodes);
   }
 }
 
diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml
index 27cef2c..95683b3 100644
--- a/core/modules/locale/locale.services.yml
+++ b/core/modules/locale/locale.services.yml
@@ -22,6 +22,6 @@ services:
       - { name: stream_wrapper, scheme: translations }
   locale.config_subscriber:
     class: Drupal\locale\LocaleConfigSubscriber
-    arguments: ['@locale.storage', '@config.factory', '@locale.config.typed']
+    arguments: ['@locale.storage', '@config.factory', '@locale.config.typed', '@language_manager']
     tags:
       - { name: event_subscriber }
diff --git a/core/modules/locale/src/LocaleConfigManager.php b/core/modules/locale/src/LocaleConfigManager.php
index aee2d59..1fa9e2f 100644
--- a/core/modules/locale/src/LocaleConfigManager.php
+++ b/core/modules/locale/src/LocaleConfigManager.php
@@ -7,33 +7,54 @@
 
 namespace Drupal\locale;
 
-use Drupal\Core\Config\TypedConfigManagerInterface;
-use Drupal\Core\Config\StorageInterface;
 use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Language\LanguageInterface;
+use Drupal\Core\Config\StorageInterface;
+use Drupal\Core\Config\TypedConfigManagerInterface;
+use Drupal\Core\StringTranslation\TranslationWrapper;
+use Drupal\Core\TypedData\TraversableTypedDataInterface;
+use Drupal\Core\TypedData\TypedDataInterface;
 use Drupal\language\ConfigurableLanguageManagerInterface;
 
 /**
- * Manages localized configuration type plugins.
+ * Manages configuration supported in part by interface translation.
+ *
+ * This manager is responsible to update configuration overrides and active
+ * translations when interface translation data changes. This allows Drupal to
+ * translate user roles, views, blocks, etc. after Drupal has been installed
+ * using the locale module's storage. When translations change in locale,
+ * LocaleConfigManager::updateConfigTranslations() is invoked to update the
+ * corresponding storage of the translation (in active storage or overrides).
+ *
+ * The saved changes result in configuration events to fire, which would make
+ * LocaleConfigSubscriber write back to the interface translation storage. To
+ * stop that from happening in case we initiate the writes from here, the
+ * $isUpdatingFromLocale flag is maintained, which is queried by
+ * LocaleConfigSubscriber.
+ *
+ * In turn when translated configuration or configuration language overrides are
+ * changed, it is the responsibility of LocaleConfigSubscriber to update locale
+ * storage.
  */
 class LocaleConfigManager {
 
   /**
-   * A storage instance for reading configuration data.
+   * The storage instance for reading configuration data.
    *
    * @var \Drupal\Core\Config\StorageInterface
    */
   protected $configStorage;
 
   /**
-   * A storage instance for reading default configuration data.
+   * The storage instance for reading default configuration data.
    *
    * @var \Drupal\Core\Config\StorageInterface
    */
   protected $installStorage;
 
   /**
-   * A string storage for reading and writing translations.
+   * The string storage for reading and writing translations.
+   *
+   * @var \Drupal\locale\StringStorageInterface;
    */
   protected $localeStorage;
 
@@ -66,11 +87,17 @@ class LocaleConfigManager {
   protected $typedConfigManager;
 
   /**
-   * Whether or not configuration translations are currently being updated.
+   * Whether or not configuration translations are being updated from locale.
+   *
+   * In this case, LocaleConfigManager is in control of the process and the
+   * reference data is locale's storage. This is used to let
+   * LocaleConfigSubscriber know that it does not need to feed back to locale.
+   * On the other hand, when not updating from locale and configuration
+   * translations change, we need to feed back to the locale storage.
    *
    * @var bool
    */
-  protected $isUpdating = FALSE;
+  protected $isUpdatingFromLocale = FALSE;
 
   /**
    * Creates a new typed configuration manager.
@@ -99,61 +126,113 @@ public function __construct(StorageInterface $config_storage, StorageInterface $
   }
 
   /**
-   * Gets locale wrapper with typed configuration data.
+   * Gets array of translation wrappers for translatable configuration.
    *
    * @param string $name
    *   Configuration object name.
    *
-   * @return \Drupal\locale\LocaleTypedConfig
-   *   Locale-wrapped configuration element.
+   * @return array
+   *   Array of translatable elements of the default configuration in $name.
    */
-  public function get($name) {
-    // Read default and current configuration data.
-    $default = $this->installStorageRead($name);
-    $updated = $this->configStorage->read($name);
-    // We get only the data that didn't change from default.
-    $data = $this->compareConfigData($default, $updated);
-    $definition = $this->typedConfigManager->getDefinition($name);
-    $data_definition = $this->typedConfigManager->buildDataDefinition($definition, $data);
-    // Unless the configuration has a explicit language code we assume English.
-    $langcode = isset($default['langcode']) ? $default['langcode'] : 'en';
-    $wrapper = new LocaleTypedConfig($data_definition, $name, $langcode, $this, $this->typedConfigManager, $this->languageManager);
-    $wrapper->setValue($data);
-    return $wrapper;
+  public function getTranslatableDefaultConfig($name) {
+    if ($this->isSupported($name)) {
+      // Create typed configuration wrapper based on install storage data.
+      $data = $this->installStorageRead($name);
+      $type_definition = $this->typedConfigManager->getDefinition($name);
+      $data_definition = $this->typedConfigManager->buildDataDefinition($type_definition, $data);
+      $typed_config = $this->typedConfigManager->create($data_definition, $data);
+      return $this->getTranslatableData($typed_config);
+    }
   }
 
   /**
-   * Compares default configuration with updated data.
+   * Gets translatable configuration data for a typed configuration element.
    *
-   * @param array $default
-   *   Default configuration data.
-   * @param array|false $updated
-   *   Current configuration data, or FALSE if no configuration data existed.
+   * @param \Drupal\Core\TypedData\TypedDataInterface $element
+   *   Typed configuration element.
    *
-   * @return array
-   *   The elements of default configuration that haven't changed.
+   * @return array|\Drupal\Core\StringTranslation\TranslationWrapper
+   *   Configuration data children of $element filtered to translatable children
+   *   returned in a nested array modeled after the structure of the
+   *   configuration. The leaf elements are TranslationWrapper instances to
+   *   translate later as needed.
    */
-  protected function compareConfigData(array $default, $updated) {
-    // Speed up comparison, specially for install operations.
-    if ($default === $updated) {
-      return $default;
+  protected function getTranslatableData(TypedDataInterface $element) {
+    $translatable = array();
+    if ($element instanceof TraversableTypedDataInterface) {
+      foreach ($element as $key => $property) {
+        $value = $this->getTranslatableData($property);
+        if (!empty($value)) {
+          $translatable[$key] = $value;
+        }
+      }
     }
-    $result = array();
-    foreach ($default as $key => $value) {
-      if (isset($updated[$key])) {
-        if (is_array($value)) {
-          $result[$key] = $this->compareConfigData($value, $updated[$key]);
+    else {
+      $definition = $element->getDataDefinition();
+      if (!empty($definition['translatable'])) {
+        $options = array();
+        if (isset($definition['translation context'])) {
+          $options['context'] = $definition['translation context'];
+        }
+        return new TranslationWrapper($element->getValue(), array(), $options);
+      }
+    }
+    return $translatable;
+  }
+
+  /**
+   * Process the translatable data array with a given language.
+   *
+   * If the given language is translatable, will return the translated copy
+   * which will only contain strings that had translations. If the given
+   * language is English and is not translatable, will return a simplified
+   * array of the English source strings only.
+   *
+   * @param string $name
+   *   The configuration name.
+   * @param array $active
+   *   The active configuration data.
+   * @param array $translatable
+   *   The translatable array structure, see this::getTranslatableData().
+   * @param string $langcode
+   *   The language code to process the array with
+   *
+   * @return array
+   *   Processed translatable data array. Will only contain translations
+   *   different from source strings or in case of untranslatable English, the
+   *   source strings themselves.
+   */
+  protected function processTranslatableData($name, array $active, array $translatable, $langcode) {
+    $translated = array();
+    foreach ($translatable as $key => $item) {
+      if (!isset($active[$key])) {
+        continue;
+      }
+      if (is_array($item)) {
+        // Only add this key if there was a translated value underneath.
+        $value = $this->processTranslatableData($name, $active[$key], $item, $langcode);
+        if (!empty($value)) {
+          $translated[$key] = $value;
+        }
+      }
+      else {
+        /** @var \Drupal\Core\StringTranslation\TranslationWrapper $item */
+        if ($langcode != 'en' || locale_translate_english()) {
+          $value = $this->translateString($name, $langcode, $item->getString(), $item->getOption('context'));
         }
-        elseif ($value === $updated[$key]) {
-          $result[$key] = $value;
+        else {
+          $value = $item->getString();
+        }
+        if (!empty($value)) {
+          $translated[$key] = $value;
         }
       }
     }
-    return $result;
+    return $translated;
   }
 
   /**
-   * Saves translated configuration data.
+   * Saves translated configuration override.
    *
    * @param string $name
    *   Configuration object name.
@@ -162,10 +241,24 @@ protected function compareConfigData(array $default, $updated) {
    * @param array $data
    *   Configuration data to be saved, that will be only the translated values.
    */
-  public function saveTranslationData($name, $langcode, array $data) {
-    $this->isUpdating = TRUE;
+  public function saveTranslationOverride($name, $langcode, array $data) {
+    $this->isUpdatingFromLocale = TRUE;
     $this->languageManager->getLanguageConfigOverride($langcode, $name)->setData($data)->save();
-    $this->isUpdating = FALSE;
+    $this->isUpdatingFromLocale = FALSE;
+  }
+
+  /**
+   * Saves translated configuration data.
+   *
+   * @param string $name
+   *   Configuration object name.
+   * @param array $data
+   *   Configuration data to be saved with translations merged in.
+   */
+  public function saveTranslationActive($name, array $data) {
+    $this->isUpdatingFromLocale = TRUE;
+    $this->configFactory->getEditable($name)->setData($data)->save();
+    $this->isUpdatingFromLocale = FALSE;
   }
 
   /**
@@ -176,10 +269,10 @@ public function saveTranslationData($name, $langcode, array $data) {
    * @param string $langcode
    *   Language code.
    */
-  public function deleteTranslationData($name, $langcode) {
-    $this->isUpdating = TRUE;
+  public function deleteTranslationOverride($name, $langcode) {
+    $this->isUpdatingFromLocale = TRUE;
     $this->languageManager->getLanguageConfigOverride($langcode, $name)->delete();
-    $this->isUpdating = FALSE;
+    $this->isUpdatingFromLocale = FALSE;
   }
 
   /**
@@ -192,7 +285,7 @@ public function deleteTranslationData($name, $langcode) {
    * @return array
    *   Array of configuration object names.
    */
-  public function getComponentNames(array $components) {
+  public function getComponentNames(array $components = array()) {
     $components = array_filter($components);
     if ($components) {
       $names = array();
@@ -209,27 +302,6 @@ public function getComponentNames(array $components) {
   }
 
   /**
-   * Deletes configuration translations for uninstalled components.
-   *
-   * @param array $components
-   *   Array with string identifiers.
-   * @param array $langcodes
-   *   Array of language codes.
-   */
-  public function deleteComponentTranslations(array $components, array $langcodes) {
-    $this->isUpdating = TRUE;
-    $names = $this->getComponentNames($components);
-    if ($names && $langcodes) {
-      foreach ($names as $name) {
-        foreach ($langcodes as $langcode) {
-          $this->deleteTranslationData($name, $langcode);
-        }
-      }
-    }
-    $this->isUpdating = FALSE;
-  }
-
-  /**
    * Gets configuration names associated with strings.
    *
    * @param array $lids
@@ -254,12 +326,12 @@ public function getStringNames(array $lids) {
    *   Language code to delete.
    */
   public function deleteLanguageTranslations($langcode) {
-    $this->isUpdating = TRUE;
+    $this->isUpdatingFromLocale = TRUE;
     $storage = $this->languageManager->getLanguageConfigOverrideStorage($langcode);
     foreach ($storage->listAll() as $name) {
       $this->languageManager->getLanguageConfigOverride($langcode, $name)->delete();
     }
-    $this->isUpdating = FALSE;
+    $this->isUpdatingFromLocale = FALSE;
   }
 
   /**
@@ -334,25 +406,158 @@ public function translateString($name, $langcode, $source, $context) {
    *
    * @param string $name
    *   Configuration name.
-   * @param \Drupal\Core\Language\LanguageInterface $language
-   *   A language object.
+   * @param string $langcode
+   *   A language code.
    *
    * @return bool
    *   A boolean indicating if a language has configuration translations.
    */
-  public function hasTranslation($name, LanguageInterface $language) {
-    $translation = $this->languageManager->getLanguageConfigOverride($language->getId(), $name);
+  public function hasTranslation($name, $langcode) {
+    $translation = $this->languageManager->getLanguageConfigOverride($langcode, $name);
     return !$translation->isNew();
   }
 
   /**
+   * Returns the original language code for this shipped configuration.
+   *
+   * @param $name
+   *   The configuration name.
+   *
+   * @return null|string
+   *   Language code of the original shipped configuration. NULL if no such
+   *   default configuration.
+   */
+  public function defaultConfigLangcode($name) {
+    $shipped = $this->installStorageRead($name);
+    if (!empty($shipped)) {
+      return !empty($shipped['langcode']) ? $shipped['langcode'] : 'en';
+    }
+  }
+
+  /**
+   * Returns the current language code for this active configuration.
+   *
+   * @param $name
+   *   The configuration name.
+   *
+   * @return null|string
+   *   Language code of the current active configuration. NULL if no such active
+   *   configuration.
+   */
+  public function activeConfigLangcode($name) {
+    $active = $this->configStorage->read($name);
+    if (!empty($active)) {
+      return !empty($active['langcode']) ? $active['langcode'] : 'en';
+    }
+  }
+
+  /**
+   * Whether the given configuration is supported for interface translation.
+   *
+   * @param $name
+   *   The configuration name.
+   *
+   * @return bool
+   *   TRUE if interface translation is supported.
+   */
+  public function isSupported($name) {
+    return $this->defaultConfigLangcode($name) == 'en' && !is_null($this->activeConfigLangcode($name));
+  }
+
+  /**
    * Indicates whether configuration translations are currently being updated.
    *
    * @return bool
    *   Whether or not configuration translations are currently being updated.
+   *   If TRUE, LocaleConfigManager is in control of the process and the
+   *   reference data is locale's storage. Changes made to active configuration
+   *   and overrides in this case should not feed back to locale storage.
+   */
+  public function isUpdatingTranslationsFromLocale() {
+    return $this->isUpdatingFromLocale;
+  }
+
+  /**
+   * Updates all configuration translations for the names / languages provided.
+   *
+   * To be used when interface translation changes result in the need to update
+   * configuration translations to keep them in sync.
+   *
+   * @param array $names
+   *   Array of names of configuration objects to update.
+   * @param array $langcodes
+   *   (optional) Array of language codes to update. Defaults to all
+   *   configurable languages.
+   *
+   * @return int
+   *   Number of configuration objects updated (saved).
    */
-  public function isUpdatingConfigTranslations() {
-    return $this->isUpdating;
+  public function updateConfigTranslations(array $names, array $langcodes = array()) {
+    $langcodes = $langcodes ? $langcodes : array_keys($this->languageManager->getLanguages());
+    $count = 0;
+    foreach ($names as $name) {
+      // Only deal with configuration which was shipped.
+      if (!$this->isSupported($name)) {
+        continue;
+      }
+
+      $translatable = $this->getTranslatableDefaultConfig($name);
+      $active_langcode = $this->activeConfigLangcode($name);
+      $active = $this->configStorage->read($name);
+
+      foreach ($langcodes as $langcode) {
+        $processed = $this->processTranslatableData($name, $active, $translatable, $langcode);
+        if (empty($processed)) {
+          continue;
+        }
+        if ($langcode != $active_langcode) {
+          // If the language code is not the same as the active storage
+          // language, we should update a configuration override.
+          if (!empty($processed)) {
+            // Update translation data in configuration override.
+            $this->saveTranslationOverride($name, $langcode, $processed);
+            $count++;
+          }
+          elseif (!$this->languageManager->getLanguageConfigOverride($langcode, $name)->isNew()) {
+            // Delete language override if override exists.
+            $this->deleteTranslationOverride($name, $langcode);
+          }
+        }
+        elseif ($langcode != 'en' || locale_translate_english()) {
+          // If the language code is the active storage language, we should
+          // update. If it is English, we should only update if English is also
+          // translatable.
+          $active = $this->mergeToActiveConfig($active, $processed);
+          $this->saveTranslationActive($name, $active);
+        }
+      }
+    }
+    return $count;
+  }
+
+  /**
+   * Merge translation data to the active configuration data.
+   *
+   * @param array $active
+   *   Active configuration array.
+   * @param array $translated
+   *   Translated configuration array.
+   * @return array
+   *   The merged array. Only items from $active will be present merged with
+   *   alternate value items from $translated.
+   */
+  protected function mergeToActiveConfig(array $active, array $translated) {
+    foreach ($translated as $key => $item) {
+      if (isset($active[$key])) {
+        if (is_array($item)) {
+          $active[$key] = $this->mergeToActiveConfig($active[$key], $translated[$key]);
+        }
+        else {
+          $active[$key] = $item;
+        }
+      }
+    }
+    return $active;
   }
 
   /**
diff --git a/core/modules/locale/src/LocaleConfigSubscriber.php b/core/modules/locale/src/LocaleConfigSubscriber.php
index 6c42d50..2c32cda 100644
--- a/core/modules/locale/src/LocaleConfigSubscriber.php
+++ b/core/modules/locale/src/LocaleConfigSubscriber.php
@@ -6,33 +6,45 @@
 
 namespace Drupal\locale;
 
-use Drupal\Core\Config\Config;
+use Drupal\Core\Config\ConfigCrudEvent;
+use Drupal\Core\Config\ConfigEvents;
 use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\TypedData\TraversableTypedDataInterface;
-use Drupal\language\Config\LanguageConfigOverride;
+use Drupal\Core\Config\StorableConfigBase;
+use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\language\Config\LanguageConfigOverrideCrudEvent;
 use Drupal\language\Config\LanguageConfigOverrideEvents;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 /**
- * Updates corresponding string translation when language overrides change.
+ * Updates strings translation when configuration translations change.
  *
- * This reacts to the updating or deleting of configuration language overrides.
- * It checks whether there are string translations associated with the
- * configuration that is being saved and, if so, updates those string
- * translations with the new configuration values and marks them as customized.
- * That way manual updates to configuration will not be inadvertently reverted
- * when updated translations from https://localize.drupal.org are being
- * imported.
+ * This reacts to the updates of translated active configuration and
+ * configuration language overrides. When those updates involve configuration
+ * which was available as default configuration, we need to feed back changes
+ * to any item which was originally part of that configuration to the interface
+ * translation storage. Those updated translations are saved as customized, so
+ * further community translation updates will not undo user changes.
+ *
+ * The active configuration or configuration language override changes may
+ * be initiated by locale data changes themselves. In that case,
+ * LocaleConfigManager is the initiator and it maintains a flag to consult, so
+ * we can ignore the changes in those cases, because such changes made should
+ * already be up to date in locale storage.
+ *
+ * This subscriber does not respond to deleting active configuration or deleting
+ * configuration translations. The locale storage is additive and we cannot be
+ * sure that only a given configuration translation used a source string. So
+ * we should not remove the translations from locale storage in these cases. The
+ * configuration or override would itself be deleted either way.
  */
 class LocaleConfigSubscriber implements EventSubscriberInterface {
 
   /**
-   * The string storage.
+   * The string storage for reading and writing translations.
    *
    * @var \Drupal\locale\StringStorageInterface;
    */
-  protected $stringStorage;
+  protected $localeStorage;
 
   /**
    * The configuration factory.
@@ -49,6 +61,13 @@ class LocaleConfigSubscriber implements EventSubscriberInterface {
   protected $localeConfigManager;
 
   /**
+   * The language manager.
+   *
+   * @var \Drupal\Core\Language\LanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
    * Constructs a LocaleConfigSubscriber.
    *
    * @param \Drupal\locale\StringStorageInterface $string_storage
@@ -58,134 +77,93 @@ class LocaleConfigSubscriber implements EventSubscriberInterface {
    * @param \Drupal\locale\LocaleConfigManager $locale_config_manager
    *   The typed configuration manager.
    */
-  public function __construct(StringStorageInterface $string_storage, ConfigFactoryInterface $config_factory, LocaleConfigManager $locale_config_manager) {
-    $this->stringStorage = $string_storage;
+  public function __construct(StringStorageInterface $string_storage, ConfigFactoryInterface $config_factory, LocaleConfigManager $locale_config_manager, LanguageManagerInterface $language_manager) {
+    $this->localeStorage = $string_storage;
     $this->configFactory = $config_factory;
     $this->localeConfigManager = $locale_config_manager;
+    $this->languageManager = $language_manager;
   }
 
   /**
    * {@inheritdoc}
    */
   public static function getSubscribedEvents() {
-    $events[LanguageConfigOverrideEvents::SAVE_OVERRIDE] = 'onSave';
-    $events[LanguageConfigOverrideEvents::DELETE_OVERRIDE] = 'onDelete';
+    $events[LanguageConfigOverrideEvents::SAVE_OVERRIDE] = 'onOverrideSave';
+    $events[ConfigEvents::SAVE] = 'onConfigSave';
     return $events;
   }
 
-
   /**
-   * Updates the translation strings when shipped configuration is saved.
+   * Updates the locale strings when a translated active configuration is saved.
    *
-   * @param \Drupal\language\Config\LanguageConfigOverrideCrudEvent $event
-   *   The language configuration event.
+   * @param \Drupal\Core\Config\ConfigCrudEvent $event
+   *   The configuration event.
    */
-  public function onSave(LanguageConfigOverrideCrudEvent $event) {
-    // Do not mark strings as customized when community translations are being
-    // imported.
-    if ($this->localeConfigManager->isUpdatingConfigTranslations()) {
-      $callable = [$this, 'saveTranslation'];
+  public function onConfigSave(ConfigCrudEvent $event) {
+    // Only attempt to feed back configuration translation changes to locale if
+    // the update itself was not initiated by locale data changes.
+    if (!$this->localeConfigManager->isUpdatingTranslationsFromLocale()) {
+      $config = $event->getConfig();
+      $langcode = $config->get('langcode') ?: 'en';
+      $this->updateLocaleStorage($config, $langcode);
     }
-    else {
-      $callable = [$this, 'saveCustomizedTranslation'];
-    }
-
-    $this->updateTranslationStrings($event, $callable);
   }
 
   /**
-   * Updates the translation strings when shipped configuration is deleted.
+   * Updates the locale strings when a configuration override is saved.
    *
    * @param \Drupal\language\Config\LanguageConfigOverrideCrudEvent $event
    *   The language configuration event.
    */
-  public function onDelete(LanguageConfigOverrideCrudEvent $event) {
-    if ($this->localeConfigManager->isUpdatingConfigTranslations()) {
-      $callable = [$this, 'deleteTranslation'];
+  public function onOverrideSave(LanguageConfigOverrideCrudEvent $event) {
+    // Only attempt to feed back configuration override changes to locale if
+    // the update itself was not initiated by locale data changes.
+    if (!$this->localeConfigManager->isUpdatingTranslationsFromLocale()) {
+      $translation_config = $event->getLanguageConfigOverride();
+      $langcode = $translation_config->getLangcode();
+      $this->updateLocaleStorage($translation_config, $langcode);
     }
-    else {
-      // Do not delete the string, but save a customized translation with the
-      // source value so that the deletion will not be reverted by importing
-      // community translations.
-      // @see \Drupal\locale\LocaleConfigSubscriber::saveCustomizedTranslation()
-      $callable = [$this, 'saveCustomizedTranslation'];
-    }
-
-    $this->updateTranslationStrings($event, $callable);
   }
 
   /**
-   * Updates the translation strings of shipped configuration.
+   * Update locale storage based on configuration translations.
    *
-   * @param \Drupal\language\Config\LanguageConfigOverrideCrudEvent $event
-   *   The language configuration event.
-   * @param $callable
-   *   A callable to apply to each translatable string of the configuration.
+   * @param \Drupal\Core\Config\StorableConfigBase $config
+   *   Active configuration or configuration translation override.
+   * @param string $langcode
+   *   The language code of $config.
    */
-  protected function updateTranslationStrings(LanguageConfigOverrideCrudEvent $event, $callable) {
-    $translation_config = $event->getLanguageConfigOverride();
-    $name = $translation_config->getName();
-
-    // Only do anything if the configuration was shipped.
-    if ($this->stringStorage->getLocations(['type' => 'configuration', 'name' => $name])) {
-      $source_config = $this->configFactory->getEditable($name);
-      $schema = $this->localeConfigManager->get($name)->getTypedConfig();
-      $this->traverseSchema($schema, $source_config, $translation_config, $callable);
+  protected function updateLocaleStorage(StorableConfigBase $config, $langcode) {
+    $name = $config->getName();
+    if ($this->localeConfigManager->isSupported($name) && ($langcode != 'en' || locale_translate_english())) {
+      $translatables = $this->localeConfigManager->getTranslatableDefaultConfig($name);
+      $this->processTranslatableData($name, $config->get(), $translatables, $langcode);
     }
   }
 
   /**
-   * Traverses configuration schema and applies a callback to each leaf element.
-   *
-   * It skips leaf elements that are not translatable.
-   *
-   * @param \Drupal\Core\TypedData\TraversableTypedDataInterface $schema
-   *   The respective configuration schema.
-   * @param callable $callable
-   *   The callable to apply to each leaf element. The callable will be called
-   *   with the leaf element and the element key as arguments.
-   * @param string|null $base_key
-   *   (optional) The base key that the schema belongs to. This should be NULL
-   *   for the top-level schema and be populated consecutively when recursing
-   *   into the schema structure.
+   * Process the translatable data array with a given language.
+   *
+   * @param string $name
+   *   The configuration name.
+   * @param array $active
+   *   The active configuration data or override data.
+   * @param array $translatable
+   *   The translatable array structure, see this::getTranslatableData().
+   * @param string $langcode
+   *   The language code to process the array with.
    */
-  protected function traverseSchema(TraversableTypedDataInterface $schema, Config $source_config, LanguageConfigOverride $translation_config, $callable, $base_key = NULL) {
-    foreach ($schema as $key => $element) {
-      $element_key = implode('.', array_filter([$base_key, $key]));
-
-      // We only care for strings here, so traverse the schema further in the
-      // case of traversable elements.
-      if ($element instanceof TraversableTypedDataInterface) {
-        $this->traverseSchema($element, $source_config, $translation_config, $callable, $element_key);
+  protected function processTranslatableData($name, array $active, array $translatable, $langcode) {
+    foreach ($translatable as $key => $item) {
+      if (!isset($active[$key])) {
+        continue;
       }
-      // Skip elements which are not translatable.
-      elseif (!empty($element->getDataDefinition()['translatable'])) {
-        $callable(
-          $source_config->get($element_key),
-          $translation_config->getLangcode(),
-          $translation_config->get($element_key)
-        );
+      if (is_array($item)) {
+        $this->processTranslatableData($name, $active[$key], $item, $langcode);
       }
-    }
-  }
-
-  /**
-   * Saves a translation string.
-   *
-   * @param string $source_value
-   *   The source string value.
-   * @param string $langcode
-   *   The language code of the translation.
-   * @param string|null $translation_value
-   *   (optional) The translation string value. If omitted, no translation will
-   *   be saved.
-   */
-  protected function saveTranslation($source_value, $langcode, $translation_value = NULL) {
-    if ($translation_value && ($translation = $this->getTranslation($source_value, $langcode, TRUE))) {
-      if ($translation->isNew() || $translation->getString() != $translation_value) {
-        $translation
-          ->setString($translation_value)
-          ->save();
+      else {
+        /** @var \Drupal\Core\StringTranslation\TranslationWrapper $item */
+        $this->saveCustomizedTranslation($name, $item->getString(), $item->getOption('context'), $active[$key], $langcode);
       }
     }
   }
@@ -193,77 +171,32 @@ protected function saveTranslation($source_value, $langcode, $translation_value
   /**
    * Saves a translation string and marks it as customized.
    *
-   * @param string $source_value
+   * @param string $name
+   *   The configuration name.
+   * @param string $source
    *   The source string value.
+   * @param string $context
+   *   The source string context.
+   * @param string $translation
+   *   The translation string.
    * @param string $langcode
    *   The language code of the translation.
-   * @param string|null $translation_value
-   *   (optional) The translation string value. If omitted, a customized string
-   *   with the source value will be saved.
-   *
-   * @see \Drupal\locale\LocaleConfigSubscriber::onDelete()
    */
-  protected function saveCustomizedTranslation($source_value, $langcode, $translation_value = NULL) {
-    if ($translation = $this->getTranslation($source_value, $langcode, TRUE)) {
-      if (!isset($translation_value)) {
-        $translation_value = $source_value;
-      }
-      if ($translation->isNew() || $translation->getString() != $translation_value) {
-        $translation
-          ->setString($translation_value)
+  protected function saveCustomizedTranslation($name, $source, $context, $translation, $langcode) {
+    // If the source is still the same as the translation, keep it as-is, to let
+    // locale to later update translations.
+    if ($source != $translation) {
+      $locale_translation = $this->localeConfigManager->translateString($name, $langcode, $source, $context);
+      // If the translation is the same as we already have in locale, keep it
+      // as-is, ie. don't set customized.
+      if ($translation != $locale_translation) {
+        $string = $this->localeStorage->findTranslation(array('source' => $source, 'context' => $context, 'language' => $langcode));
+        $string
+          ->setString($translation)
           ->setCustomized(TRUE)
           ->save();
       }
     }
   }
 
-  /**
-   * Deletes a translation string, if it exists.
-   *
-   * @param string $source_value
-   *   The source string value.
-   * @param string $langcode
-   *   The language code of the translation.
-   *
-   * @see \Drupal\locale\LocaleConfigSubscriber::onDelete()
-   */
-  protected function deleteTranslation($source_value, $langcode) {
-    if ($translation = $this->getTranslation($source_value, $langcode, FALSE)) {
-      $translation->delete();
-    }
-  }
-
-  /**
-   * Gets a translation string.
-   *
-   * @param string $source_value
-   *   The source string value.
-   * @param string $langcode
-   *   The language code of the translation.
-   * @param bool $create_fallback
-   *   (optional) By default if a source string could be found and no
-   *   translation in the given language exists yet, a translation object is
-   *   created. This can be circumvented by passing FALSE.
-   *
-   * @return \Drupal\locale\TranslationString|null
-   *   The translation string if one was found or created.
-   */
-  protected function getTranslation($source_value, $langcode, $create_fallback = TRUE) {
-    // There is no point in creating a translation without a source.
-    if ($source_string = $this->stringStorage->findString(['source' => $source_value])) {
-      // Get the translation for this original source string from locale.
-      $conditions = [
-        'lid' => $source_string->lid,
-        'language' => $langcode,
-      ];
-      $translations = $this->stringStorage->getTranslations($conditions + ['translated' => TRUE]);
-      if ($translations) {
-        return reset($translations);
-      }
-      elseif ($create_fallback) {
-        return $this->stringStorage->createTranslation($conditions);
-      }
-    }
-  }
-
 }
diff --git a/core/modules/locale/src/LocaleTypedConfig.php b/core/modules/locale/src/LocaleTypedConfig.php
deleted file mode 100644
index ca31a38..0000000
--- a/core/modules/locale/src/LocaleTypedConfig.php
+++ /dev/null
@@ -1,209 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\locale\LocaleTypedConfig.
- */
-
-namespace Drupal\locale;
-
-use Drupal\Core\Language\LanguageManagerInterface;
-use Drupal\Core\TypedData\ContextAwareInterface;
-use Drupal\Core\TypedData\DataDefinitionInterface;
-use Drupal\Core\Config\Schema\Element;
-use Drupal\Core\Config\TypedConfigManagerInterface;
-use Drupal\Core\TypedData\TraversableTypedDataInterface;
-use Drupal\Core\TypedData\TypedDataInterface;
-
-/**
- * Defines the locale configuration wrapper object.
- */
-class LocaleTypedConfig extends Element {
-
-  /**
-   * The typed configuration data.
-   *
-   * @var \Drupal\Core\Config\Schema\Element
-   */
-  protected $typedConfig;
-
-  /**
-   * The language code for which this is a translation.
-   *
-   * @var string
-   */
-  protected $langcode;
-
-  /**
-   * The locale configuration manager object.
-   *
-   * @var \Drupal\locale\LocaleConfigManager
-   */
-  protected $localeConfig;
-
-  /**
-   * The typed config manager.
-   *
-   * @var \Drupal\Core\Config\TypedConfigManagerInterface
-   */
-  protected $typedConfigManager;
-
-  /**
-   * The language manager.
-   *
-   * @var \Drupal\Core\Language\LanguageManagerInterface
-   */
-  protected $languageManager;
-
-  /**
-   * Constructs a configuration wrapper object.
-   *
-   * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition
-   *   The data definition.
-   * @param string $name
-   *   The configuration object name.
-   * @param string $langcode
-   *   Language code for the source configuration data.
-   * @param \Drupal\locale\LocaleConfigManager $locale_config
-   *   The locale configuration manager object.
-   * @param \Drupal\locale\TypedConfigManagerInterface $typed_config;
-   *   The typed configuration manager interface.
-   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
-   *   The language manager.
-   */
-  public function __construct(DataDefinitionInterface $definition, $name, $langcode, LocaleConfigManager $locale_config, TypedConfigManagerInterface $typed_config, LanguageManagerInterface $language_manager) {
-    parent::__construct($definition, $name);
-    $this->langcode = $langcode;
-    $this->localeConfig = $locale_config;
-    $this->typedConfigManager = $typed_config;
-    $this->languageManager = $language_manager;
-  }
-
-  /**
-   * Gets wrapped typed config object.
-   */
-  public function getTypedConfig() {
-    return $this->typedConfigManager->create($this->definition, $this->value);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTranslation($langcode) {
-    $options = array(
-      'source' => $this->langcode,
-      'target' => $langcode,
-    );
-    $data = $this->getElementTranslation($this->getTypedConfig(), $options);
-    return $this->typedConfigManager->create($this->definition, $data);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function language() {
-    return $this->languageManager->getLanguage($this->langcode);
-  }
-
-  /**
-   * Checks whether we can translate these languages.
-   *
-   * @param string $from_langcode
-   *   Source language code.
-   * @param string $to_langcode
-   *   Destination language code.
-   *
-   * @return bool
-   *   TRUE if this translator supports translations for these languages.
-   */
-  protected function canTranslate($from_langcode, $to_langcode) {
-    if ($from_langcode == 'en') {
-      return TRUE;
-    }
-    return FALSE;
-  }
-
-  /**
-   * Gets translated configuration data for a typed configuration element.
-   *
-   * @param \Drupal\Core\TypedData\TypedDataInterface $element
-   *   Typed configuration element.
-   * @param array $options
-   *   Array with translation options that must contain the keys defined in
-   *   \Drupal\locale\LocaleTypedConfig::translateElement().
-   *
-   * @return array
-   *   Configuration data translated to the requested language if available,
-   *   an empty array otherwise.
-   */
-  protected function getElementTranslation(TypedDataInterface $element, array $options) {
-    $translation = array();
-    if ($element instanceof TraversableTypedDataInterface) {
-      $translation = $this->getArrayTranslation($element, $options);
-    }
-    elseif ($this->translateElement($element, $options)) {
-      $translation = $element->getValue();
-    }
-    return $translation;
-  }
-
-  /**
-   * Gets translated configuration data for a traversable element.
-   *
-   * @param \Drupal\Core\TypedData\TraversableTypedDataInterface $element
-   *   Typed configuration array element.
-   * @param array $options
-   *   Array with translation options that must contain the keys defined in
-   *   \Drupal\locale\LocaleTypedConfig::translateElement().
-   *
-   * @return array
-   *   Configuration data translated to the requested language.
-   */
-  protected function getArrayTranslation(TraversableTypedDataInterface $element, array $options) {
-    $translation = array();
-    foreach ($element as $key => $property) {
-      $value = $this->getElementTranslation($property, $options);
-      if (!empty($value)) {
-        $translation[$key] = $value;
-      }
-    }
-    return $translation;
-  }
-
-  /**
-   * Translates element's value if it fits our translation criteria.
-   *
-   * For an element to be translatable by locale module it needs to be of base
-   * type 'string' and have 'translatable = TRUE' in the element's definition.
-   * Translatable elements may use these additional keys in their data
-   * definition:
-   * - 'translatable', FALSE to opt out of translation.
-   * - 'translation context', to define the string context.
-   *
-   * @param \Drupal\Core\TypedData\TypedDataInterface $element
-   *   Configuration element.
-   * @param array $options
-   *   Array with translation options that must contain the following keys:
-   *   - 'source', Source language code.
-   *   - 'target', Target language code.
-   *
-   * @return bool
-   *   Whether the element fits the translation criteria.
-   */
-  protected function translateElement(TypedDataInterface $element, array $options) {
-    if ($this->canTranslate($options['source'], $options['target'])) {
-      $definition = $element->getDataDefinition();
-      $value = $element->getValue();
-      if ($value && !empty($definition['translatable'])) {
-        $context = isset($definition['translation context']) ? $definition['translation context'] : '';
-        if ($translation = $this->localeConfig->translateString($this->name, $options['target'], $value, $context)) {
-          $element->setValue($translation);
-          return TRUE;
-        }
-      }
-    }
-    // The element does not have a translation.
-    return FALSE;
-  }
-
-}
diff --git a/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php b/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php
index f3f7415..6b2e27d 100644
--- a/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php
+++ b/core/modules/locale/src/Tests/LocaleConfigSubscriberTest.php
@@ -162,7 +162,7 @@ public function testLocaleDeleteTranslation() {
    */
   protected function setUpNoTranslation($config_name, $key, $source) {
     // Add a source string with the configuration name as a location. This gets
-    // called from locale_config_update_multiple() normally.
+    // called from LocaleConfigManager::updateConfigTranslations() normally.
     $this->localeConfigManager->translateString($config_name, $this->langcode, $source, '');
     $this->languageManager
       ->setConfigOverrideLanguage(ConfigurableLanguage::load($this->langcode));
@@ -192,8 +192,8 @@ protected function setUpNoTranslation($config_name, $key, $source) {
   protected function setUpTranslation($config_name, $key, $source, $translation) {
     // Create source and translation strings for the configuration value and add
     // the configuration name as a location. This would be performed by
-    // locale_translate_batch_import() and locale_config_update_multiple()
-    // normally.
+    // locale_translate_batch_import() and
+    // LocaleConfigManager::updateConfigTranslations() normally.
     $source_object = $this->stringStorage->createString([
       'source' => $source,
       'context' => '',
@@ -256,7 +256,7 @@ protected function saveLanguageOverride($config_name, $key, $value) {
    */
   protected function saveLocaleTranslationData($config_name, $key, $value) {
     $this->localeConfigManager
-      ->saveTranslationData($config_name, $this->langcode, [$key => $value]);
+      ->saveTranslationOverride($config_name, $this->langcode, [$key => $value]);
     $this->configFactory->reset($config_name);
 
     $this->assertConfigValue($config_name, $key, $value);
@@ -308,7 +308,7 @@ protected function deleteLanguageOverride($config_name, $key, $source_value) {
    *   from the configuration factory after the deletion.
    */
   protected function deleteLocaleTranslationData($config_name, $key, $source_value) {
-    $this->localeConfigManager->deleteTranslationData($config_name, $this->langcode);
+    $this->localeConfigManager->deleteTranslationOverride($config_name, $this->langcode);
     $this->configFactory->reset($config_name);
 
     $this->assertConfigValue($config_name, $key, $source_value);
diff --git a/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php b/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php
index 27f120d..afd6de9 100644
--- a/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php
+++ b/core/modules/locale/src/Tests/LocaleConfigTranslationTest.php
@@ -79,7 +79,7 @@ public function testConfigTranslation() {
     );
     $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
 
-    $wrapper = $this->container->get('locale.config.typed')->get('system.site');
+    $wrapper = $this->container->get('locale.config.typed')->getTranslatableDefaultConfig('system.site');
 
     // Get translation and check we've only got the site name.
     $translation = $wrapper->getTranslation($langcode);
@@ -109,7 +109,7 @@ public function testConfigTranslation() {
     );
     $this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
 
-    $wrapper = $this->container->get('locale.config.typed')->get('core.date_format.medium');
+    $wrapper = $this->container->get('locale.config.typed')->getTranslatableDefaultConfig('core.date_format.medium');
 
     // Get translation and check we've only got the site name.
     $translation = $wrapper->getTranslation($langcode);
@@ -162,7 +162,7 @@ public function testConfigTranslation() {
     $this->assertTrue(count($translations) == 1 && $translation->source == $string->source && $translation->translation == $image_style_label, 'Got only one translation for image configuration.');
 
     // Try more complex configuration data.
-    $wrapper = $this->container->get('locale.config.typed')->get('image.style.medium');
+    $wrapper = $this->container->get('locale.config.typed')->getTranslatableDefaultConfig('image.style.medium');
 
     $translation = $wrapper->getTranslation($langcode);
     $property = $translation->get('label');
