diff --git a/modules/local_translation_content/css/preview.css b/modules/local_translation_content/css/preview.css
new file mode 100644
index 0000000..0d2f138
--- /dev/null
+++ b/modules/local_translation_content/css/preview.css
@@ -0,0 +1,6 @@
+.local-translation-preview td {
+  vertical-align: text-top;
+}
+.field--type-image .local-translation-preview td {
+  vertical-align: top;
+}
diff --git a/modules/local_translation_content/js/fields_translations_preview.js b/modules/local_translation_content/js/fields_translations_preview.js
new file mode 100644
index 0000000..b4fd60e
--- /dev/null
+++ b/modules/local_translation_content/js/fields_translations_preview.js
@@ -0,0 +1,206 @@
+(function ($, Drupal) {
+  'use strict';
+
+  Drupal.behaviors.fieldsTranslationsPreview = {
+    attach: function (context, settings) {
+      var translations    = settings.localTranslationFieldsTranslationsPreview;
+      var currentLanguage = settings.localTranslationCurrentLanguageName;
+      if (translations) {
+        var prefix = 'field--name-';
+        $.each(translations, function (name, table) {
+          var $field, label_selector, $preview, $label,
+            $row, $last_row, $container, $legend;
+          if (name.indexOf('_summary') === -1) {
+            $field = $('.' + prefix + name.split('_').join('-'), context);
+            label_selector = '.form-item > label:not([for*="format"],[for*="alt"],[for*="title"]), .form-item > label[for*="title-0-value"]';
+            if (!$field.length) {
+              $field = $('.form-item-' + name.split('_').join('-'), context);
+              label_selector = 'label:not([for*="format"],[for*="alt"],[for*="title"]), label[for*="title-0-value"]';
+            }
+            if ($field.length > 0) {
+              if (!isContainerExists($field)) {
+                $('<div class="local-translation-preview"></div>')
+                  .insertAfter($field.find(label_selector));
+              }
+              $(table).appendTo(
+                $field.find('.local-translation-preview')
+              );
+
+              $preview = $field.find('.local-translation-preview');
+              $label = $preview.prev();
+              $preview.detach().prependTo($field);
+              $label.detach().prependTo($field);
+              $label.removeClass('option');
+              // Prepare new table row.
+              $row = $('<tr><td></td><td>' + currentLanguage + '</td></td>');
+              // Inherit odd/even classes flow
+              // to prevent any style bugs.
+              $last_row = $(table).find('tr:last');
+              if ($last_row.hasClass('odd')) {
+                $row.addClass('even');
+              }
+              else if ($last_row.hasClass('even')) {
+                $row.addClass('odd');
+              }
+              $container = $row.find('td:first');
+              appendFieldRecursive($container, $field);
+              $field.find('label[for$="summary"]').hide();
+              // Additional fix for fieldset's "legend" element.
+              $legend = $container.find('fieldset legend');
+              if ($legend.length > 0) {
+                $legend.detach().prependTo($field);
+                $($field.find('legend')[0])
+                  .replaceWith('<label>' + $legend.html() + '</label>');
+              }
+              $row.appendTo($field.find('.local-translation-preview table tbody'));
+            }
+          }
+          else {
+            var field_name = name.replace('_summary', '');
+            $field = $('.field--type-text-with-summary.field--name-' + field_name.replace('_', '-'), context);
+            if ($field.length) {
+              label_selector = 'label[for$="summary"]';
+              if ($field.find(label_selector).find('.local-translation-preview').length < 2) {
+                $('<div class="local-translation-preview"></div>')
+                  .appendTo($field);
+              }
+              $(table).appendTo(
+                $field.find('.local-translation-preview')
+              );
+              var $summary = $field.find('textarea[name$="[summary]"]')
+                .closest('.text-summary-wrapper');
+
+              // Prepare new table row.
+              $row = $('<tr><td></td><td>' + currentLanguage + '</td></td>');
+              // Inherit odd/even classes flow
+              // to prevent any style bugs.
+              $last_row = $(table).find('tr:last');
+              if ($last_row.hasClass('odd')) {
+                $row.addClass('even');
+              }
+              else if ($last_row.hasClass('even')) {
+                $row.addClass('odd');
+              }
+              $container = $row.find('td:first');
+              $summary.detach().appendTo($container);
+              $row.appendTo($field.find('.local-translation-preview:last() table tbody'));
+              var field_label = $field.find('label[for$="value"]').text();
+              $field.find(label_selector).text($field.find(label_selector).text() + ' (' + field_label + ')');
+              $field.find(label_selector).show();
+              $field.find(label_selector).detach()
+                .insertBefore($field.find('.local-translation-preview:last()'));
+              $field.find('.local-translation-preview:first() label[for$="summary"]').remove();
+            }
+          }
+        });
+
+        // Cleanup redundant tables.
+        $('.local-translation-preview', context).each(function () {
+          var $tables = $(this).find('table');
+          if ($tables.length > 1) {
+            for (var i = 1; i <= $tables.length; i++) {
+              if ($tables[i]) {
+                $tables[i].remove();
+              }
+            }
+          }
+        });
+      }
+
+      /**
+       * Recursively rebuild the HTML structure of the field element.
+       *
+       * @param {jQuery} $container
+       *   Container DOM.
+       * @param {jQuery} $field
+       *   Field DOM.
+       *
+       * @return null
+       *   NULL when the recursive iterations are finished.
+       */
+      function appendFieldRecursive($container, $field) {
+        var $input = $($field.find('.local-translation-preview').next()[0]);
+        if ($input.length < 1) {
+          return null;
+        }
+        $input.detach().prependTo($container);
+        $container.find('.local-translation-preview').remove();
+        return appendFieldRecursive($container, $field);
+      }
+
+      /**
+       * Check if table container was already attached.
+       *
+       * @param {Object} $field
+       *   JQuery DOM object.
+       *
+       * @return {Boolean}
+       *   TRUE - if container is already exists, FALSE otherwise.
+       */
+      function isContainerExists($field) {
+        return $field.find('label')
+          .next()
+          .hasClass('local-translation-preview');
+      }
+    }
+  };
+
+  Drupal.behaviors.summaryExpandingHandler = {
+    attach: function (context, settings) {
+      // Fix the behavior of the opening/closing textarea
+      // for the summary sub-field.
+      $(window).on('load', function () {
+        var $container = $('.local-translation-preview', context);
+        if ($container.length > 0) {
+          var $link = $container.find('button.link-edit-summary');
+          if ($link.length > 0) {
+            $link.on('click', function (event) {
+              $container = $(this).closest('.local-translation-preview').parent();
+              var $summary_wrapper = $container.find('tr:last td .text-summary-wrapper');
+              if ($summary_wrapper.css('display') === 'none') {
+                $(this).html(Drupal.t('Hide summary'));
+                if ($container.find('.local-translation-preview').length < 2) {
+                  $('<div class="local-translation-preview"><table><tbody><tr><td></td><td>'
+                    + settings.localTranslationCurrentLanguageName
+                    + '</td></tr></tbody></table></div>')
+                    .insertAfter($container.find('.local-translation-preview'));
+                  var $second_container = $container.find('.local-translation-preview:last');
+                  var $cell = $second_container.find('tr td:first');
+                  $summary_wrapper.detach()
+                    .appendTo($cell).show();
+                  $container.find('label[for$="summary"]')
+                    .detach()
+                    .insertBefore($second_container)
+                    .show();
+                  var field_label = $container.find('label[for$="value"]').text();
+                  if (!/\(*\)/.test($container.find('label[for$="summary"]').text())) {
+                    $container.find('label[for$="summary"]')
+                      .text(
+                        $container.find('label[for$="summary"]').text() + ' (' + field_label + ')'
+                      );
+                  }
+                }
+              }
+              else {
+                $(this).html(Drupal.t('Edit summary'));
+                $container.find('.local-translation-preview:last tr td:first > div')
+                  .detach()
+                  .prependTo($(this).parent().parent())
+                  .hide();
+                $container.find('label[for$="summary"]')
+                  .detach()
+                  .insertBefore($container.find('label[for$="value"]'))
+                  .hide();
+                $container.find('.local-translation-preview:last')
+                  .remove();
+              }
+              event.preventDefault();
+              return false;
+            });
+          }
+        }
+      });
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/modules/local_translation_content/local_translation_content.libraries.yml b/modules/local_translation_content/local_translation_content.libraries.yml
new file mode 100644
index 0000000..9096373
--- /dev/null
+++ b/modules/local_translation_content/local_translation_content.libraries.yml
@@ -0,0 +1,9 @@
+fields-translations-preview:
+  css:
+    component:
+      css/preview.css: {preprocess: false}
+  js:
+    js/fields_translations_preview.js: {preprocess: false}
+  dependencies:
+    - core/drupal
+    - core/jquery
diff --git a/modules/local_translation_content/local_translation_content.module b/modules/local_translation_content/local_translation_content.module
index 46bffd8..0564f6b 100644
--- a/modules/local_translation_content/local_translation_content.module
+++ b/modules/local_translation_content/local_translation_content.module
@@ -6,8 +6,10 @@
  */
 
 use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Entity\ContentEntityFormInterface;
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\local_translation_content\Processor\LocalTranslationFieldsPreviewsProcessor;
 use Drupal\local_translation_content\Controller\LocalTranslationContentLanguageCtrl;
 use Drupal\local_translation_content\Plugin\views\filter\TranslationLanguageLimitedToTranslationSkills;
 use Drupal\views\Plugin\views\query\QueryPluginBase;
@@ -159,6 +161,33 @@ function local_translation_content_config_schema_info_alter(&$definitions) {
  * Implements hook_form_alter().
  */
 function local_translation_content_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
+  // Content entity forms fields translation previews block.
+  $build_info = $form_state->getBuildInfo();
+  if (isset($build_info['callback_object'])) {
+    $entity_form = $build_info['callback_object'];
+    // Ensure the current form is a content entity form.
+    if ($entity_form instanceof ContentEntityFormInterface) {
+      if (!$entity_form->isDefaultFormLangcode($form_state)) {
+        $processor = new LocalTranslationFieldsPreviewsProcessor($entity_form->getEntity());
+        $languages = $processor->getPreviewLanguages();
+        $translations_previews = [];
+        foreach ($languages as $langcode => $language) {
+          $translation = $processor->getTranslation($langcode);
+          if ($translation instanceof ContentEntityInterface) {
+            $fields = $processor->getFieldNames();
+            $translations_previews[$language->getName()] = $processor
+              ->getFieldsTranslations($fields, $translation);
+          }
+        }
+        if (!empty($translations_previews)) {
+          $processor->prepareTables($translations_previews);
+          $form['#attached']['drupalSettings']['localTranslationFieldsTranslationsPreview'] = $translations_previews;
+          $form['#attached']['drupalSettings']['localTranslationCurrentLanguageName'] = $processor->getCurrentLanguageName();
+        }
+        $form['#attached']['library'][] = 'local_translation_content/fields-translations-preview';
+      }
+    }
+  }
   if (stripos($form_id, 'node_') !== FALSE) {
     $node = \Drupal::routeMatch()->getParameter('node');
     if ($node instanceof Node && isset($form['source_langcode'])) {
diff --git a/modules/local_translation_content/src/Processor/LocalTranslationFieldsPreviewsProcessor.php b/modules/local_translation_content/src/Processor/LocalTranslationFieldsPreviewsProcessor.php
new file mode 100644
index 0000000..85dc8ce
--- /dev/null
+++ b/modules/local_translation_content/src/Processor/LocalTranslationFieldsPreviewsProcessor.php
@@ -0,0 +1,262 @@
+<?php
+
+namespace Drupal\local_translation_content\Processor;
+
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Entity\ContentEntityInterface;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+use Drupal\Core\Render\Element;
+
+/**
+ * Class LocalTranslationFieldsPreviewsProcessor.
+ *
+ * @package Drupal\local_translation_content\Processor
+ */
+class LocalTranslationFieldsPreviewsProcessor extends ControllerBase {
+
+  /**
+   * Processing entity object.
+   *
+   * @var \Drupal\Core\Entity\ContentEntityInterface
+   */
+  protected $entity;
+  /**
+   * Current language ID.
+   *
+   * @var string
+   */
+  protected $currentLanguage;
+  /**
+   * All enabled languages.
+   *
+   * @var \Drupal\Core\Language\LanguageInterface[]
+   */
+  protected $languages;
+  /**
+   * Renderer service.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+  /**
+   * User skills service.
+   *
+   * @var \Drupal\local_translation\Services\LocalTranslationUserSkills
+   */
+  protected $userSkills;
+  /**
+   * Original language.
+   *
+   * @var \Drupal\Core\Language\LanguageInterface
+   */
+  protected $originalLanguage;
+
+  /**
+   * LocalTranslationFieldsPreviewsProcessor constructor.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   Entity object to operate on.
+   */
+  public function __construct(ContentEntityInterface $entity) {
+    $this->entity           = $entity;
+    $this->languages        = $this->languageManager()->getNativeLanguages();
+    $this->originalLanguage = $entity->getUntranslated()->language();
+    $this->renderer         = \Drupal::service('renderer');
+    $this->userSkills       = \Drupal::service('local_translation.user_skills');
+    $this->currentLanguage  = $this->languageManager()
+      ->getCurrentLanguage()
+      ->getId();
+  }
+
+  /**
+   * Get languages for preview.
+   *
+   * @return \Drupal\Core\Language\LanguageInterface[]
+   *   Language objects available for preview.
+   */
+  public function getPreviewLanguages() {
+    $languages = $this->languages;
+    foreach ($languages as $langcode => $language) {
+      if (!$this->entity->hasTranslation($langcode)
+        || !$this->userSkills->userHasSkill($langcode)
+        || $langcode === $this->originalLanguage->getId()
+        || $this->isTargetLanguage($langcode)
+      ) {
+        unset($languages[$langcode]);
+      }
+    }
+    return [$this->originalLanguage->getId() => $this->originalLanguage] + $languages;
+  }
+
+  /**
+   * Check if specified language is a translation target language.
+   *
+   * @param string $langcode
+   *   Langcode to be checked.
+   *
+   * @return bool
+   *   Checking result.
+   */
+  protected function isTargetLanguage($langcode) {
+    $target_language_id = $this->getTargetLanguage()->getId();
+    return $langcode === $target_language_id;
+  }
+
+  /**
+   * Get target language object.
+   *
+   * @return \Drupal\Core\Language\LanguageInterface|mixed|null
+   *   Target language object.
+   */
+  protected function getTargetLanguage() {
+    $match = \Drupal::routeMatch();
+    if ($target = $match->getParameter('target')) {
+      return $target;
+    }
+    return \Drupal::languageManager()->getCurrentLanguage();
+  }
+
+  /**
+   * Get current language name.
+   *
+   * @return string
+   *   Current language name.
+   */
+  public function getCurrentLanguageName() {
+    return $this->getTargetLanguage()->getName();
+  }
+
+  /**
+   * Get node's translation.
+   *
+   * @param string $langcode
+   *   Language ID.
+   *
+   * @return \Drupal\Core\Entity\ContentEntityInterface|null
+   *   Translation object or NULL if translation doesn't exist.
+   */
+  public function getTranslation($langcode) {
+    return $this->entity->hasTranslation($langcode)
+      ? $this->entity->getTranslation($langcode)
+      : NULL;
+  }
+
+  /**
+   * Get field names of the field widgets we need to alter.
+   *
+   * @return array
+   *   Array of field names.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
+   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
+   */
+  public function getFieldNames() {
+    $display = $this->entityTypeManager()
+      ->getStorage('entity_form_display')
+      ->load($this->entity->getEntityTypeId()
+        . '.' . $this->entity->bundle()
+        . '.default');
+    if (!$display instanceof EntityFormDisplay) {
+      return [];
+    }
+    $components = $display->getComponents();
+    return !empty($components) ? array_keys($components) : [];
+  }
+
+  /**
+   * Get fields' translations.
+   *
+   * @param array $fields
+   *   Array of field names.
+   * @param \Drupal\node\Entity\Node $translation
+   *   Translation version of the node.
+   * @param bool $rendered
+   *   Optional. Render fields or not. Defaults to TRUE.
+   *
+   * @return array
+   *   Fields' translations array.
+   */
+  public function getFieldsTranslations(array $fields, ContentEntityInterface $translation, $rendered = TRUE) {
+    $translations = [];
+    if (empty($fields)) {
+      return $translations;
+    }
+    foreach ($fields as $field_name) {
+      if (!$translation->hasField($field_name)) {
+        continue;
+      }
+      $field = $translation->get($field_name);
+      if ($field->isEmpty() || !$field->getFieldDefinition()->isTranslatable()) {
+        continue;
+      }
+      $translations[$field_name] = $field->view(['type' => 'default_formatter']);
+      if (empty($translations[$field_name])) {
+        unset($translations[$field_name]);
+        continue;
+      }
+      $translations[$field_name]['#label_display'] = 'hidden';
+      if ($field->getFieldDefinition()->getType() === 'boolean') {
+        $items = $translations[$field_name]['#items']->getValue();
+        foreach (Element::children($translations[$field_name]) as $child) {
+          $translations[$field_name][$child] = [
+            '#type'       => 'checkbox',
+            '#checked'    => $items[$child]['value'] === '1',
+            '#attributes' => ['disabled' => 'disabled'],
+          ];
+        }
+      }
+      elseif ($field->getFieldDefinition()->getType() === 'text_with_summary') {
+        if ($summary = $field->getValue()[0]['summary']) {
+          $body = $translations[$field_name];
+          $translations[$field_name] = [
+            'body'    => $body,
+            'summary' => [
+              '#type'   => 'markup',
+              '#markup' => '<p>' . $summary . '</p>',
+            ],
+          ];
+        }
+      }
+      if ($rendered) {
+        if (isset($translations[$field_name]) && isset($translations[$field_name]['summary'])) {
+          $translations[$field_name . '_summary'] = $this->renderer
+            ->renderRoot($translations[$field_name]['summary']);
+          unset($translations[$field_name]['summary']);
+        }
+        $translations[$field_name] = $this->renderer
+          ->renderRoot($translations[$field_name]);
+      }
+    }
+    return $translations;
+  }
+
+  /**
+   * Prepare tables for field previews.
+   *
+   * @param array &$previews
+   *   Previews data array.
+   */
+  public function prepareTables(array &$previews) {
+    static $table = ['#type' => 'table'];
+    $translations_previews = [];
+    foreach ($previews as $language => $field_values) {
+      foreach ($field_values as $field_name => $field_value) {
+        if (!isset($translations_previews[$field_name])) {
+          $translations_previews[$field_name] = $table;
+        }
+        if ($this->originalLanguage->getName() === $language) {
+          $language = $this->t(
+            '<strong>@language_name (Original language)</strong>',
+            ['@language_name' => $language]
+          );
+        }
+        $translations_previews[$field_name]['#rows'][] = [$field_value, $language];
+      }
+    }
+    foreach ($translations_previews as &$table) {
+      $table = $this->renderer->renderRoot($table);
+    }
+    $previews = $translations_previews;
+  }
+
+}
