I want to create a block type that has a couple of fields, a template and attached js.

I want that the user in my site will be able to create blocks of this type just like they create a custom block : through /block/add/myBlockType

I would like ideally to have it all done programmatically but I dont mind manually creating my block type though "admin/structure/block/block-content/types" or with configuration files.

The thing is I have been scraping google for two days already and I dont manage to figure out how to programmarically create a block type

And this that the information is not easily found on google makes me think that instead I need to create my type with configuration and then apply my plugin on creation of a new block but im still not sure how to do that and what my plugin needs to extend.

Can anyone give me a hint!

Thanks a lot.

  • When creating custom block types programatically you create a Block plugin. There are a ton of guides how to do that, here's one. valuebound.com/resources/blog/… – user72672 Jan 1 at 17:00
  • Thank you for the reply. I have already written this block plugin. and I have found tons of guides just like the one you linked here. but they all finish with one single block. I want that my user will be able to create as many blocks as they wish. – crab Jan 1 at 17:15
  • Oh, this works in panels, but not in core. You have to add a deriver to the block plugin in order for it to work. Look at this post for help. drupal.stackexchange.com/questions/264177/… – user72672 Jan 1 at 17:29
  • The discussion is confusing. A custom block type is the bundle of the block content entity (like content type for nodes) and not a block plugin. @crab, please make it more clear what you want to create. – 4k4 Jan 1 at 17:43
  • I want to create block type! I think my question is clear. I can delete the last part if its confusing. – crab Jan 1 at 17:58

You can create content block type using configuration files:
In you module should have config/install/block_content.type.YOUR_BLOCK_TYPE_MACHINE_NAME.yml see the following example from core for Basic block core/profiles/standard/config/install/block_content.type.basic.yml .

Here is an example to create new type called My Block Type

  1. Go to admin/structure/block/block-content/types Create by clicking on Add custom block type
  2. Create fields you want by Manage Fields

  3. To export your configuration Go to admin/config/development/configuration/single/export enter image description here And Create a config file in your Module and put in it the result: YOURMODULENAME/config/install/block_content.type.my_block_type.yml

  4. And also you should export fields associated to your block type: the same way you did with block type config: Go to admin/config/development/configuration/single/export choose Field as configuration type and choose all Configuration name with name block_content.my_block_type.FIELD_NAME like the body field below enter image description here and then the Field Storage configuration.

Or you can export configuration using Drupal console like the following:

drupal config:export:entity block_content my_block_type --module="YOURMODULENAME" --optional-config --remove-uuid --remove-config-hash --include-module-dependencies
| improve this answer | |

I had the same issue and I hope I have resolved it.

Your algorithm is next:

  1. Create your own module
  2. Create file .install
  3. There must be at least one hook hook_install (I have used two: hook_install and hook_uninstall)
  4. Inside install hook:

    -create a new block type

    -create fieldStorageConfig

    -create fieldConfig

    -set component for form and view display

My code:

function <your_module_name>_install() {
  $newBlockType = BlockContentType::create([
    'id' => <your_id>,
    'label' => 'Custom block type',
    'description' => "A custom block type",

  $blockId = $newBlockType->id();

  block_content_add_field($blockId, 'Icon', 'custom_block_icon', 'image', 'image', 'image_image');
  block_content_add_field($blockId, 'Count', 'custom_block_count', 'integer', 'number_integer', 'number');
  block_content_add_field($blockId, 'Description', 'custom_block_description', 'text', 'text_default', 'text_textfield');

function block_content_add_field(
  $viewDisplayType = 'text_default',
  $formDisplayType = 'text_textarea_with_summary') {
    // Add or remove the body field, as needed.
    $field = FieldConfig::loadByName('block_content', $blockTypeId, $componentName);
    if (empty($field)) {
      $fieldStorage = FieldStorageConfig::loadByName('block_content', $componentName);
      if (empty($fieldStorage)) {
        $fieldStorage = FieldStorageConfig::create([
          'field_name' => $componentName,
          'entity_type' => 'block_content',
          'type' => $fieldStorageType,

      $field = FieldConfig::create([
        'field_storage' => $fieldStorage,
        'bundle' => $blockTypeId,
        'label' => $label,
        'settings' => ['display_summary' => FALSE],


      /** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
      $display_repository = \Drupal::service('entity_display.repository');

      // Assign widget settings for the default form mode.
      $display_repository->getFormDisplay('block_content', $blockTypeId)
        ->setComponent($componentName, [
          'type' => $formDisplayType,

      // Assign display settings for default view mode.
      $display_repository->getViewDisplay('block_content', $blockTypeId)
        ->setComponent($componentName, [
          'label' => 'hidden',
          'type' => $viewDisplayType,

    return $field;

Result: the new custom block type with 3 fields.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.