amjadiqbal/laravel-ninja-keys
Laravel Ninja Keys adds a fast keyboard-driven command palette to Laravel apps, letting users search and run actions, navigate pages, and trigger shortcuts through an elegant Ninja Keys interface with simple configuration.
composer require the package, then publish config with the new tag:
php artisan vendor:publish --tag=ninja-keys-config
Publish the bundled ninja-keys assets using the ninja-keys-assets tag (or Laravel's laravel-assets publishing) so the palette does not rely on the CDN fallback.<x-ninja-keys />
or with the directive:
@ninjaKeys
@ninjaKeysScripts still works but is the legacy entry point; prefer the component/directive for new work.Cmd/Ctrl+K. Start with navigation actions before wiring complex handlers:
use NinjaKeys\Facades\NinjaKeys;
NinjaKeys::define(function ($keys) {
$keys->action('Dashboard')
->id('dashboard')
->route('dashboard');
$keys->action('Create project')
->id('projects.create')
->href(route('projects.create'));
});
config/ninja-keys.php, the package README for action/component examples, the Blade component attributes, and the NinjaKeys manager API (define(), has(), forget(), clear()). v1.0.0 also adds a php artisan about entry, which is useful for confirming the package is loaded and how assets are configured.NinjaKeys::define() callbacks to register actions at render time. This is the central place for app-wide commands, routes, and handlers.
NinjaKeys::define(function ($keys) {
$keys->action('Open billing')
->id('billing')
->route('billing.index')
->handler(fn ($action) => /* optional extra work */ null);
});
action.handler is not a function failure by passing the callable correctly. Use closures or invokable objects; do not pass a string function name.href() for normal links and route() for named routes. route() supports opening a new tab with _blank; when livewire_navigate is enabled it uses Livewire.navigate() so navigation stays within Livewire's SPA behavior.has(), forget(), and clear() to register or remove actions based on the current user, tenant, feature flags, or page context. Gate filtering also hides actions automatically and now correctly hides sub-actions and nested children of hidden actions.<x-ninja-keys /> instance for page-specific behavior instead of relying on the removed global config keys (hotKeys, searchPlaceholder, noHeader). Treat the component as the per-page configuration surface.data-ninja-keys-open to buttons or links, optionally with a value to open a specific submenu. This is useful for contextual palettes on settings pages, dashboards, or admin screens.onSelected hook: use this for analytics or cross-cutting UI reactions when an action is chosen. Keep it lightweight; it runs in the browser on every selection.wire:navigate: v1.0.0 fixes stale/duplicate hotkeys after navigation. If you register actions manually in JavaScript outside the package, clean them up on livewire:navigated; actions registered via NinjaKeys::define() and the Blade component should follow the page lifecycle.use_cdn and asset_path became script and asset_url. The config publish tag is now ninja-keys-config. Update deployment scripts and any custom config references.hotKeys, searchPlaceholder, and noHeader are gone from config. Move those behaviors to component attributes or your own layout/JS.id and title: v1.0.0 throws InvalidArgumentException instead of silently skipping the action or rendering undefined. Add guards in dynamic action registration loops.asset_url if you host assets elsewhere.( and [ are now escaped before ninja-keys builds its search RegExp. This fixes keystroke crashes, but it also means the search box behaves as literal text search, not regex search.const ninja issue is fixed, so rendering the palette twice no longer breaks the inline script. Still avoid intentionally mounting multiple palettes unless you have a clear layering/accessibility plan.@ninjaKeysScripts remains supported, but new code should use <x-ninja-keys /> or @ninjaKeys. Mixing old and new entry points may produce duplicate script inclusion or confusing per-page overrides.php artisan about for the package entry, inspect the published asset path under public/vendor/ninja-keys, and confirm the nonce is present on both the palette script and the inline bootstrap script when CSP is enabled.How can I help you explore Laravel packages today?