A Kirby 5 CMS panel plugin that provides a safe, time-limited debug mode toggle with automatic expiry and git-safe flag file management.
- Flag-based debug control - Uses a
.debug_enabledflag file instead of modifyingconfig.php - Panel auto-debug - Automatically enables debug for panel when authorized users are logged in (prevents panel lockout)
- Auto-expiry - Debug mode automatically disables after configured hours
- Permission system - Restrict access by admin status, role name, or custom callback
- Git-safe - Automatically adds flag file to
.gitignore - Panel UI - Clean card-based interface with status indicator
- Dark/Light mode - Fully responsive to Kirby panel theme (Kirby 5) and fallback for Kirby 4
- Real-time status - Shows who enabled debug and when it expires
The built-in Kirby workarounds for toggling debug mode didn't fully fit my needs. So I built this for myself. It does exactly what I need and nothing more. If it fits yours too, feel free to use it.
- Download and extract the plugin to
site/plugins/debug-toggle/ - The plugin structure should be:
site/plugins/debug-toggle/ ├── index.php ├── index.js ├── index.css ├── README.md └── LICENSE
composer require martino/kirby-debug-togglesite/config/config.php:
return [
// REQUIRED: Debug mode controlled by flag file
// Replace any existing 'debug' => true with this closure
'debug' => (function() {
$flag = __DIR__ . '/.debug_enabled';
if (!file_exists($flag)) return false;
$data = @json_decode(file_get_contents($flag), true);
if (!$data || empty($data['expires_at'])) return false;
return time() < $data['expires_at'];
})(),
// OPTIONAL: Plugin configuration (uses defaults if omitted)
'Martino.debug-toggle.expiry-hours' => 4, // Hours until auto-disable (default: 4)
'Martino.debug-toggle.permission' => 'admin', // Who can toggle (default: 'admin')
'Martino.debug-toggle.panel-auto-debug' => true, // Auto-enable debug for panel (default: true)
];Important: The debug closure is required for the plugin to work. Without it, the panel UI will appear but debug mode won't actually activate when toggled.
Panel Auto-Debug: By default, debug mode is automatically enabled in the panel for authorized users (even when the toggle is OFF). This prevents panel corruption from hiding errors. You can disable this by setting 'Martino.debug-toggle.panel-auto-debug' => false.
Type: int
Default: 4
Number of hours until debug mode automatically disables.
'Martino.debug-toggle.expiry-hours' => 8, // 8 hoursType: string|callable
Default: 'admin'
Controls who can access and toggle debug mode.
Options:
-
'admin'- Only users with admin status (usesisAdmin())'Martino.debug-toggle.permission' => 'admin',
-
Role name - Only users with specific role
'Martino.debug-toggle.permission' => 'editor', 'Martino.debug-toggle.permission' => 'developer',
-
Custom callback - Custom permission logic
'Martino.debug-toggle.permission' => function($user) { return in_array($user->email(), ['[email protected]', '[email protected]']); },
Type: bool
Default: true
Automatically enables debug mode in the panel for authorized users, even when the toggle is OFF.
Why this exists: If the panel breaks due to an error, you need debug mode to see what went wrong. With this enabled, authorized users always see panel errors, preventing you from being locked out.
'Martino.debug-toggle.panel-auto-debug' => true, // Always show panel errors to authorized users
'Martino.debug-toggle.panel-auto-debug' => false, // Disable auto-debug (not recommended)Behavior:
- ✅ Frontend: Controlled by the toggle (manual)
- ✅ Panel (authorized users): Always ON (auto-debug)
- ✅ Panel (public/unauthorized): Controlled by the toggle
- Log in to the Kirby panel as an authorized user
- Click Debug in the sidebar menu
- Click Turn ON to enable debug mode
- Debug mode will automatically disable after the configured expiry time
- Click Turn OFF to manually disable debug mode
The debug toggle interface displays:
- Status - Current state (ON/OFF)
- Enabled by - Email of user who enabled debug
- Expires at - Timestamp when debug will auto-disable
- Warning message - Reminder that errors are visible to all visitors
- Status indicator - Visual dot (orange = active, gray = inactive)
The plugin uses a flag file at site/config/.debug_enabled to control debug mode:
{
"enabled_by": "[email protected]",
"enabled_at": 1712345678,
"expires_at": 1712359678
}Benefits:
- No modification of
config.phprequired - Git-safe (automatically added to
.gitignore) - Automatic expiry prevents forgotten debug mode
- Tracks who enabled debug and when
- All API routes require authentication and permission checks
- Flag file is created with
chmod 0600(owner read/write only) - Expired flags are automatically deleted on next state check
- Default state is OFF (no flag file = no debug)
The plugin provides two API endpoints:
Returns current debug state and metadata.
Response:
{
"debug": true,
"enabled_by": "[email protected]",
"enabled_at": "2024-04-05 14:00",
"expires_at": "2024-04-05 18:00",
"expired": false
}Toggles debug mode on or off.
Request:
{
"enabled": true
}Response: Same as GET endpoint
- Kirby 5.x
- PHP 8.2+
- Panel access with appropriate permissions
- Verify you're logged in as an admin user (or user with configured permission)
- Check that the plugin files are in
site/plugins/debug-toggle/ - Hard refresh the panel (Cmd+Shift+R / Ctrl+Shift+R)
- Verify the debug config closure is added to
config.php - Check file permissions on
site/config/directory - Ensure
.debug_enabledfile can be created/deleted
- Verify your user has the required permission level
- Check the
Martino.debug-toggle.permissionconfig option
site/plugins/debug-toggle/
├── index.php # Backend: panel area, API routes, helpers
├── index.js # Frontend: Vue component
├── index.css # Styles: dark/light mode support
├── README.md # Documentation
└── LICENSE # MIT License
The plugin provides these helper functions:
debugFlagPath()- Returns path to flag filedebugFlagData()- Reads and decodes flag filedebugFlagExpired()- Checks if flag has expireddebugFlagActive()- Checks if debug is currently activedebugHasPermission()- Checks if current user has permissionensureGitIgnore()- Adds flag file to.gitignore
MIT License - Copyright (c) 2026 João Martino / nonverbal
See LICENSE file for details.
João Martino
nonverbal
nonverbalclub.pt
For issues, questions, or contributions, please visit the GitHub repository.
Questions or doubts:
Made with ❤️ for the Kirby community
