In my decoupled Drupal + Next.js setup, editing or deleting a redirect entity has no effect on the Next.js frontend cache. The stale redirect continues to be served to visitors even after the change is saved in Drupal.

Steps to reproduce:

  1. Have a Next.js frontend with "use cache" (or ISR) enabled.
  2. Visit a URL that resolves via a Drupal redirect, e.g. /old-blog redirects to /blog/my-post. The frontend caches this resolution.
  3. In Drupal, edit that redirect (change the source, destination, or status code) or delete it entirely.
  4. Visit /old-blog on the frontend again — it still serves the old cached redirect. Drupal's revalidation signal had no effect.

Expected: The Next.js cache for the affected path is cleared after the redirect is changed or deleted, so the next visit reflects the current Drupal state.

Actual: The cache is never cleared. The Path revalidator sends ?path=/admin/config/search/redirect/edit/42 (the redirect entity's canonical URL in Drupal, which is its admin form) to Next.js instead of the frontend source path like ?path=/old-blog. Next.js has no cached entry for the admin URL, so the revalidation is a silent no-op.

Proposed resolutions:

Option 1: Patch the existing Path plugin

Add a redirect-aware branch inside Path::revalidate(). When the entity being saved is a Redirect, use $entity->getSource()['path'] instead of $event->getEntityUrl() to build the revalidation path. This keeps everything in one place but introduces a redirect module dependency into the next module's core Path plugin.

Additionally, to handle source renames (where both the old and new paths need revalidating), EntityActionEvent::createFromEntity() would need to capture $entity->original onto the event object at construction time, because by the time the revalidator runs at kernel.terminate, core has already called unset($entity->original). A new getOriginalEntity() getter on the event would expose this to any revalidator.

Option 2: Create a new dedicated Redirect revalidator plugin

Add a separate plugin (e.g. redirect_path) that handles redirect entities exclusively. It reads $entity->getSource()['path'] for the current source and uses the same getOriginalEntity() approach for the old source on rename. This keeps the existing Path plugin clean and dependency-free, and gives site builders a dedicated option to select for redirect entity types.

Please help me on deciding which approach is better.

Comments

jatin.buzz created an issue. See original summary.

jatin.buzz’s picture

Assigned: Unassigned » jatin.buzz