diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 59a64a14b3b27534fb75b66275ef18809f7d0842..6fcaf2a6f29cfbaf1d55a5858f5934c4adf3c5f9 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -602,11 +602,23 @@ function node_theme_suggestions_node(array $variables) {
  * inside "/core/modules/node/templates/node.html.twig". Look in there for the
  * full list of variables.
  *
+ * By default this function performs special preprocessing of some base fields
+ * so they are available as variables in the template. For example 'title'
+ * appears as 'label'. This preprocessing is skipped if:
+ * - a module makes the field's display configurable via the field UI by means
+ *   of BaseFieldDefinition::setDisplayConfigurable()
+ * - AND the additional entity type property
+ *   'enable_base_field_custom_preprocess_skipping' has been set using
+ *   hook_entity_type_build().
+ *
  * @param array $variables
  *   An associative array containing:
  *   - elements: An array of elements to display in view mode.
  *   - node: The node object.
  *   - view_mode: View mode; e.g., 'full', 'teaser', etc.
+ *
+ * @see hook_entity_type_build()
+ * @see \Drupal\Core\Field\BaseFieldDefinition::setDisplayConfigurable()
  */
 function template_preprocess_node(&$variables) {
   $variables['view_mode'] = $variables['elements']['#view_mode'];
@@ -615,14 +627,29 @@ function template_preprocess_node(&$variables) {
   $variables['node'] = $variables['elements']['#node'];
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
-  $variables['date'] = \Drupal::service('renderer')->render($variables['elements']['created']);
-  unset($variables['elements']['created']);
-  $variables['author_name'] = \Drupal::service('renderer')->render($variables['elements']['uid']);
-  unset($variables['elements']['uid']);
+  $skip_custom_preprocessing = $node->getEntityType()->get('enable_base_field_custom_preprocess_skipping');
+
+  // Make created, uid and title fields available separately. Skip this custom
+  // preprocessing if the field display is configurable and skipping has been
+  // enabled.
+  // @todo https://www.drupal.org/project/drupal/issues/3015623
+  //   In D9 delete this code and matching template lines. Using
+  //   $variables['content'] is more flexible and consistent.
+  $submitted_configurable = $node->getFieldDefinition('created')->isDisplayConfigurable('view') || $node->getFieldDefinition('uid')->isDisplayConfigurable('view');
+  if (!$skip_custom_preprocessing || !$submitted_configurable) {
+    $variables['date'] = \Drupal::service('renderer')->render($variables['elements']['created']);
+    unset($variables['elements']['created']);
+    $variables['author_name'] = \Drupal::service('renderer')->render($variables['elements']['uid']);
+    unset($variables['elements']['uid']);
+  }
+
+  if (!$skip_custom_preprocessing || !$node->getFieldDefinition('title')->isDisplayConfigurable('view')) {
+    $variables['label'] = $variables['elements']['title'];
+    unset($variables['elements']['title']);
+  }
 
   $variables['url'] = !$node->isNew() ? $node->toUrl('canonical')->toString() : NULL;
-  $variables['label'] = $variables['elements']['title'];
-  unset($variables['elements']['title']);
+
   // The 'page' variable is set to TRUE in two occasions:
   //   - The view mode is 'full' and we are on the 'node.view' route.
   //   - The node is in preview and view mode is either 'full' or 'default'.
@@ -634,17 +661,24 @@ function template_preprocess_node(&$variables) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
 
-  // Display post information only on certain node types.
-  $node_type = $node->type->entity;
-  // Used by RDF to add attributes around the author and date submitted.
-  $variables['author_attributes'] = new Attribute();
-  $variables['display_submitted'] = $node_type->displaySubmitted();
-  if ($variables['display_submitted']) {
-    if (theme_get_setting('features.node_user_picture')) {
-      // To change user picture settings (e.g. image style), edit the 'compact'
-      // view mode on the User entity. Note that the 'compact' view mode might
-      // not be configured, so remember to always check the theme setting first.
-      $variables['author_picture'] = user_view($node->getOwner(), 'compact');
+  if (isset($variables['date'])) {
+    // Display post information on certain node types. This only occurs if
+    // custom preprocessing occurred for both of the created and uid fields.
+    // @todo https://www.drupal.org/project/drupal/issues/3015623
+    //   In D9 delete this code and matching template lines. Using a field
+    //   formatter is more flexible and consistent.
+    $node_type = $node->type->entity;
+    // Used by RDF to add attributes around the author and date submitted.
+    $variables['author_attributes'] = new Attribute();
+    $variables['display_submitted'] = $node_type->displaySubmitted();
+    if ($variables['display_submitted']) {
+      if (theme_get_setting('features.node_user_picture')) {
+        // To change user picture settings (e.g. image style), edit the
+        // 'compact' view mode on the User entity. Note that the 'compact'
+        // view mode might not be configured, so remember to always check the
+        // theme setting first.
+        $variables['author_picture'] = user_view($node->getOwner(), 'compact');
+      }
     }
   }
 
diff --git a/core/modules/node/templates/node.html.twig b/core/modules/node/templates/node.html.twig
index c7ada1e54f644ac2a068ef57640e2f53f1d6abfc..0833ae40680cf326b01bed26a8f491fe57647e99 100644
--- a/core/modules/node/templates/node.html.twig
+++ b/core/modules/node/templates/node.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -75,7 +75,7 @@
 <article{{ attributes }}>
 
   {{ title_prefix }}
-  {% if not page %}
+  {% if label and not page %}
     <h2{{ title_attributes }}>
       <a href="{{ url }}" rel="bookmark">{{ label }}</a>
     </h2>
diff --git a/core/modules/node/tests/modules/node_display_configurable_test/config/install/rdf.mapping.node.page.yml b/core/modules/node/tests/modules/node_display_configurable_test/config/install/rdf.mapping.node.page.yml
new file mode 100644
index 0000000000000000000000000000000000000000..dd6535c3044652325990b2721fe26db3a08f6b4c
--- /dev/null
+++ b/core/modules/node/tests/modules/node_display_configurable_test/config/install/rdf.mapping.node.page.yml
@@ -0,0 +1,40 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - node.type.page
+  module:
+    - node
+id: node.page
+targetEntityType: node
+bundle: page
+types:
+  - 'schema:WebPage'
+fieldMappings:
+  title:
+    properties:
+      - 'schema:name'
+  created:
+    properties:
+      - 'schema:dateCreated'
+    datatype_callback:
+      callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value'
+  changed:
+    properties:
+      - 'schema:dateModified'
+    datatype_callback:
+      callable: 'Drupal\rdf\CommonDataConverter::dateIso8601Value'
+  body:
+    properties:
+      - 'schema:text'
+  uid:
+    properties:
+      - 'schema:author'
+    mapping_type: rel
+  comment_count:
+    properties:
+      - 'schema:interactionCount'
+    datatype_callback:
+      callable: 'Drupal\rdf\SchemaOrgDataConverter::interactionCount'
+      arguments:
+        interaction_type: UserComments
diff --git a/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.info.yml b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c6b478d27135a6c630a087d7f97cbd5da59395d9
--- /dev/null
+++ b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Node configurable display module tests'
+type: module
+description: 'Support module for node \Drupal\Core\Field\BaseFieldDefinition::setDisplayConfigurable() testing.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.module b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.module
new file mode 100644
index 0000000000000000000000000000000000000000..a06318dbeb858cc67dabb7504ccfb961fdf454bd
--- /dev/null
+++ b/core/modules/node/tests/modules/node_display_configurable_test/node_display_configurable_test.module
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * A module for testing making node base fields' displays configurable.
+ */
+
+use Drupal\Core\Entity\EntityTypeInterface;
+
+/**
+ * Implements hook_entity_base_field_info_alter().
+ */
+function node_display_configurable_test_entity_base_field_info_alter(&$base_field_definitions, EntityTypeInterface $entity_type) {
+  if ($entity_type->id() == 'node') {
+    foreach (['created', 'uid', 'title'] as $field) {
+      /** @var \Drupal\Core\Field\BaseFieldDefinition[] $base_field_definitions */
+      $base_field_definitions[$field]->setDisplayConfigurable('view', TRUE);
+    }
+  }
+}
+
+/**
+ * Implements hook_entity_type_build().
+ */
+function node_display_configurable_test_entity_type_build(array &$entity_types) {
+  // Allow skipping of extra preprocessing for configurable display.
+  $entity_types['node']->set('enable_base_field_custom_preprocess_skipping', TRUE);
+}
diff --git a/core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php b/core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5bac9abfa953eee18ffd569b4bdd0ce1bd4fe977
--- /dev/null
+++ b/core/modules/node/tests/src/Functional/NodeDisplayConfigurableTest.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Drupal\Tests\node\Functional;
+
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+
+/**
+ * Tests making node base fields' displays configurable.
+ *
+ * @group node
+ */
+class NodeDisplayConfigurableTest extends NodeTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['quickedit', 'rdf'];
+
+  /**
+   * Sets base fields to configurable display and check settings are respected.
+   */
+  public function testDisplayConfigurable() {
+    // Change the node type setting to show submitted by information.
+    $node_type = \Drupal::entityTypeManager()->getStorage('node_type')->load('page');
+    $node_type->setDisplaySubmitted(TRUE);
+    $node_type->save();
+
+    $user = $this->drupalCreateUser(['access in-place editing', 'administer nodes']);
+    $this->drupalLogin($user);
+    $node = $this->drupalCreateNode(['uid' => $user->id()]);
+    $assert = $this->assertSession();
+
+    // Check the node with Drupal default non-configurable display.
+    $this->drupalGet($node->toUrl());
+    $assert->elementTextContains('css', 'span.field--name-created', \Drupal::service('date.formatter')->format($node->getCreatedTime()));
+    $assert->elementTextContains('css', 'span.field--name-uid[data-quickedit-field-id="node/1/uid/en/full"]', $user->getAccountName());
+    $assert->elementTextContains('css', 'div.node__submitted', 'Submitted by');
+    $assert->elementTextContains('css', 'span.field--name-title', $node->getTitle());
+
+    // Enable module to make base fields' displays configurable.
+    \Drupal::service('module_installer')->install(['node_display_configurable_test']);
+
+    // Configure display.
+    $display = EntityViewDisplay::load('node.page.default');
+    $display->setComponent('uid',
+      [
+        'type' => 'entity_reference_label',
+        'label' => 'above',
+        'settings' => ['link' => FALSE],
+      ])
+      ->save();
+
+    // Recheck the node with configurable display.
+    $this->drupalGet($node->toUrl());
+    $assert->elementTextContains('css', 'span.field--name-created', \Drupal::service('date.formatter')->format($node->getCreatedTime()));
+    $assert->elementTextContains('css', 'span.field--name-uid[data-quickedit-field-id="node/1/uid/en/full"]', $user->getAccountName());
+    $assert->elementNotExists('css', 'span.field--name-uid a');
+    $assert->elementTextContains('css', 'span.field--name-title', $node->getTitle());
+    $assert->elementExists('css', 'span[property="schema:dateCreated"]');
+
+    // Remove from display.
+    $display->removeComponent('uid')
+      ->removeComponent('created')
+      ->save();
+
+    $this->drupalGet($node->toUrl());
+    $assert->elementNotExists('css', '.field--name-created');
+    $assert->elementNotExists('css', '.field--name-uid');
+  }
+
+}
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 8c70786eac9ed014aea605711ba139655a22be30..7570ebd585887dc5937ccfc66d2dccd05caa4e3b 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -323,13 +323,30 @@ function rdf_preprocess_node(&$variables) {
 
   // Adds RDFa markup for the date.
   $created_mapping = $mapping->getPreparedFieldMapping('created');
-  if (!empty($created_mapping) && $variables['display_submitted']) {
+  if (!empty($created_mapping)) {
     $date_attributes = rdf_rdfa_attributes($created_mapping, $variables['node']->get('created')->first()->toArray());
     $rdf_metadata = [
       '#theme' => 'rdf_metadata',
       '#metadata' => [$date_attributes],
     ];
-    $variables['metadata'] = \Drupal::service('renderer')->render($rdf_metadata);
+
+    // Depending on whether custom preprocessing is enabled, the 'created'
+    // field may appear in either of two different places, so check both of
+    // those places here.
+    // @see template_preprocess_node.
+    if (!empty($variables['display_submitted'])) {
+      // If custom preprocessing is enabled, then detect if the 'created'
+      // field is displayed by checking the 'display_submitted' variable.  In
+      // this case, for back-compatibility, put the metadata into a special
+      // variable.
+      $variables['metadata'] = \Drupal::service('renderer')->render($rdf_metadata);
+    }
+    elseif (isset($variables['elements']['created'])) {
+      // Otherwise, detect if the 'created' field is displayed by checking if
+      // it is present in the 'elements variable.  Put the metadata into
+      // title_suffix, along with other metadata added by this module.
+      $variables['title_suffix']['rdf_meta_created'] = $rdf_metadata;
+    }
   }
 
   // Adds RDFa markup annotating the number of comments a node has.
diff --git a/core/profiles/demo_umami/themes/umami/templates/content/node--article--full.html.twig b/core/profiles/demo_umami/themes/umami/templates/content/node--article--full.html.twig
index 70b897dc92213a4bca03b6254390f9c1a11010ce..7cd0fe0f53c4ed77b448ef0820de7b253a07d0b0 100644
--- a/core/profiles/demo_umami/themes/umami/templates/content/node--article--full.html.twig
+++ b/core/profiles/demo_umami/themes/umami/templates/content/node--article--full.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -81,11 +81,13 @@
 <article{{ attributes.addClass(classes) }}>
 
   {{ title_prefix }}
+  {% if label %}
     <header class="node__header">
       <h1 class="page-title">
         {{ label }}
       </h1>
     </header>
+  {% endif %}
   {{ title_suffix }}
 
   {% if display_submitted %}
diff --git a/core/profiles/demo_umami/themes/umami/templates/content/node--card-common-alt.html.twig b/core/profiles/demo_umami/themes/umami/templates/content/node--card-common-alt.html.twig
index 8aea1b79029a55dd3d89e22f52e82ec4e84a4c07..545205b64e1ec574ab617cdff95b9dac03ae187f 100644
--- a/core/profiles/demo_umami/themes/umami/templates/content/node--card-common-alt.html.twig
+++ b/core/profiles/demo_umami/themes/umami/templates/content/node--card-common-alt.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
diff --git a/core/profiles/demo_umami/themes/umami/templates/content/node--card-common.html.twig b/core/profiles/demo_umami/themes/umami/templates/content/node--card-common.html.twig
index f1b6a547cbbd65d0aa5c1175c3ad83061dcf7343..e326e37f4f57cbc82b0fae6b484ef0071754011f 100644
--- a/core/profiles/demo_umami/themes/umami/templates/content/node--card-common.html.twig
+++ b/core/profiles/demo_umami/themes/umami/templates/content/node--card-common.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -86,7 +86,7 @@
 <article{{ attributes.addClass(classes) }}>
 
   {{ title_prefix }}
-  {% if not page %}
+  {% if label and not page %}
     <h2{{ title_attributes.addClass('node__title') }}>
       <a class="node__link" href="{{ url }}" rel="bookmark">{{ label }}</a>
     </h2>
diff --git a/core/profiles/demo_umami/themes/umami/templates/content/node--card.html.twig b/core/profiles/demo_umami/themes/umami/templates/content/node--card.html.twig
index 4737ca221e3b3559ceb42e5f6e5fde8767ab1453..e4d0289aecadccaca299f3d32cdc15145ec77aa6 100644
--- a/core/profiles/demo_umami/themes/umami/templates/content/node--card.html.twig
+++ b/core/profiles/demo_umami/themes/umami/templates/content/node--card.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -83,7 +83,7 @@
 <article{{ attributes.addClass(classes) }}>
 
   {{ title_prefix }}
-  {% if not page %}
+  {% if label and not page %}
     <h2{{ title_attributes.addClass('node__title') }}>
       <a class="node__link" href="{{ url }}" rel="bookmark">{{ label }}</a>
     </h2>
diff --git a/core/profiles/demo_umami/themes/umami/templates/content/node--recipe--full.html.twig b/core/profiles/demo_umami/themes/umami/templates/content/node--recipe--full.html.twig
index 96ad360ae091350b2b6db14e4b8e40bddc6f2342..67ec67cf2a8515305d182e03fc49769169ae0db7 100644
--- a/core/profiles/demo_umami/themes/umami/templates/content/node--recipe--full.html.twig
+++ b/core/profiles/demo_umami/themes/umami/templates/content/node--recipe--full.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -81,11 +81,13 @@ view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
 <article{{ attributes.addClass(classes) }}>
 
   {{ title_prefix }}
+  {% if label %}
     <header class="node__header">
       <h1 class="page-title">
         {{ label }}
       </h1>
     </header>
+  {% endif %}
   {{ title_suffix }}
 
   {% if display_submitted %}
diff --git a/core/profiles/demo_umami/themes/umami/templates/content/node.html.twig b/core/profiles/demo_umami/themes/umami/templates/content/node.html.twig
index 69c384b9fa9dc74055f4b987a44959a91c135eb8..359f926dd1fc98876bc41424aab319de626b114c 100644
--- a/core/profiles/demo_umami/themes/umami/templates/content/node.html.twig
+++ b/core/profiles/demo_umami/themes/umami/templates/content/node.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -82,16 +82,18 @@
 <article{{ attributes.addClass(classes) }}>
 
   {{ title_prefix }}
-  {% if page %}
-  <header class="node__header">
-    <h1 class="page-title">
-      {{ label }}
-    </h1>
-  </header>
-  {% else %}
-    <h2{{ title_attributes }}>
-      <a href="{{ url }}" rel="bookmark">{{ label }}</a>
-    </h2>
+  {% if label %}
+    {% if page %}
+      <header class="node__header">
+        <h1 class="page-title">
+          {{ label }}
+        </h1>
+      </header>
+    {% else %}
+      <h2{{ title_attributes }}>
+        <a href="{{ url }}" rel="bookmark">{{ label }}</a>
+      </h2>
+    {% endif %}
   {% endif %}
   {{ title_suffix }}
 
diff --git a/core/themes/bartik/templates/node.html.twig b/core/themes/bartik/templates/node.html.twig
index b257ad3cb6602aa18acb4120707dc225eeec5a49..c7495223fedb0d71ce99442db6f51edbd384d49d 100644
--- a/core/themes/bartik/templates/node.html.twig
+++ b/core/themes/bartik/templates/node.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -81,7 +81,7 @@
 <article{{ attributes.addClass(classes) }}>
   <header>
     {{ title_prefix }}
-    {% if not page %}
+      {% if label and not page %}
       <h2{{ title_attributes.addClass('node__title') }}>
         <a href="{{ url }}" rel="bookmark">{{ label }}</a>
       </h2>
diff --git a/core/themes/classy/templates/content/node.html.twig b/core/themes/classy/templates/content/node.html.twig
index 7f99e796f62825615b8787821e2e83151902639b..a42ff52d025a6e00b0122d68c2d7dea0a9b01bab 100644
--- a/core/themes/classy/templates/content/node.html.twig
+++ b/core/themes/classy/templates/content/node.html.twig
@@ -15,7 +15,7 @@
  *   Calling other methods, such as node.delete(), will result in an exception.
  *   See \Drupal\node\Entity\Node for a full list of public properties and
  *   methods for the node object.
- * - label: The title of the node.
+ * - label: (optional) The title of the node.
  * - content: All node items. Use {{ content }} to print them all,
  *   or print a subset such as {{ content.field_example }}. Use
  *   {{ content|without('field_example') }} to temporarily suppress the printing
@@ -23,8 +23,8 @@
  * - author_picture: The node author user entity, rendered using the "compact"
  *   view mode.
  * - metadata: Metadata for this node.
- * - date: Themed creation date field.
- * - author_name: Themed author name field.
+ * - date: (optional) Themed creation date field.
+ * - author_name: (optional) Themed author name field.
  * - url: Direct URL of the current node.
  * - display_submitted: Whether submission information should be displayed.
  * - attributes: HTML attributes for the containing element.
@@ -84,7 +84,7 @@
 <article{{ attributes.addClass(classes) }}>
 
   {{ title_prefix }}
-  {% if not page %}
+  {% if label and not page %}
     <h2{{ title_attributes }}>
       <a href="{{ url }}" rel="bookmark">{{ label }}</a>
     </h2>