diff --git a/src/Entity/Handler/WidgetContentModerationHandler.php b/src/Entity/Handler/WidgetContentModerationHandler.php
new file mode 100644
index 0000000..6c34e1c
--- /dev/null
+++ b/src/Entity/Handler/WidgetContentModerationHandler.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\widget_engine\Entity\Handler;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\content_moderation\Entity\Handler\ModerationHandler;
+
+/**
+ * Customizations for block content entities.
+ *
+ * @internal
+ */
+class WidgetContentModerationHandler extends ModerationHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function enforceRevisionsEntityFormAlter(array &$form, FormStateInterface $form_state, $form_id) {
+    $form['revision']['#default_value'] = TRUE;
+    $form['revision']['#disabled'] = TRUE;
+    $form['revision']['#description'] = $this->t('Revisions must be required when moderation is enabled.');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function enforceRevisionsBundleFormAlter(array &$form, FormStateInterface $form_state, $form_id) {
+    $form['revision']['#default_value'] = 1;
+    $form['revision']['#disabled'] = TRUE;
+    $form['revision']['#description'] = $this->t('Revisions must be required when moderation is enabled.');
+  }
+
+}
diff --git a/src/Entity/Widget.php b/src/Entity/Widget.php
index 3b622bb..cd20e1f 100644
--- a/src/Entity/Widget.php
+++ b/src/Entity/Widget.php
@@ -2,10 +2,9 @@
 
 namespace Drupal\widget_engine\Entity;
 
+use Drupal\Core\Entity\EditorialContentEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
-use Drupal\Core\Entity\ContentEntityBase;
-use Drupal\Core\Entity\EntityChangedTrait;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\user\UserInterface;
 
@@ -36,16 +35,25 @@ use Drupal\user\UserInterface;
  *   },
  *   base_table = "widget",
  *   data_table = "widget_field_data",
+ *   revision_table = "widget_revision",
+ *   revision_data_table = "widget_field_revision",
+ *   show_revision_ui = TRUE,
  *   translatable = TRUE,
  *   admin_permission = "administer widget entities",
  *   entity_keys = {
  *     "id" = "wid",
+ *     "revision" = "revision_id",
  *     "bundle" = "type",
  *     "label" = "name",
  *     "uuid" = "uuid",
  *     "uid" = "user_id",
  *     "langcode" = "langcode",
- *     "status" = "status",
+ *     "published" = "status",
+ *   },
+ *   revision_metadata_keys = {
+ *     "revision_user" = "revision_user",
+ *     "revision_created" = "revision_created",
+ *     "revision_log_message" = "revision_log",
  *   },
  *   links = {
  *     "canonical" = "/admin/structure/widget/{widget}",
@@ -59,9 +67,7 @@ use Drupal\user\UserInterface;
  *   field_ui_base_route = "entity.widget_type.edit_form"
  * )
  */
-class Widget extends ContentEntityBase implements WidgetInterface {
-
-  use EntityChangedTrait;
+class Widget extends EditorialContentEntityBase implements WidgetInterface {
 
   /**
    * {@inheritdoc}
@@ -73,6 +79,20 @@ class Widget extends ContentEntityBase implements WidgetInterface {
     );
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
+    parent::preSaveRevision($storage, $record);
+
+    if (!$this->isNewRevision() && isset($this->original) && (!isset($record->revision_log) || $record->revision_log === '')) {
+      // If we are updating an existing block_content without adding a new
+      // revision and the user did not supply a revision log, keep the existing
+      // one.
+      $record->revision_log = $this->original->getRevisionLogMessage();
+    }
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -143,15 +163,71 @@ class Widget extends ContentEntityBase implements WidgetInterface {
   /**
    * {@inheritdoc}
    */
-  public function isPublished() {
-    return (bool) $this->getEntityKey('status');
+  public function getRevisionLog() {
+    return $this->getRevisionLogMessage();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRevisionLog($revision_log) {
+    return $this->setRevisionLogMessage($revision_log);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionCreationTime() {
+    return $this->get('revision_created')->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRevisionCreationTime($timestamp) {
+    $this->set('revision_created', $timestamp);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionUser() {
+    return $this->get('revision_user')->entity;
+  }
+
+  public function setRevisionUser(UserInterface $account) {
+    $this->set('revision_user', $account);
+    return $this;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function setPublished($published) {
-    $this->set('status', $published ? TRUE : FALSE);
+  public function getRevisionUserId() {
+    return $this->get('revision_user')->entity->id();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRevisionUserId($user_id) {
+    $this->set('revision_user', $user_id);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionLogMessage() {
+    return $this->get('revision_log')->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setRevisionLogMessage($revision_log_message) {
+    $this->set('revision_log', $revision_log_message);
     return $this;
   }
 
@@ -206,7 +282,8 @@ class Widget extends ContentEntityBase implements WidgetInterface {
         'weight' => -4,
       ))
       ->setDisplayConfigurable('form', TRUE)
-      ->setDisplayConfigurable('view', TRUE);
+      ->setDisplayConfigurable('view', TRUE)
+      ->setRevisionable(TRUE);
 
     $fields['status'] = BaseFieldDefinition::create('boolean')
       ->setLabel(t('Publishing status'))
@@ -219,7 +296,8 @@ class Widget extends ContentEntityBase implements WidgetInterface {
 
     $fields['changed'] = BaseFieldDefinition::create('changed')
       ->setLabel(t('Changed'))
-      ->setDescription(t('The time that the entity was last edited.'));
+      ->setDescription(t('The time that the entity was last edited.'))
+      ->setRevisionable(TRUE);
 
     $fields['widget_preview'] = BaseFieldDefinition::create('image')
       ->setLabel(t('Widget preview'))
@@ -247,6 +325,8 @@ class Widget extends ContentEntityBase implements WidgetInterface {
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayConfigurable('view', TRUE);
 
+    $fields['revision_log']->setDescription(t('The log entry explaining the changes in this revision.'));
+
     return $fields;
   }
 
diff --git a/src/Entity/WidgetInterface.php b/src/Entity/WidgetInterface.php
index b355a49..e6c6579 100644
--- a/src/Entity/WidgetInterface.php
+++ b/src/Entity/WidgetInterface.php
@@ -4,6 +4,8 @@ namespace Drupal\widget_engine\Entity;
 
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityChangedInterface;
+use Drupal\Core\Entity\EntityPublishedInterface;
+use Drupal\Core\Entity\RevisionLogInterface;
 use Drupal\user\EntityOwnerInterface;
 
 /**
@@ -11,7 +13,7 @@ use Drupal\user\EntityOwnerInterface;
  *
  * @ingroup widget_engine
  */
-interface WidgetInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface {
+interface WidgetInterface extends ContentEntityInterface, EntityChangedInterface, EntityOwnerInterface, RevisionLogInterface, EntityPublishedInterface {
 
   // Add get/set methods for your configuration properties here.
 
@@ -62,24 +64,28 @@ interface WidgetInterface extends ContentEntityInterface, EntityChangedInterface
   public function setCreatedTime($timestamp);
 
   /**
-   * Returns the Widget published status indicator.
+   * Returns the block revision log message.
    *
-   * Unpublished Widget are only visible to restricted users.
+   * @return string
+   *   The revision log message.
    *
-   * @return bool
-   *   TRUE if the Widget is published.
+   * @deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use
+   *   \Drupal\Core\Entity\RevisionLogInterface::getRevisionLogMessage() instead.
    */
-  public function isPublished();
+  public function getRevisionLog();
 
   /**
-   * Sets the published status of a Widget.
+   * Sets the block revision log message.
    *
-   * @param bool $published
-   *   TRUE to set this Widget to published, FALSE to set it to unpublished.
+   * @param string $revision_log
+   *   The revision log message.
    *
-   * @return \Drupal\widget_engine\Entity\WidgetInterface
-   *   The called Widget entity.
+   * @return $this
+   *   The class instance that this method is called on.
+   *
+   * @deprecated in drupal:8.2.0 and is removed from drupal:9.0.0. Use
+   *   \Drupal\Core\Entity\RevisionLogInterface::setRevisionLogMessage() instead.
    */
-  public function setPublished($published);
+  public function setRevisionLog($revision_log);
 
 }
diff --git a/src/Entity/WidgetType.php b/src/Entity/WidgetType.php
index 156b33c..a65fdd0 100644
--- a/src/Entity/WidgetType.php
+++ b/src/Entity/WidgetType.php
@@ -36,6 +36,12 @@ use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
  *     "edit-form" = "/admin/structure/widget_type/{widget_type}/edit",
  *     "delete-form" = "/admin/structure/widget_type/{widget_type}/delete",
  *     "collection" = "/admin/structure/widget_type"
+ *   },
+ *   config_export = {
+ *     "id",
+ *     "label",
+ *     "revision",
+ *     "description",
  *   }
  * )
  */
@@ -55,4 +61,32 @@ class WidgetType extends ConfigEntityBundleBase implements WidgetTypeInterface {
    */
   protected $label;
 
+  /**
+   * The default revision setting for custom blocks of this type.
+   *
+   * @var bool
+   */
+  protected $revision;
+
+  /**
+   * The description of the block type.
+   *
+   * @var string
+   */
+  protected $description;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return $this->description;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function shouldCreateNewRevision() {
+    return $this->revision;
+  }
+
 }
diff --git a/src/Entity/WidgetTypeInterface.php b/src/Entity/WidgetTypeInterface.php
index 80acfa6..0ea1a69 100644
--- a/src/Entity/WidgetTypeInterface.php
+++ b/src/Entity/WidgetTypeInterface.php
@@ -3,11 +3,18 @@
 namespace Drupal\widget_engine\Entity;
 
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\RevisionableEntityBundleInterface;
 
 /**
  * Provides an interface for defining Widget type entities.
  */
-interface WidgetTypeInterface extends ConfigEntityInterface {
+interface WidgetTypeInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface {
 
-  // Add get/set methods for your configuration properties here.
+  /**
+   * Returns the description of the block type.
+   *
+   * @return string
+   *   The description of the type of this block.
+   */
+  public function getDescription();
 }
diff --git a/src/Entity/WidgetViewsData.php b/src/Entity/WidgetViewsData.php
index 7c0d730..5c07e13 100644
--- a/src/Entity/WidgetViewsData.php
+++ b/src/Entity/WidgetViewsData.php
@@ -15,6 +15,27 @@ class WidgetViewsData extends EntityViewsData {
   public function getViewsData() {
     $data = parent::getViewsData();
 
+    $data['widget_field_revision']['table']['wizard_id'] = 'widget_revision';
+
+    // Advertise this table as a possible base table.
+    $data['widget_field_revision']['table']['base']['help'] = $this->t('Content revision is a history of changes to content.');
+    $data['widget_field_revision']['table']['base']['defaults']['title'] = 'title';
+
+    $data['widget_field_revision']['wid']['argument'] = [
+      'id' => 'widget_wid',
+      'numeric' => TRUE,
+    ];
+
+    $data['widget_field_revision']['wid']['relationship']['id'] = 'standard';
+    $data['widget_field_revision']['wid']['relationship']['base'] = 'widget_field_data';
+    $data['widget_field_revision']['wid']['relationship']['base field'] = 'wid';
+    $data['widget_field_revision']['wid']['relationship']['title'] = $this->t('Widget');
+    $data['widget_field_revision']['wid']['relationship']['label'] = $this->t('Get the actual widget from a widget revision.');
+    $data['widget_field_revision']['wid']['relationship']['extra'][] = [
+      'field' => 'langcode',
+      'left_field' => 'langcode',
+    ];
+
     // Additional information for Views integration, such as table joins, can be
     // put here.
     return $data;
diff --git a/src/Form/WidgetTypeForm.php b/src/Form/WidgetTypeForm.php
index 6a5dc12..97621fa 100644
--- a/src/Form/WidgetTypeForm.php
+++ b/src/Form/WidgetTypeForm.php
@@ -2,15 +2,16 @@
 
 namespace Drupal\widget_engine\Form;
 
-use Drupal\Core\Entity\EntityForm;
+use Drupal\Core\Entity\BundleEntityFormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\language\Entity\ContentLanguageSettings;
 
 /**
  * Class WidgetTypeForm.
  *
  * @package Drupal\widget_engine\Form
  */
-class WidgetTypeForm extends EntityForm {
+class WidgetTypeForm extends BundleEntityFormBase {
 
   /**
    * {@inheritdoc}
@@ -37,9 +38,47 @@ class WidgetTypeForm extends EntityForm {
       '#disabled' => !$widget_type->isNew(),
     ];
 
-    /* You will need additional form elements for your custom properties. */
+    $form['description'] = [
+      '#type' => 'textarea',
+      '#default_value' => $widget_type->getDescription(),
+      '#description' => t('Enter a description for this Widget type.'),
+      '#title' => t('Description'),
+    ];
+
+    $form['revision'] = [
+      '#type' => 'checkbox',
+      '#title' => t('Create new revision'),
+      '#default_value' => $widget_type->shouldCreateNewRevision(),
+      '#description' => t('Create a new revision by default for this Widget type.'),
+    ];
+
+    if ($this->moduleHandler->moduleExists('language')) {
+      $form['language'] = [
+        '#type' => 'details',
+        '#title' => t('Language settings'),
+        '#group' => 'additional_settings',
+      ];
+
+      $language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('widget', $widget_type->id());
+      $form['language']['language_configuration'] = [
+        '#type' => 'language_configuration',
+        '#entity_information' => [
+          'entity_type' => 'widget',
+          'bundle' => $widget_type->id(),
+        ],
+        '#default_value' => $language_configuration,
+      ];
 
-    return $form;
+      $form['#submit'][] = 'language_configuration_element_submit';
+    }
+
+    $form['actions'] = ['#type' => 'actions'];
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#value' => t('Save'),
+    ];
+
+    return $this->protectBundleIdElement($form);
   }
 
   /**
@@ -49,17 +88,15 @@ class WidgetTypeForm extends EntityForm {
     $widget_type = $this->entity;
     $status = $widget_type->save();
 
-    switch ($status) {
-      case SAVED_NEW:
-        drupal_set_message($this->t('Created the %label Widget type.', [
-          '%label' => $widget_type->label(),
-        ]));
-        break;
-
-      default:
-        drupal_set_message($this->t('Saved the %label Widget type.', [
-          '%label' => $widget_type->label(),
-        ]));
+    $edit_link = $this->entity->toLink($this->t('Edit'), 'edit-form')->toString();
+    $logger = $this->logger('widget_engine');
+    if ($status == SAVED_UPDATED) {
+      $this->messenger()->addStatus(t('Widget type %label has been updated.', ['%label' => $widget_type->label()]));
+      $logger->notice('Widget type %label has been updated.', ['%label' => $widget_type->label(), 'link' => $edit_link]);
+    }
+    else {
+      $this->messenger()->addStatus(t('Widget type %label has been added.', ['%label' => $widget_type->label()]));
+      $logger->notice('Widget type %label has been added.', ['%label' => $widget_type->label(), 'link' => $edit_link]);
     }
     $form_state->setRedirectUrl($widget_type->toUrl('collection'));
   }
diff --git a/src/Plugin/views/wizard/WidgetRevision.php b/src/Plugin/views/wizard/WidgetRevision.php
new file mode 100644
index 0000000..14f1561
--- /dev/null
+++ b/src/Plugin/views/wizard/WidgetRevision.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\widget_engine\Plugin\views\wizard;
+
+use Drupal\views\Plugin\views\wizard\WizardPluginBase;
+
+/**
+ * Provides Views creation wizard for Widget revisions.
+ *
+ * @ViewsWizard(
+ *   id = "widget_revision",
+ *   base_table = "widget_field_revision",
+ *   title = @Translation("Widget revisions")
+ * )
+ */
+class WidgetRevision extends WizardPluginBase {
+
+  /**
+   * Set the created column.
+   *
+   * @var string
+   */
+  protected $createdColumn = 'widget_field_revision-created';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defaultDisplayOptions() {
+    $display_options = parent::defaultDisplayOptions();
+
+    // Add permission-based access control.
+    $display_options['access']['type'] = 'perm';
+    $display_options['access']['options']['perm'] = 'view unpublished widget entities';
+
+    // Remove the default fields, since we are customizing them here.
+    unset($display_options['fields']);
+
+    // Add the changed field.
+    $display_options['fields']['changed']['id'] = 'changed';
+    $display_options['fields']['changed']['table'] = 'widget_field_revision';
+    $display_options['fields']['changed']['field'] = 'changed';
+    $display_options['fields']['changed']['entity_type'] = 'widget';
+    $display_options['fields']['changed']['entity_field'] = 'changed';
+    $display_options['fields']['changed']['alter']['alter_text'] = FALSE;
+    $display_options['fields']['changed']['alter']['make_link'] = FALSE;
+    $display_options['fields']['changed']['alter']['absolute'] = FALSE;
+    $display_options['fields']['changed']['alter']['trim'] = FALSE;
+    $display_options['fields']['changed']['alter']['word_boundary'] = FALSE;
+    $display_options['fields']['changed']['alter']['ellipsis'] = FALSE;
+    $display_options['fields']['changed']['alter']['strip_tags'] = FALSE;
+    $display_options['fields']['changed']['alter']['html'] = FALSE;
+    $display_options['fields']['changed']['hide_empty'] = FALSE;
+    $display_options['fields']['changed']['empty_zero'] = FALSE;
+    $display_options['fields']['changed']['plugin_id'] = 'field';
+    $display_options['fields']['changed']['type'] = 'timestamp';
+    $display_options['fields']['changed']['settings']['date_format'] = 'medium';
+    $display_options['fields']['changed']['settings']['custom_date_format'] = '';
+    $display_options['fields']['changed']['settings']['timezone'] = '';
+
+    // Add the name field.
+    $display_options['fields']['name']['id'] = 'name';
+    $display_options['fields']['name']['table'] = 'widget_field_revision';
+    $display_options['fields']['name']['field'] = 'name';
+    $display_options['fields']['name']['entity_type'] = 'widget';
+    $display_options['fields']['name']['entity_field'] = 'name';
+    $display_options['fields']['name']['label'] = '';
+    $display_options['fields']['name']['alter']['alter_text'] = 0;
+    $display_options['fields']['name']['alter']['make_link'] = 0;
+    $display_options['fields']['name']['alter']['absolute'] = 0;
+    $display_options['fields']['name']['alter']['trim'] = 0;
+    $display_options['fields']['name']['alter']['word_boundary'] = 0;
+    $display_options['fields']['name']['alter']['ellipsis'] = 0;
+    $display_options['fields']['name']['alter']['strip_tags'] = 0;
+    $display_options['fields']['name']['alter']['html'] = 0;
+    $display_options['fields']['name']['hide_empty'] = 0;
+    $display_options['fields']['name']['empty_zero'] = 0;
+    $display_options['fields']['name']['settings']['link_to_entity'] = 0;
+    $display_options['fields']['name']['plugin_id'] = 'field';
+
+    return $display_options;
+  }
+
+}
diff --git a/widget_engine.module b/widget_engine.module
index 2d5ec61..3ffa263 100644
--- a/widget_engine.module
+++ b/widget_engine.module
@@ -9,6 +9,7 @@ use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Ajax\InvokeCommand;
 use Drupal\Core\Render\Element;
 use Drupal\image\Entity\ImageStyle;
+use Drupal\widget_engine\Entity\Handler\WidgetContentModerationHandler;
 
 /**
  * Load needed for module includes.
@@ -277,3 +278,11 @@ function widget_engine_build_preview_image($data) {
 
   return $data;
 }
+
+/**
+ * Implements hook_entity_type_alter().
+ */
+function widget_engine_entity_type_alter(array &$entity_types) {
+  /** @var $entity_types \Drupal\Core\Entity\EntityTypeInterface[] */
+  $entity_types['widget']->setHandlerClass('moderation', WidgetContentModerationHandler::class);
+}
diff --git a/widget_engine.post_update.php b/widget_engine.post_update.php
new file mode 100755
index 0000000..cba3f26
--- /dev/null
+++ b/widget_engine.post_update.php
@@ -0,0 +1,121 @@
+<?php
+
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+
+/**
+ * Widget entity to be revisionable.
+ */
+
+function widget_engine_post_update_make_widget_revisionable(&$sandbox) {
+
+  $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+  /** @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository */
+  $last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
+
+  $entity_type = $definition_update_manager->getEntityType('widget');
+  $field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions('widget');
+
+  // Update the entity type definition.
+  $entity_keys = $entity_type->getKeys();
+  $entity_keys['revision'] = 'revision_id';
+  $entity_keys['revision_translation_affected'] = 'revision_translation_affected';
+
+  $entity_type->set('entity_keys', $entity_keys);
+  $entity_type->set('revision_table', 'widget_revision');
+  $entity_type->set('revision_data_table', 'widget_field_revision');
+
+  $revision_metadata_keys = [
+    'revision_default' => 'revision_default',
+    'revision_user' => 'revision_user',
+    'revision_created' => 'revision_created',
+    'revision_log_message' => 'revision_log',
+  ];
+  $entity_type->set('revision_metadata_keys', $revision_metadata_keys);
+
+  // Update the field storage definitions and add the new ones required by a
+  // revisionable entity type.
+  $field_storage_definitions['langcode']->setRevisionable(TRUE);
+  $field_storage_definitions['name']->setRevisionable(TRUE);
+  $field_storage_definitions['wid']->setRevisionable(TRUE);
+  $field_storage_definitions['type']->setRevisionable(TRUE);
+  $field_storage_definitions['changed']->setRevisionable(TRUE);
+  $field_storage_definitions['created']->setRevisionable(TRUE);
+
+  $field_storage_definitions['wid'] = BaseFieldDefinition::create('integer')
+    ->setName('wid')
+    ->setTargetEntityTypeId('widget')
+    ->setTargetBundle(NULL)
+    ->setLabel(new TranslatableMarkup('wid'))
+    ->setReadOnly(TRUE)
+    ->setSetting('unsigned', TRUE);
+
+  $field_storage_definitions['revision_id'] = BaseFieldDefinition::create('integer')
+    ->setName('revision_id')
+    ->setTargetEntityTypeId('widget')
+    ->setTargetBundle(NULL)
+    ->setLabel(new TranslatableMarkup('Revision ID'))
+    ->setReadOnly(TRUE)
+    ->setSetting('unsigned', TRUE);
+
+  $field_storage_definitions['revision_default'] = BaseFieldDefinition::create('boolean')
+    ->setName('revision_default')
+    ->setTargetEntityTypeId('widget')
+    ->setTargetBundle(NULL)
+    ->setLabel(new TranslatableMarkup('Default revision'))
+    ->setDescription(new TranslatableMarkup('A flag indicating whether this was a default revision when it was saved.'))
+    ->setStorageRequired(TRUE)
+    ->setInternal(TRUE)
+    ->setTranslatable(FALSE)
+    ->setRevisionable(TRUE);
+
+  $field_storage_definitions['revision_translation_affected'] = BaseFieldDefinition::create('boolean')
+    ->setName('revision_translation_affected')
+    ->setTargetEntityTypeId('widget')
+    ->setTargetBundle(NULL)
+    ->setLabel(new TranslatableMarkup('Revision translation affected'))
+    ->setDescription(new TranslatableMarkup('Indicates if the last edit of a translation belongs to current revision.'))
+    ->setReadOnly(TRUE)
+    ->setRevisionable(TRUE)
+    ->setTranslatable(TRUE);
+
+  $field_storage_definitions['revision_created'] = BaseFieldDefinition::create('created')
+    ->setName('revision_created')
+    ->setTargetEntityTypeId('widget')
+    ->setTargetBundle(NULL)
+    ->setLabel(new TranslatableMarkup('Revision create time'))
+    ->setDescription(new TranslatableMarkup('The time that the current revision was created.'))
+    ->setRevisionable(TRUE);
+
+  $field_storage_definitions['revision_user'] = BaseFieldDefinition::create('entity_reference')
+    ->setName('revision_user')
+    ->setTargetEntityTypeId('widget')
+    ->setTargetBundle(NULL)
+    ->setLabel(new TranslatableMarkup('Revision user'))
+    ->setDescription(new TranslatableMarkup('The user ID of the author of the current revision.'))
+    ->setSetting('target_type', 'user')
+    ->setRevisionable(TRUE);
+
+  $field_storage_definitions['revision_log'] = BaseFieldDefinition::create('string_long')
+    ->setName('revision_log')
+    ->setTargetEntityTypeId('widget')
+    ->setTargetBundle(NULL)
+    ->setLabel(new TranslatableMarkup('Revision log message'))
+    ->setDescription(new TranslatableMarkup('Briefly describe the changes you have made.'))
+    ->setRevisionable(TRUE)
+    ->setDefaultValue('');
+
+  $definition_update_manager->updateFieldableEntityType($entity_type, $field_storage_definitions, $sandbox);
+
+  return t('Widget have been converted to be revisionable.');
+}
+
+/**
+ * Update data in Widget entity revision.
+ */
+function widget_engine_post_update_make_widget_revisionable_update_data(&$sandbox) {
+  $query = "UPDATE widget_revision AS WR, widget_field_data AS WFD
+SET WR.revision_user = WFD.user_id, WR.revision_created = WFD.created
+WHERE WFD.wid = WR.wid and WR.revision_user IS NULL";
+  \Drupal::database()->query($query);
+}
