Skip to content

Content Block Entities

When to Use

Working with instances of block content (content entities created from block types).

Steps

  1. Understanding BlockContent entity
  2. Content entity with bundle (block type)
  3. Fieldable, translatable, revisionable
  4. Two modes: reusable vs non-reusable

  5. Creating content blocks

  6. Via UI: /block/add/{type}
  7. Programmatically: BlockContent::create([])
  8. Via inline form in Layout Builder

  9. Loading content blocks

    $block = BlockContent::load($id);
    $blocks = \Drupal::entityTypeManager()
      ->getStorage('block_content')
      ->loadByProperties(['type' => 'call_to_action']);
    

  10. Updating content blocks

    $block->set('field_title', 'New Title');
    $block->save();
    

  11. Accessing fields

    $title = $block->field_title->value;
    $image_url = $block->field_image->entity->createFileUrl();
    

Decision Points

At this step... If... Then...
Step 2 (create) Block appears on one page only Use non-reusable (inline block)
Step 2 (create) Block appears on multiple pages Use reusable block
Step 3 (load) Loading many blocks Use loadMultiple() for efficiency
Step 4 (update) Changing reusable block Understand it updates everywhere it's placed
Step 5 (access) Field might be empty Check ->isEmpty() before accessing ->value

Pattern

Reusable vs non-reusable:

// Reusable block (appears in block library)
$block = BlockContent::create([
  'type' => 'basic',
  'info' => 'About Us',
  'reusable' => TRUE, // Can be placed multiple times
]);

// Non-reusable block (Layout Builder inline block)
$block = BlockContent::create([
  'type' => 'basic',
  'info' => 'Inline content',
  'reusable' => FALSE, // Owned by specific layout
]);

Working with block content:

// Load and render
$block = BlockContent::load(1);
$view_builder = \Drupal::entityTypeManager()->getViewBuilder('block_content');
$build = $view_builder->view($block, 'full');

// Access fields safely
if (!$block->field_image->isEmpty()) {
  $image_uri = $block->field_image->entity->getFileUri();
}

// Delete
$block->delete();

Reference: core/modules/block_content/src/Entity/BlockContent.php, core/modules/block_content/src/Plugin/Block/BlockContentBlock.php

Common Mistakes

  • Confusing BlockContent (entity) with Block (config entity for placement) → Two different things; Block references a plugin which may wrap BlockContent
  • Editing non-reusable blocks outside Layout Builder → They're not in the block library; use Layout Builder UI
  • Not checking reusable flag before placing → Non-reusable blocks shouldn't be placed in traditional regions
  • Hardcoding block content IDs → Use labels or UUIDs for portability across environments
  • Not handling deleted content block references → Placed blocks will error if content entity deleted

See Also