Drupal is a registered trademark of Dries Buytaert

revref

No security coverage
View on drupal.org

Drupal stores entity relationships in one direction; a node that references a taxonomy term knows about that term, but the term has no built-in way to know which nodes reference it. The Reverse Reference module helps to solve this.

It provides a lookup service, a performance index, and precise render cache tags so you can discover and display "what references this entity" reliably, efficiently, and with correct caching behaviour.

Features

Drupal's entity reference system is one-directional by design. When you add a reference field to a content type, the source entity knows its targets, but targets have no awareness of what references them.

For simple use cases this is fine. But it becomes a problem as soon as you need to:

  • Display a block showing "profiles at this location" on a map pin page
  • Show a count of how many articles reference a given tag
  • Build a "related content" block based on shared taxonomy terms
  • Know which nodes reference a media asset before deleting it
  • Feed a decoupled front end with reverse relationship data via JSON:API

Without this module, the standard solution is an entityQuery on every page load, which can't be cached correctly. The query result can change when any referencing entity is saved, but nothing tells Drupal's render cache to invalidate.

Render cache correctness

The module generates revref:<entity_type>:<id> cache tags and attaches them to reverse lookup results automatically.

When a referencing entity is saved and its references change, only the affected tags are invalidated, precisely and synchronously.

Blocks and pages that display reverse reference data are cached correctly and invalidate only when necessary.

A reverse lookup service

The reverse_reference.lookup service provides findReferencers() and countReferencers() methods for use in custom modules, hooks, preprocess functions, and Drush scripts. Both methods are scope-controlled. You specify which entity type, bundles, and optionally which fields to search. Both always return correct results, using an optimised index when available and falling back to entityQuery automatically when not.

Computed field plugins

Add a reverse_entity_reference or reverse_entity_reference_count field to any entity type without writing code. These computed fields integrate natively with the Entity API, Views, and the field formatter system. Cache tags are bubbled correctly to the parent render array.

An asynchronous performance index

Reference data is written to a dedicated revref_index database table by a queue worker after each entity save. Lookups against the index are a single indexed database read rather than an entityQuery scan. The index is a performance optimisation only; lookups fall back to entityQuery transparently if the index is unavailable or stale. Correctness is never dependent on the index.

Migration and bulk operation safety

A revref.defer_indexing state flag suppresses queue flooding during migrations and bulk imports. Run drush revref:rebuild once when the operation is complete to populate the index cleanly.

Events

ReverseReferenceChangedEvent is dispatched synchronously when relationships change, carrying the source entity and the added and removed target IDs. ReverseReferenceIndexedEvent is dispatched after the async index update. Subscribe to these events to trigger secondary operations (search re-indexing, webhook notifications, audit logging) without duplicating reference-change detection logic in your own hooks.

Explicit access control

Every call to the lookup service requires an explicit access_check: TRUE or access_check: FALSE option. There is no silent default. Presentation-layer code should pass TRUE; system-level code passes FALSE with documented intent.

Post-Installation

After enabling the module, review the default configuration in revref.settings.yml or via your configuration management workflow:

  • index_entity_types: which entity types are included in the async index. Defaults to node, media, and taxonomy_term.
  • ignored_entity_types: types excluded from indexing regardless of the above. Defaults to paragraph, which is excluded because Drupal's paragraph revision behaviour creates high index churn.
  • revision_policy: controls which revision is indexed. The default published indexes only the latest published revision, which is correct for most public-facing sites. Set to default for editorial contexts where draft-state relationships need to be reflected in lookups.

Run drush revref:rebuild after first enabling the module to populate the index from existing content. On a large site this processes entities in batches via the queue worker and runs on cron.

To add a computed reverse reference field to a content type, use the standard Field UI at Manage fields → Add field and select Reverse entity reference or Reverse entity reference count from the field type list. Configure the scope (source entity type and bundles to search) and lookup options (access checking, published-only filtering) in the field settings form. No custom code is required.

Additional Requirements

Drupal core 10 or 11. No contributed modules are required.

The module depends only on core subsystems: the Entity API, Queue API, Key/Value store, Cache Tags, Field API, and Event Dispatcher. PHP 8.1 or higher is required, consistent with Drupal 10's minimum PHP version.

Entity Usage is the most complementary module. It tracks relationships across all reference types (including WYSIWYG embeds and Layout Builder blocks that this module intentionally excludes) and provides an editorial "Used by" UI tab on entity edit pages. The two modules solve overlapping but distinct problems and can run on the same site without conflict.

Use Entity Usage for editorial dependency visibility and deletion safety. Use this module for render cache correctness, computed field traversal, and performance-indexed lookups on entity reference fields.

Drush is required for the drush revref:rebuild command and is already a standard part of most Drupal development setups.

Similar projects

Entity Usage tracks reverse relationships and provides a "Used by" UI, but has no cache tag infrastructure. It cannot tell Drupal's render cache when to invalidate based on relationship changes.

The two modules are complementary rather than competing; see Recommended modules above for guidance on using both together.

Entity Reference Integrity and similar modules provide deletion protection and editorial visibility into dependencies, but do not provide cacheable reverse lookups, a computed field type, or a lookup service API.

No existing contrib module provides revref:-style cache tags, a computed reverse reference field type with correct cache metadata bubbling, or an async performance index for reverse lookups.

Activity

Total releases
3
First release
Mar 2026
Latest release
4 days ago
Release cadence
1 day
Stability
0% stable

Release Timeline

Releases

Version Type Release date
1.0.0-alpha2 Pre-release Mar 10, 2026
1.0.0-alpha1 Pre-release Mar 9, 2026
1.0.x-dev Dev Mar 9, 2026