How to create custom entity in Drupal 11

Building

Quick summary

Learn how to create a custom entity in Drupal 11 using the Entity API. This guide covers base fields, bundles, handlers, and best practices to build powerful custom data models.

Introduction

Drupal 11 custom content entity allow developers to define entity new type of data objects beyond the built-in nodes, users, taxonomy terms etc. In this guide we’ll walk through how to build a custom entity in Drupal 11, including how to define the entity, add bundles, base fields, and use the Entity API in practice. We’ll reference key Drupal concepts like Drupal 11 custom content entity, define baseFieldDefinitions Drupal, create entity bundle Drupal 11, and illustrate using a ContentEntityBase example Drupal.

What is a custom content entity in Drupal

Developer defined data structure bases on fundamental entity API is called custom content entity in Drupal. Its working is similar to Drupal inbuilt entities like node or user. But its control is in your hand like how it is saved, what data it contains, how it behaves, what bundles it supports, and how access is controlled.

In contrast to a simple content type (which is just a bundle of the node entity), a custom entity gives you a new entity class, storage handler, schema, and optionally bundle support. This makes it ideal for domain-specific content models (for example, “Event”, “SurveyResponse”, “ProductReview” etc) where you want tailored behaviours beyond what nodes provide.

When should you use a custom entity instead of a Node?

Here are some guidelines to help decide when to choose a custom entity instead of a node in Drupal 11.

  • If you need custom storage, a custom database schema, or performance optimizations that don’t map well to the node/field API, then a custom entity may be the better fit.
  • If the data object has different semantics, lifecycle, or access control compared to standard content (for example, audit logs, configuration data, domain-specific records), then a custom entity is appropriate.
  • If you want to expose the entity via API (JSON API) and treat it similarly to other content entities, custom entity support is a suitable option.
  • On the other hand, if your content model is essentially a typical content type (just fields), easily editable by the author, and utilizes standard node features (revisioning, workflows, path aliasing, etc.), then sticking with a node content type is simpler.

Most frequently asked question in FAQ

A node is a built-in Content entity with all the usual integrations (field UI, path aliasing, revisioning, content type bundle, etc). A custom entity gives you the freedom to define a completely new entity type (and optional bundles) with custom storage, handlers, fields, and behaviours.
Developers choose them when they need more control, custom behaviour, or want to decouple from the node concept while still leveraging the Entity API. For many sites standard content types suffice, but for complex or bespoke data models custom entities shine.
See the list above for typical mistakes and fixes: mismatched schema, missing bundle definitions, handler issues, views misconfigurations, permission problems, and JSON:API exposure omissions.

Steps to create a custom entity in Drupal 11

Here is a high-level workflow to create a custom content entity with bundles in Drupal 11

  • Define a new custom module (my_module) with .info.yml, .module, etc.
  • In your custom module, define the entity type in my_module/src/Entity/MyEntity.php, implement ContentEntityInterface, or extend ContentEntityBase.
  • Inside of my_module/my_module.entity_type.yml, declare the entity type with parameters like id, label, handlers, base_table, data_table, bundle_of, etc.
  • Add the bundle entity (if required) in MyEntityType.php, or declare a bundle in YAML.
  • In the entity class, implement public static function baseFieldDefinitions(EntityTypeInterface $entity_type) to define base fields.
  • Create the install hook to provide the schema or rely on Drupal’s ContentEntityBase default schema based on base field definitions.
  • Provide UI handlers (list, form, access) by specifying them in the handlers section of the entity type definition.
  • Register routes, controllers, and menu links for managing the entity (add/edit/delete list).
  • Optionally, integrate with Views, JSON: API, permissions, and other modules.
  • Update your module to define field UI, display modes, and view modes for the custom entity.
  • Clear caches, run install/upgrade, then test creating, editing, and listing the entity.
  • Debug and refine as needed.
  • How to future-proof your website for upcoming features

In each of these steps, you are essentially following the Drupal Entity API tutorial style—defining handlers, base fields, bundle support, UI, and integration.

How to define base fields in a custom entity

Base fields are the fields defined on the entity type itself (shared across all bundles). They are declared using baseFieldDefinitions() in your entity class (or trait).

For example:

Here you are using the define baseFieldDefinitions Drupal method to set up the fields. You can add other field types (entity_reference, boolean, decimal, etc) depending on your data model.

You then ensure those fields are included in your entity_type.yml and handled by Drupal’s default schema generation via ContentEntityBase or your custom storage handler. This ensures consistency and low overhead.

Adding bundle support to a custom entity

If you want your custom entity to support multiple sub types (bundles) just like nodes support content types, you must declare bundle_entity_type in your entity type YAML and/or provide a bundle entity class. For example:

In your module, you also define MyEntityType.php class extending ConfigEntityBundleBase (or similar) to represent each bundle, and provide YAML definitions for each bundle (machine name, label, description etc).
With bundle support enabled, you can then treat each bundle differently in terms of base/field definitions, form/display modes, permissions, etc. This pattern lets you “create entity bundle Drupal 11” and treat bundles as first-class types.

Content entity base example in Drupal 11

Let’s look at an example of a custom entity, article review, that allows bundles.
We’ll extend content entity base:

In this example, you can see how the Content Entity Base example in Drupal is realised: you extend the base class, declare metadata via annotation @ContentEntityType, define handlers, base table, bundle support, entity keys, etc. Then you implement baseFieldDefinitions() to define the foundational fields.

Once the module is enabled, Drupal will create the schema, and you can start adding bundles and fields via UI (if you’ve enabled Field UI support) or in code.

Handling views, forms, and display for custom entities

Once your custom entity type is defined and installed, you’ll typically:

  • Create list builders (via list_builder handler) for admin listing screens.
  • Create form controllers (default, add, edit, delete) for users/editors to work with the entity.
  • Configure display modes: define how the entity is rendered in the front end and in the admin UI.
  • Use Views to make listings of your custom entities. Since your entity type implements EntityInterface and uses ContentEntityBase, it is automatically approved by Views once the module is enabled.
  • Expose the entity via JSON: API, REST, or GraphQL (if you’ve configured support) so it can be consumed by external systems.
  • Manage field configuration: you can assign additional fields (via UI or code) to the bundle(s), modify form/display settings per bundle, manage permissions, etc.
  • Ensure permission handlers and access control so only authorised users can view, create, edit or delete the entity instances.

This entire flow aligns with the Drupal Entity API tutorial mindset: you define storage, handlers, UI, access, views, forms, and display.

Common pitfalls and debug tips

When implementing a custom entity in Drupal 11 you may confront several common errors:

  • Schemamismatch errors: If baseFieldDefinitions change after installation without updates, the database table may be out of sync. Use drush entity: updates or write an update hook.
  • Bundle entity not found: If you declare bundle_entity_type but don’t define the bundle class or YAML for the bundle entity, you’ll get errors when trying to add or list bundles.
  • Wrong handlers or missing route links: Ensure your links in the annotation/definition match actual routes or controllers exist, or else menu items will fail.
  • Field UI not enabled: If you expect to see the custom entity in the “Manage fields” UI and can’t, ensure you’ve set field_ui_base_route, and that the Field UI module is enabled.
  • Views listing blank: Ensure the entity type is properly declared with the base_table and data_table, and has the correct entity_keys so Views can identify id/label/uuid.
  • Permission issues: Always properly define the access control handler (if you override) and ensure that roles have the correct permissions; otherwise, entity creation/editing will fail silently.
  • JSON: API exposure missing: If you expect your custom entity to appear in JSON: API endpoints but it doesn’t, ensure that the entity type has json_schema and/or you’ve configured JSON: API settings so the new entity type is exposed.

See the list above for typical mistakes and fixes: mismatched schema, missing bundle definitions, handler issues, views misconfigurations, permission problems, and JSON: API exposure omissions.

Best practices for custom entities in Drupal 11

  • Use meaningful machine names and labels for your entity types and bundles.
  • Keep your entity definitions clean, well-documented, and version-controlled.
  • Define base fields carefully – only fields common to all bundles of the entity type. Use configurable fields for bundle-specific fields.
  • Provide revision support if your entity needs versioning (use RevisionableInterface and set revision handlers).
  • Use proper handlers for storage, access, and list builders — don’t rely purely on defaults if your entity has special behaviour.
  • Write update hooks for any schema or field changes after installation.
  • Plan for field UI, display modes, View integration, and REST/JSON API exposure upfront.
  • Consider performance: if your entity will have many records, optimise queries, indexes, and use appropriate storage handlers.
  • Leverage the composite architecture of Drupal’s Entity API instead of “reinventing the wheel”.
  • Also, cross-link your custom entity with other entities when necessary, using entity_reference base fields; treat relationships explicitly.
  • As you design your custom entity, remember that although it allows advanced control, it also adds complexity. If the requirement is simple content, a node content type might be enough.
  • Drupal 10 to 11 upgrade guide: How to safely update your site in 2026

Conclusion

Create custom entity in Drupal 11 allows you to define powerful, domain-specific content models using the Entity API. From defining base fields with define baseFieldDefinitions, adding bundle support, extending ContentEntityBase example Drupal, to integrating with Views, forms and APIs, you now have a road-map to build your own custom entity type. Remember to assess when this approach is necessary (versus simply using nodes), adopt best practices, and watch out for common pitfalls. With the right structure, your custom entity will serve as a strong foundation for your project’s data architecture.

Author : Jay Prakash Kushwah Date: December 5, 2025