Rabbit Hole
Controls the behavior of entity canonical pages, allowing redirect, access denial, or 404 responses instead of displaying content.
rabbit_hole
Install
composer require 'drupal/rabbit_hole:8.x-1.0'
Overview
Rabbit Hole adds the ability to control what should happen when an entity is being viewed at its own page (canonical URL). This is useful for entities that should not be directly accessible, such as nodes used only as viewsource or paragraphs that should never be viewed standalone.
The module provides four built-in behaviors: displaying the page normally, returning a 403 Access Denied response, returning a 404 Page Not Found response, or redirecting to another URL with configurable HTTP response codes. Token support enables dynamic redirect destinations based on entity field values.
Configuration can be set at the entity type level, bundle level, or overridden per individual entity. The permission system allows administrators to configure behaviors while allowing certain users to bypass restrictions and view pages normally.
The module uses a plugin architecture that allows developers to create custom behaviors beyond the four built-in options. All behaviors are invoked via an event subscriber that intercepts kernel requests to entity canonical routes.
Features
- Control canonical page behavior for any content entity type with a canonical link template
- Four built-in behaviors: Display Page, Access Denied (403), Page Not Found (404), and Page Redirect
- Page redirect supports configurable HTTP response codes (301, 302, 303, 304, 305, 307)
- Token support in redirect paths for dynamic destinations based on entity field values
- Fallback behavior configuration when redirect path is invalid or empty
- Per-entity-type, per-bundle, and per-entity override settings
- Permission-based bypass allowing administrators to view restricted pages
- Optional warning message display for users who bypass the configured action
- Plugin architecture for creating custom behavior plugins
- Event subscriber intercepts kernel.request and kernel.response events for canonical entity routes
- Alter hooks for modifying behavior values and responses programmatically
- Configuration entity storage for bundle-level settings
- Custom field type for storing per-entity override settings
- Translatable per-entity settings support
Use Cases
Hide landing page nodes used only as Views sources
When using nodes as data sources for Views (e.g., a 'Slide' content type that populates a slideshow), individual node pages have no useful content. Configure Rabbit Hole with 'Page not found' or 'Page redirect' behavior for these content types to prevent users from accessing meaningless pages while the nodes remain usable in Views.
Redirect product pages to category listings
For e-commerce sites where individual product pages should not be directly accessible, configure Rabbit Hole with 'Page redirect' behavior using a token like [node:field_category:entity:url] to redirect visitors to the product's category page instead.
Restrict access to premium content
Use the 'Access denied' behavior for content types that require special access. Combined with the bypass permission, premium subscribers can view pages normally while anonymous users see access denied messages.
Prevent direct access to paragraph library items
Paragraph library items should typically only be viewed within the context of their parent entity. Configure Rabbit Hole with 'Page not found' to prevent direct URL access to these items.
SEO redirects for migrated content
When migrating content from an old site structure, use the 'Page redirect' behavior with 301 (Moved Permanently) to redirect old URL patterns to new locations, preserving SEO value.
Redirect user profiles to external directory
For organizations using an external staff directory, configure Rabbit Hole on user entities to redirect profile pages to the external directory URL, possibly using tokens to construct user-specific URLs.
Create honeypot pages for security monitoring
Create content types that trigger 'Access denied' responses. Any access attempts to these pages can be logged and monitored as potential malicious activity.
Tips
- Enable the Token module for enhanced redirect path options with dynamic token replacement based on entity fields
- Use 301 (Moved Permanently) redirects for permanent URL changes and 302 (Found) for temporary redirects to ensure proper SEO handling
- The bypass permission allows content editors to preview pages that would otherwise be restricted - grant this to trusted roles
- When disabling entity overrides for a bundle with existing values, all per-entity settings will be deleted - the confirmation prompt prevents accidental data loss
- Test redirect paths thoroughly when using tokens - invalid paths will trigger the fallback behavior
- For multilingual sites, Rabbit Hole settings are translatable, allowing different behaviors per language
- Custom behavior plugins can be created by extending RabbitHoleBehaviorPluginBase and using the @RabbitHoleBehaviorPlugin annotation
- The deprecated submodules (rh_node, rh_user, etc.) will be removed in version 3.0 - migrate to the unified configuration system
Technical Details
Admin Pages 2
/admin/config/content/rabbit-hole
Main configuration page for enabling Rabbit Hole functionality on different entity types. Displays a table of all supported content entity types with checkboxes to enable/disable Rabbit Hole for each type. For enabled entity types, shows current bundle configurations including the default behavior and whether per-entity overrides are allowed.
/admin/config/content/rabbit-hole/{entity_type_id}
Configuration page for setting Rabbit Hole behavior on specific bundles of an entity type. Allows setting the default behavior, enabling per-entity overrides, and configuring bypass options for each bundle.
Permissions 3
Hooks 3
hook_rabbit_hole_values_alter
Allows modules to alter Rabbit Hole values before the behavior plugin is loaded and executed. Can modify the action, bypass access, or any other values that affect behavior execution.
hook_rabbit_hole_response_alter
Allows modules to alter the response after the behavior plugin's performAction() method has been executed. Can modify redirect destinations or replace the response entirely.
hook_rabbit_hole_rabbit_hole_behavior_plugin_info_alter
Allows modules to alter the behavior plugin definitions discovered by the plugin manager.
Troubleshooting 7
Rabbit Hole only supports content entity types that have a canonical link template defined. Check that your entity type definition includes a 'canonical' link template.
Verify that the user does not have the 'Bypass Rabbit Hole action' permission for the entity type. Check if 'Disable permissions-based bypassing' is enabled in bundle settings.
Ensure the Token module is installed and enabled. Verify the token syntax is correct for the entity type (e.g., [node:field_name] for nodes, [user:field_name] for users).
This is expected behavior. Rabbit Hole automatically redirects to the entity edit form after saving when a non-display behavior is configured to prevent landing on error pages.
If entities have per-entity override values stored in the database, you must first disable overrides for all bundles (which deletes the values) before you can disable the entity type.
Check that 'Allow these settings to be overridden for individual entities' is enabled for the bundle, and that the current user has the 'Administer Rabbit Hole settings for [entity type]' permission.
The fallback action only triggers when the redirect path is invalid or empty after token replacement. Test with an entity that has empty values in the token fields.
Security Notes 6
- Rabbit Hole is covered by Drupal's security advisory policy
- The redirect functionality validates URLs to prevent open redirect vulnerabilities - external URLs are handled via TrustedRedirectResponse
- Permission checks are performed before displaying configuration options - users without 'rabbit hole administer' permission cannot see or modify settings
- The 'no_bypass' option allows strict enforcement of behaviors even for administrators - use carefully as it can lock out access to content
- Per-entity override values are stored in a standard Drupal field with proper access control
- Token replacement in redirect paths is sanitized through Drupal's token system