diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index 8e14b36..eaae63f 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -219,3 +219,16 @@ config_dependencies:
       label: 'Theme dependencies'
       sequence:
         - type: string
+
+# Human readable string that is associated with a format.
+text_with_format:
+  type: mapping
+  label: 'Text with format'
+  mapping:
+    value:
+      type: text
+      label: 'Content'
+      translatable: true
+    format:
+      type: string
+      label: 'Text format'
diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/config_translation.module
index 256bfba..e2f19ee 100644
--- a/core/modules/config_translation/config_translation.module
+++ b/core/modules/config_translation/config_translation.module
@@ -186,12 +186,30 @@ function config_translation_entity_operation(EntityInterface $entity) {
 
 /**
  * Implements hook_config_translation_type_info_alter().
+ *
+ * @todo Convert this hook into a real typed data alter hook,
+ *   https://drupal.org/node/2145633.
  */
 function config_translation_config_translation_type_info_alter(&$definitions) {
+  $map = array(
+    'label' => '\Drupal\config_translation\FormElement\Textfield',
+    'text' => '\Drupal\config_translation\FormElement\Textarea',
+    'date_format' => '\Drupal\config_translation\FormElement\DateFormat',
+    'text_with_format' => '\Drupal\config_translation\FormElement\TextFormat',
+  );
+
   // Enhance the text and date type definitions with classes to generate proper
   // form elements in ConfigTranslationFormBase. Other translatable types will
   // appear as a one line textfield.
-  $definitions['text']['form_element_class'] = '\Drupal\config_translation\FormElement\Textarea';
-  $definitions['date_format']['form_element_class'] = '\Drupal\config_translation\FormElement\DateFormat';
+  foreach ($definitions as $type => &$definition) {
+    if (!isset($definition['form_element_class'])) {
+      if (isset($map[$definition['type']])) {
+        $definition['form_element_class'] = $map[$definition['type']];
+      }
+      elseif (!empty($definition['translatable'])) {
+        $definition['form_element_class'] = '\Drupal\config_translation\FormElement\Textfield';
+      }
+    }
+  }
 }
 
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php
index fb3ba88..edf9f7c 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php
@@ -194,7 +194,7 @@ public function buildForm(array $form, array &$form_state, Request $request = NU
     );
     foreach ($this->mapper->getConfigNames() as $name) {
       $form['config_names'][$name] = array('#type' => 'container');
-      $form['config_names'][$name] += $this->buildConfigForm($this->typedConfigManager->get($name), $config_factory->get($name)->get(), $this->baseConfigData[$name]);
+      $form['config_names'][$name] += $this->buildConfigForm($name, $this->typedConfigManager->get($name), $config_factory->get($name)->get(), $this->baseConfigData[$name]);
     }
 
     $form['actions']['#type'] = 'actions';
@@ -227,7 +227,7 @@ public function submitForm(array &$form, array &$form_state) {
       $config_translation = $this->languageManager->getLanguageConfigOverride($this->language->id, $name);
       $locations = $this->localeStorage->getLocations(array('type' => 'configuration', 'name' => $name));
 
-      $this->setConfig($this->language, $base_config, $config_translation, $form_values[$name], !empty($locations));
+      $this->setConfig($this->language, $base_config, $config_translation, $this->typedConfigManager->get($name), $form_values[$name], !empty($locations));
 
       // If no overrides, delete language specific configuration file.
       $saved_config = $config_translation->get();
@@ -249,6 +249,8 @@ public function submitForm(array &$form, array &$form_state) {
   /**
    * Formats configuration schema as a form tree.
    *
+   * @param string $name
+   *   The configuration name.
    * @param \Drupal\Core\Config\Schema\Element $schema
    *   Schema definition of configuration.
    * @param array|string $config_data
@@ -266,16 +268,33 @@ public function submitForm(array &$form, array &$form_state) {
    * @return array
    *   An associative array containing the structure of the form.
    */
-  protected function buildConfigForm(Element $schema, $config_data, $base_config_data, $open = TRUE, $base_key = '') {
+  protected function buildConfigForm($name, Element $schema, $config_data, $base_config_data, $open = TRUE, $base_key = '') {
     $build = array();
     foreach ($schema as $key => $element) {
       // Make the specific element key, "$base_key.$key".
       $element_key = implode('.', array_filter(array($base_key, $key)));
       $definition = $element->getDataDefinition() + array('label' => $this->t('N/A'));
-      if ($element instanceof Element) {
+
+      // Invoke hook_config_translation_type_info_alter() implementations to
+      // alter the configuration types.
+      $definitions = array(
+        $definition['type'] => &$definition,
+      );
+
+      $this->moduleHandler->alter('config_translation_type_info', $definitions);
+      $element_type = $definition['type'];
+
+      // When building the form we traverse the schema until we find an element
+      // with a form element class. When setting the config values in, we
+      // instead traverse the schema until we find a translatable element. This
+      // allows for for elements handling multiple schema parts only some of
+      // which are translatable. The TextFormat element requires this as the
+      // form inherently covers the 'format' property as well, even though that
+      // is not translatable.
+      if ($element instanceof Element && !isset($definitions[$element_type]['form_element_class'])) {
         // Build sub-structure and include it with a wrapper in the form
         // if there are any translatable elements there.
-        $sub_build = $this->buildConfigForm($element, $config_data[$key], $base_config_data[$key], FALSE, $element_key);
+        $sub_build = $this->buildConfigForm($name, $element, $config_data[$key], $base_config_data[$key], FALSE, $element_key);
         if (!empty($sub_build)) {
           // For some configuration elements the same element structure can
           // repeat multiple times, (like views displays, filters, etc.).
@@ -304,27 +323,16 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d
           ) + $sub_build;
         }
       }
-      else {
-        $definition = $element->getDataDefinition();
-
-        // Invoke hook_config_translation_type_info_alter() implementations to
-        // alter the configuration types.
-        $definitions = array(
-          $definition['type'] => &$definition,
-        );
-        $this->moduleHandler->alter('config_translation_type_info', $definitions);
-
-        // Create form element only for translatable items.
-        if (!isset($definition['translatable']) || !isset($definition['type'])) {
-          continue;
-        }
+      elseif (isset($definition['form_element_class'])) {
+        /** @var \Drupal\config_translation\FormElement\ElementInterface $form_element */
+        $form_element = new $definition['form_element_class']();
 
         $value = $config_data[$key];
         $build[$element_key] = array(
           '#theme' => 'config_translation_manage_form_element',
         );
         $build[$element_key]['source'] = array(
-          '#markup' => $base_config_data[$key] ? ('<span lang="' . $this->sourceLanguage->id . '">' . nl2br($base_config_data[$key] . '</span>')) : t('(Empty)'),
+          '#markup' => $form_element->getRenderedSource($base_config_data[$key], $this->sourceLanguage),
           '#title' => $this->t(
             '!label <span class="visually-hidden">(!source_language)</span>',
             array(
@@ -333,13 +341,22 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d
             )
           ),
           '#type' => 'item',
+          // The 'item' element generally receives input, but in this case it is
+          // both unnecessary and unwanted, as we only want one form value per
+          // configuration element.
+          // @see system_element_info()
+          '#input' => FALSE,
         );
 
-        $definition += array('form_element_class' => '\Drupal\config_translation\FormElement\Textfield');
-
-        /** @var \Drupal\config_translation\FormElement\ElementInterface $form_element */
-        $form_element = new $definition['form_element_class']();
         $build[$element_key]['translation'] = $form_element->getFormElement($definition, $this->language, $value);
+        // For accessibility we make source and translation appear next to each
+        // other in the source for each element, which is why we utilize the
+        // 'source' and 'translation' sub-keys for the form. The form values,
+        // however, should mirror the configuration structure, so that we can
+        // traverse the configuration schema in
+        // ConfigTranslationFormBase::setConfig(). Therefore, the 'translation'
+        // key is removed from the form parents.
+        $build[$element_key]['translation']['#parents'] = array_merge(array('config_names', $name), explode('.', $element_key));
       }
     }
     return $build;
@@ -354,6 +371,8 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d
    *   Base configuration values, in the source language.
    * @param \Drupal\Core\Config\Config $config_translation
    *   Translation configuration override data.
+   * @param \Drupal\Core\Config\Schema\Element $schema
+   *   Schema definition of configuration.
    * @param array $config_values
    *   A simple one dimensional or recursive array:
    *     - simple:
@@ -369,17 +388,28 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d
    *   (optional) Flag to specify whether the configuration had a shipped
    *   version and therefore should also be stored in the locale database.
    *
+   * @param null $base_key
    * @return array
    *   Translation configuration override data.
    */
-  protected function setConfig(Language $language, Config $base_config, Config $config_translation, array $config_values, $shipped_config = FALSE) {
-    foreach ($config_values as $key => $value) {
-      if (is_array($value) && !isset($value['translation'])) {
+  protected function setConfig(Language $language, Config $base_config, Config $config_translation, Element $schema, array $config_values, $shipped_config = FALSE, $base_key = NULL) {
+    foreach ($schema as $key => $element) {
+      if (!isset($config_values[$key])) {
+        continue;
+      }
+      $value = $config_values[$key];
+
+      $element_key = implode('.', array_filter(array($base_key, $key)));
+      $definition = $element->getDataDefinition();
+      // While the 'form_element_class' key is used for form building, the
+      // 'translatable' key is used for the setting of configuration values.
+      // This allows the form to contain values which will not be set, such as
+      // the TextFormat element's 'format' value.
+      if ($element instanceof Element && empty($definition['translatable'])) {
         // Traverse into this level in the configuration.
-        $this->setConfig($language, $base_config, $config_translation, $value, $shipped_config);
+        $this->setConfig($language, $base_config, $config_translation, $element, $value, $shipped_config, $element_key);
       }
       else {
-
         // If the configuration file being translated was originally shipped, we
         // should update the locale translation storage. The string should
         // already be there, but we make sure to check.
@@ -396,8 +426,8 @@ protected function setConfig(Language $language, Config $base_config, Config $co
 
           // If we have a new translation or different from what is stored in
           // locale before, save this as an updated customize translation.
-          if ($translation->isNew() || $translation->getString() != $value['translation']) {
-            $translation->setString($value['translation'])
+          if ($translation->isNew() || $translation->getString() != $value) {
+            $translation->setString($value)
               ->setCustomized()
               ->save();
           }
@@ -405,8 +435,8 @@ protected function setConfig(Language $language, Config $base_config, Config $co
 
         // Save value, if different from the source value in the base
         // configuration. If same as original configuration, remove override.
-        if ($base_config->get($key) !== $value['translation']) {
-          $config_translation->set($key, $value['translation']);
+        if ($base_config->get($key) !== $value) {
+          $config_translation->set($element_key, $value);
         }
         else {
           $config_translation->clear($key);
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/DateFormat.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/DateFormat.php
index 3abb57e..497728d 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/DateFormat.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/DateFormat.php
@@ -17,6 +17,8 @@
  * Defines the date format element for the configuration translation interface.
  */
 class DateFormat implements ElementInterface {
+
+  use SimpleSourceTrait;
   use StringTranslationTrait;
 
   /**
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php
index 9072cfc..188d02d 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php
@@ -29,4 +29,17 @@
    */
   public function getFormElement(array $definition, Language $language, $value);
 
+  /**
+   * Returns the rendered source element for a given configuration definition.
+   *
+   * @param array|string $base_config
+   *   The configuration value of the element in the source language.
+   * @param \Drupal\Core\Language\Language $source_language
+   *   Thee source language of the configuration object.
+   *
+   * @return string
+   *   The rendered value in source language.
+   */
+  public function getRenderedSource($base_config, Language $source_language);
+
 }
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/SimpleSourceTrait.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/SimpleSourceTrait.php
new file mode 100644
index 0000000..5d52567
--- /dev/null
+++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/SimpleSourceTrait.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config_translation\FormElement\SimpleSourceTrait.
+ */
+
+namespace Drupal\config_translation\FormElement;
+
+use Drupal\Core\Language\Language;
+
+/**
+ * Provides a trait for form element classes with a simple rendered source.
+ */
+trait SimpleSourceTrait {
+
+  /**
+   * Returns the rendered source element for a given configuration definition.
+   *
+   * @param array|string $base_config
+   *   The configuration value of the element in the source language.
+   * @param \Drupal\Core\Language\Language $source_language
+   *   Thee source language of the configuration object.
+   *
+   * @return string
+   *   The rendered value in source language.
+   *
+   * @see \Drupal\config_translation\FormElement\ElementInterface::getRenderedSource()
+   */
+  public function getRenderedSource($base_config, Language $source_language) {
+    return $base_config ? ('<span lang="' . $source_language->id . '">' . nl2br($base_config . '</span>')) : t('(Empty)');
+  }
+
+}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/TextFormat.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/TextFormat.php
new file mode 100644
index 0000000..2b1e494
--- /dev/null
+++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/TextFormat.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\config_translation\FormElement\TextFormat.
+ */
+
+namespace Drupal\config_translation\FormElement;
+
+use Drupal\Core\Language\Language;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+
+/**
+ * Defines the text_format element for the configuration translation interface.
+ */
+class TextFormat implements ElementInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormElement(array $definition, Language $language, $value) {
+    $element = array(
+      '#type' => 'text_format',
+      '#default_value' => $value['value'],
+      '#format' => $value['format'],
+      '#title' => $this->t($definition['label']) . '<span class="visually-hidden"> (' . $language->name . ')</span>',
+      '#attributes' => array('lang' => $language->id),
+    );
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRenderedSource($base_config, Language $source_language) {
+    $value = check_markup($base_config['value'], $base_config['format'], $source_language->id);
+    return $value ? '<span lang="' . $source_language->id . '">' . $value . '</span>' : t('(Empty)');
+  }
+
+}
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textarea.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textarea.php
index b796685..54110a1 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textarea.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textarea.php
@@ -14,6 +14,8 @@
  * Defines the textarea element for the configuration translation interface.
  */
 class Textarea implements ElementInterface {
+
+  use SimpleSourceTrait;
   use StringTranslationTrait;
 
   /**
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textfield.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textfield.php
index 46d71fe..7edbfd3 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textfield.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Textfield.php
@@ -14,6 +14,8 @@
  * Defines the textfield element for the configuration translation interface.
  */
 class Textfield implements ElementInterface {
+
+  use SimpleSourceTrait;
   use StringTranslationTrait;
 
   /**
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationFormTest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationFormTest.php
index c5bce3f..591c796 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationFormTest.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationFormTest.php
@@ -20,7 +20,7 @@ class ConfigTranslationFormTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = array('config_translation', 'config_translation_test');
+  public static $modules = array('config_translation', 'config_translation_test', 'editor');
 
   /**
    * The plugin ID of the mapper to test.
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
index 46ef47f..7c494b7 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php
@@ -9,7 +9,6 @@
 
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\Unicode;
-use Drupal\Core\Config\FileStorage;
 use Drupal\Core\Language\Language;
 use Drupal\simpletest\WebTestBase;
 
@@ -23,7 +22,7 @@ class ConfigTranslationUiTest extends WebTestBase {
    *
    * @var array
    */
-  public static $modules = array('node', 'contact', 'config_translation', 'config_translation_test', 'views', 'views_ui', 'contextual');
+  public static $modules = array('node', 'contact', 'config_translation', 'config_translation_test', 'views', 'views_ui', 'contextual', 'filter');
 
   /**
    * Languages to enable.
@@ -127,8 +126,8 @@ public function testSiteInformationTranslationUi() {
 
     // Update site name and slogan for French.
     $edit = array(
-      'config_names[system.site][name][translation]' => $fr_site_name,
-      'config_names[system.site][slogan][translation]' => $fr_site_slogan,
+      'config_names[system.site][name]' => $fr_site_name,
+      'config_names[system.site][slogan]' => $fr_site_slogan,
     );
 
     $this->drupalPostForm("$translation_base_url/fr/add", $edit, t('Save translation'));
@@ -141,8 +140,8 @@ public function testSiteInformationTranslationUi() {
 
     // Check translation saved proper.
     $this->drupalGet("$translation_base_url/fr/edit");
-    $this->assertFieldByName('config_names[system.site][name][translation]', $fr_site_name);
-    $this->assertFieldByName('config_names[system.site][slogan][translation]', $fr_site_slogan);
+    $this->assertFieldByName('config_names[system.site][name]', $fr_site_name);
+    $this->assertFieldByName('config_names[system.site][slogan]', $fr_site_slogan);
 
     // Check French translation of site name and slogan are in place.
     $this->drupalGet('fr');
@@ -170,8 +169,8 @@ public function testSourceValueDuplicateSave() {
 
     // Case 1: Update new value for site slogan and site name.
     $edit = array(
-      'config_names[system.site][name][translation]' => 'FR ' . $site_name,
-      'config_names[system.site][slogan][translation]' => 'FR ' . $site_slogan,
+      'config_names[system.site][name]' => 'FR ' . $site_name,
+      'config_names[system.site][slogan]' => 'FR ' . $site_slogan,
     );
     // First time, no overrides, so just Add link.
     $this->drupalPostForm("$translation_base_url/fr/add", $edit, t('Save translation'));
@@ -193,8 +192,8 @@ public function testSourceValueDuplicateSave() {
     $this->assertNoText('FR ' . $site_name);
     $this->assertNoText('FR ' . $site_slogan);
     $edit = array(
-      'config_names[system.site][name][translation]' => $site_name,
-      'config_names[system.site][slogan][translation]' => 'FR ' . $site_slogan,
+      'config_names[system.site][name]' => $site_name,
+      'config_names[system.site][slogan]' => 'FR ' . $site_slogan,
     );
     $this->drupalPostForm(NULL, $edit, t('Save translation'));
     $this->assertRaw(t('Successfully updated @language translation.', array('@language' => 'French')));
@@ -208,8 +207,8 @@ public function testSourceValueDuplicateSave() {
     $this->drupalGet("$translation_base_url/fr/edit");
     $this->assertNoText('FR ' . $site_slogan);
     $edit = array(
-      'config_names[system.site][name][translation]' => $site_name,
-      'config_names[system.site][slogan][translation]' => $site_slogan,
+      'config_names[system.site][name]' => $site_name,
+      'config_names[system.site][slogan]' => $site_slogan,
     );
     $this->drupalPostForm(NULL, $edit, t('Save translation'));
     $override = \Drupal::languageManager()->getLanguageConfigOverride('fr', 'system.site');
@@ -273,8 +272,8 @@ public function testContactConfigEntityTranslation() {
 
       // Update translatable fields.
       $edit = array(
-        'config_names[contact.category.feedback][label][translation]' => 'Website feedback - ' . $langcode,
-        'config_names[contact.category.feedback][reply][translation]' => 'Thank you for your mail - ' . $langcode,
+        'config_names[contact.category.feedback][label]' => 'Website feedback - ' . $langcode,
+        'config_names[contact.category.feedback][reply]' => 'Thank you for your mail - ' . $langcode,
       );
 
       // Save language specific version of form.
@@ -312,7 +311,7 @@ public function testContactConfigEntityTranslation() {
       $langcode_prefixes = array_merge(array(''), $this->langcodes);
       foreach ($langcode_prefixes as $langcode_prefix) {
         $this->drupalGet(ltrim("$langcode_prefix/$translation_base_url/$langcode/edit"));
-        $this->assertFieldByName('config_names[contact.category.feedback][label][translation]', 'Website feedback - ' . $langcode);
+        $this->assertFieldByName('config_names[contact.category.feedback][label]', 'Website feedback - ' . $langcode);
         $this->assertText($label);
       }
     }
@@ -402,8 +401,8 @@ public function testDateFormatTranslation() {
 
       // Update translatable fields.
       $edit = array(
-        'config_names[system.date_format.' . $id . '][label][translation]' => $id . ' - FR',
-        'config_names[system.date_format.' . $id . '][pattern][pattern.php][translation]' => 'D',
+        'config_names[system.date_format.' . $id . '][label]' => $id . ' - FR',
+        'config_names[system.date_format.' . $id . '][pattern][php]' => 'D',
       );
 
       // Save language specific version of form.
@@ -439,9 +438,9 @@ public function testAccountSettingsConfigurationTranslation() {
 
     // Update account settings fields for French.
     $edit = array(
-      'config_names[user.settings][anonymous][translation]' => 'Anonyme',
-      'config_names[user.mail][status_blocked][status_blocked.subject][translation]' => 'Testing, your account is blocked.',
-      'config_names[user.mail][status_blocked][status_blocked.body][translation]' => 'Testing account blocked body.',
+      'config_names[user.settings][anonymous]' => 'Anonyme',
+      'config_names[user.mail][status_blocked][subject]' => 'Testing, your account is blocked.',
+      'config_names[user.mail][status_blocked][body]' => 'Testing account blocked body.',
     );
 
     $this->drupalPostForm('admin/config/people/accounts/translate/fr/add', $edit, t('Save translation'));
@@ -450,7 +449,7 @@ public function testAccountSettingsConfigurationTranslation() {
     $this->drupalGet('admin/config/people/accounts/translate/fr/edit');
     foreach ($edit as $key => $value) {
       // Check the translations appear in the right field type as well.
-      $xpath = '//' . (strpos($key, '.body') ? 'textarea' : 'input') . '[@name="'. $key . '"]';
+      $xpath = '//' . (strpos($key, '[body]') ? 'textarea' : 'input') . '[@name="'. $key . '"]';
       $this->assertFieldByXPath($xpath, $value);
     }
     // Check that labels for email settings appear.
@@ -537,10 +536,10 @@ public function testViewsTranslationUI() {
 
     // Update Views Fields for French.
     $edit = array(
-      'config_names[views.view.frontpage][description][translation]' => $description . " FR",
-      'config_names[views.view.frontpage][label][translation]' => $human_readable_name . " FR",
-      'config_names[views.view.frontpage][display][default][display.default.display_title][translation]' => $display_settings_master . " FR",
-      'config_names[views.view.frontpage][display][default][display_options][display.default.display_options.title][translation]' => $display_options_master . " FR",
+      'config_names[views.view.frontpage][description]' => $description . " FR",
+      'config_names[views.view.frontpage][label]' => $human_readable_name . " FR",
+      'config_names[views.view.frontpage][display][default][display_title]' => $display_settings_master . " FR",
+      'config_names[views.view.frontpage][display][default][display_options][title]' => $display_options_master . " FR",
     );
     $this->drupalPostForm("$translation_base_url/fr/add", $edit, t('Save translation'));
     $this->assertRaw(t('Successfully saved @language translation.', array('@language' => 'French')));
@@ -552,10 +551,10 @@ public function testViewsTranslationUI() {
 
     // Check translation saved proper.
     $this->drupalGet("$translation_base_url/fr/edit");
-    $this->assertFieldByName('config_names[views.view.frontpage][description][translation]', $description . " FR");
-    $this->assertFieldByName('config_names[views.view.frontpage][label][translation]', $human_readable_name . " FR");
-    $this->assertFieldByName('config_names[views.view.frontpage][display][default][display.default.display_title][translation]', $display_settings_master . " FR");
-    $this->assertFieldByName('config_names[views.view.frontpage][display][default][display_options][display.default.display_options.title][translation]', $display_options_master . " FR");
+    $this->assertFieldByName('config_names[views.view.frontpage][description]', $description . " FR");
+    $this->assertFieldByName('config_names[views.view.frontpage][label]', $human_readable_name . " FR");
+    $this->assertFieldByName('config_names[views.view.frontpage][display][default][display_title]', $display_settings_master . " FR");
+    $this->assertFieldByName('config_names[views.view.frontpage][display][default][display_options][title]', $display_options_master . " FR");
   }
 
   /**
@@ -586,7 +585,7 @@ public function testLocaleDBStorage() {
 
     // Add custom translation.
     $edit = array(
-      'config_names[user.settings][anonymous][translation]' => 'Anonyme',
+      'config_names[user.settings][anonymous]' => 'Anonyme',
     );
     $this->drupalPostForm('admin/config/people/accounts/translate/fr/add', $edit, t('Save translation'));
 
@@ -597,7 +596,7 @@ public function testLocaleDBStorage() {
 
     // revert custom translations to base translation.
     $edit = array(
-      'config_names[user.settings][anonymous][translation]' => 'Anonymous',
+      'config_names[user.settings][anonymous]' => 'Anonymous',
     );
     $this->drupalPostForm('admin/config/people/accounts/translate/fr/edit', $edit, t('Save translation'));
 
@@ -655,6 +654,55 @@ public function testAlterInfo() {
   }
 
   /**
+   * Test text_format translation.
+   */
+  public function testTextFormatTranslation() {
+    $this->drupalLogin($this->admin_user);
+    /** @var \Drupal\Core\Config\ConfigFactoryInterface $config_factory */
+    $config_factory = $this->container->get('config.factory');
+
+    $expected = array(
+      'value' => '<strong>Hello World</strong>',
+      'format' => 'plain_text',
+    );
+    $actual = $config_factory
+      ->setOverrideState(FALSE)
+      ->get('config_translation_test.content')
+      ->get('content');
+    $this->assertEqual($expected, $actual);
+
+    $translation_base_url = 'admin/config/media/file-system/translate';
+    $this->drupalGet($translation_base_url);
+
+    // 'Add' link should be present for French translation.
+    $translation_page_url = "$translation_base_url/fr/add";
+    $this->assertLinkByHref($translation_page_url);
+
+    $this->drupalGet($translation_page_url);
+
+    // Update translatable fields.
+    $edit = array(
+      'config_names[config_translation_test.content][content][value]' => '<strong>Hello World</strong> - FR',
+    );
+
+    // Save language specific version of form.
+    $this->drupalPostForm($translation_page_url, $edit, t('Save translation'));
+
+    // Get translation and check we've got the right value.
+    $expected = array(
+      'value' => '<strong>Hello World</strong> - FR',
+      'format' => 'plain_text',
+    );
+    $this->container->get('language.config_factory_override')
+      ->setLanguage(new Language(array('id' => 'fr')));
+    $actual = $config_factory
+      ->setOverrideState(TRUE)
+      ->get('config_translation_test.content')
+      ->get('content');
+    $this->assertEqual($expected, $actual);
+  }
+
+  /**
    * Gets translation from locale storage.
    *
    * @param $config_name
diff --git a/core/modules/config_translation/tests/modules/config_translation_test/config/install/config_translation_test.content.yml b/core/modules/config_translation/tests/modules/config_translation_test/config/install/config_translation_test.content.yml
new file mode 100644
index 0000000..55aa430
--- /dev/null
+++ b/core/modules/config_translation/tests/modules/config_translation_test/config/install/config_translation_test.content.yml
@@ -0,0 +1,6 @@
+id: test
+label: 'Test'
+langcode: en
+content:
+  value: "<strong>Hello World</strong>"
+  format: plain_text
diff --git a/core/modules/config_translation/tests/modules/config_translation_test/config/schema/config_translation_test.schema.yml b/core/modules/config_translation/tests/modules/config_translation_test/config/schema/config_translation_test.schema.yml
new file mode 100644
index 0000000..3fcaac3
--- /dev/null
+++ b/core/modules/config_translation/tests/modules/config_translation_test/config/schema/config_translation_test.schema.yml
@@ -0,0 +1,18 @@
+# Schema for the configuration files of the Configuration translation test module.
+
+config_translation_test.content:
+  type: mapping
+  label: 'Content'
+  mapping:
+    id:
+      type: string
+      label: 'Category identifier'
+    label:
+      type: label
+      label: 'Label'
+    langcode:
+      type: string
+      label: 'Default language'
+    content:
+      type: text_with_format
+      label: 'Content'
diff --git a/core/modules/config_translation/tests/modules/config_translation_test/config_translation_test.config_translation.yml b/core/modules/config_translation/tests/modules/config_translation_test/config_translation_test.config_translation.yml
new file mode 100644
index 0000000..070245c
--- /dev/null
+++ b/core/modules/config_translation/tests/modules/config_translation_test/config_translation_test.config_translation.yml
@@ -0,0 +1,6 @@
+# Attach to file settings for testing. The base route does not matter.
+system.file_system_settings:
+  title: 'Test config translation'
+  base_route_name: system.file_system_settings
+  names:
+    - config_translation_test.content
diff --git a/core/modules/config_translation/tests/themes/config_translation_test_theme/config_translation_test_theme.config_translation.yml b/core/modules/config_translation/tests/themes/config_translation_test_theme/config_translation_test_theme.config_translation.yml
index 7c8cdd8..5d84070 100644
--- a/core/modules/config_translation/tests/themes/config_translation_test_theme/config_translation_test_theme.config_translation.yml
+++ b/core/modules/config_translation/tests/themes/config_translation_test_theme/config_translation_test_theme.config_translation.yml
@@ -1,3 +1,4 @@
+# Attach to performance settings for testing. The base route does not matter.
 system.performance_settings:
   title: 'Theme translation test'
   base_route_name: system.performance_settings
