Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ninja Keys Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Requirements: PHP 8.3+, Laravel 12 or 13. This is a hard upgrade gate if you are still on Laravel 10/11 or PHP 8.2.
  • Install: 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.
  • Render the palette once in your main layout:
    <x-ninja-keys />
    
    or with the directive:
    @ninjaKeys
    
    @ninjaKeysScripts still works but is the legacy entry point; prefer the component/directive for new work.
  • First use case: register a few global actions in a service provider and let developers open the palette with 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'));
    });
    
  • Where to look first: the published 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.

Implementation Patterns

  • Global actions in a service provider: use 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);
    });
    
  • Handlers are callables and receive the action object. v1.0.0 fixes the previous action.handler is not a function failure by passing the callable correctly. Use closures or invokable objects; do not pass a string function name.
  • Navigation actions: prefer 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.
  • Conditional actions: use 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.
  • Per-page overrides: pass component attributes on the <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.
  • Click triggers: add 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.
  • Nested actions: define parent/child action trees through the package API. The package flattens trees internally to work around ninja-keys 1.2.2 moving root actions into submenus, so rely on the package's tree API rather than hand-writing ninja-keys nested data.
  • Livewire 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.
  • CSP: both scripts receive the configured CSP nonce. If you run a strict CSP, prefer published local assets over the CDN fallback so the script origin is controlled.

Gotchas and Tips

  • Breaking config changes: 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.
  • Removed options: hotKeys, searchPlaceholder, and noHeader are gone from config. Move those behaviors to component attributes or your own layout/JS.
  • Actions must have both id and title: v1.0.0 throws InvalidArgumentException instead of silently skipping the action or rendering undefined. Add guards in dynamic action registration loops.
  • Handler signature changed to match ninja-keys: handlers receive the action. If you previously worked around the string-handler bug, remove that workaround and test handler closures.
  • Publish assets for production: the CDN fallback is useful for local prototyping, but it introduces an external dependency and may conflict with CSP. Run the asset publishing step and set asset_url if you host assets elsewhere.
  • Search escaping: regex characters like ( 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.
  • Gate filtering is render-time: hidden actions and their nested children are removed when the palette renders. If permissions change without a page reload, re-render the component or refresh the relevant Livewire component.
  • Octane safety: the manager is scoped per request. Do not capture the manager in long-lived singletons or store request-specific actions in static properties across requests.
  • Duplicate palettes: the old global 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.
  • Legacy directive: @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.
  • Debugging tip: check 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.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource