matildevoldsen / quick-actions
Home screen quick actions (iOS) and launcher shortcuts (Android) for NativePHP Mobile
Package info
github.com/Matildevoldsen/quick-actions
Type:nativephp-plugin
pkg:composer/matildevoldsen/quick-actions
Requires
- php: ^8.3
- nativephp/mobile: ^3.0
Requires (Dev)
- laravel/framework: ^13.0
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
README
Home screen quick actions for NativePHP Mobile apps, with iOS home screen shortcuts and Android launcher shortcuts driven from Laravel.
This package is a Composer package named matildevoldsen/quick-actions. It is built for iOS and Android, requires nativephp/mobile, and is maintained by Matilde Enevoldsen.
What it does
- Registers shortcut items from Laravel
- Syncs those items to iOS and Android through the NativePHP bridge
- Supports route-based shortcuts and signed event-dispatch shortcuts
- Can publish selected items into Spotlight and App Shortcuts so users can launch them from search
- Ships a NativePHP post-compile hook for the generated iOS project
- Includes Boost guidelines and a small JavaScript bridge helper for advanced SPA use
Requirements
- PHP 8.3+
- Laravel
nativephp/mobile^3.0- Android SDK 29+
- iOS 18.0+
Installation
composer require matildevoldsen/quick-actions # First-time setup in the host app php artisan vendor:publish --tag=nativephp-plugins-provider # Register the plugin so NativePHP compiles the native code php artisan native:plugin:register zinxan/quick-actions # Verify registration php artisan native:plugin:list # Build / refresh the native projects php artisan native:install --no-interaction
The package service provider is auto-discovered by Laravel. Plugin registration is still required so the native Swift and Kotlin code is compiled into your app.
Permissions and native configuration
This plugin does not request any extra Android permissions and does not add any iOS Info.plist usage descriptions.
Platform configuration shipped in nativephp.json:
- Android
min_version:29 - iOS
min_version:18.0 - Android init function:
com.zinxan.plugins.quickactions.bootstrapQuickActions - iOS init function:
QuickActionsPlugin.bootstrap - iOS post-compile hook:
nativephp:quick-actions:post-compile
Usage (PHP)
Register quick actions during application boot so they are present before the response is finalized.
use ZinXan\QuickActions\QuickActions; use ZinXan\QuickActions\Shortcut; Shortcut::create('scan', 'Scan') ->icon('camera') ->dispatch(\App\Events\OpenScanner::class, [ 'source' => 'shortcut', 'redirectTo' => '/scanner', ]); QuickActions::addItem('Images') ->icon('photo') ->route('gallery.index'); Shortcut::create('ask-ai', 'Ask AI') ->icon('search') ->addToQuickActions() ->openRoute('ai.index');
QuickActions is launcher/app-icon first. Shortcut is Spotlight/App Shortcuts first. Either builder can opt into both surfaces.
Where to register items
Typical places to register items:
- a service provider
boot()method - route bootstrapping for app-wide shortcuts
- request-specific UI flows before the response finishes
The package syncs the registry after the application has booted and again at middleware termination, so request-specific shortcuts can still be finalized safely.
API reference
QuickActions::addItem(string $title, ?string $id = null): QuickActionItem
Creates a launcher quick action definition. If no ID is passed, the package derives a stable slug from the title so installed shortcuts keep working across restarts.
Shortcut::create(string $id, string $title): QuickActionItem
Creates a Spotlight/App Shortcuts definition using the explicit ID API.
use ZinXan\QuickActions\Shortcut; Shortcut::create('ask-ai', 'Ask AI') ->icon('search') ->openRoute('ai.index');
Separate surfaces, with opt-in crossover
use ZinXan\QuickActions\QuickActions; use ZinXan\QuickActions\Shortcut; QuickActions::addItem('Camera') ->icon('camera') ->addToShortcuts() ->route('camera.index'); Shortcut::create('ask-ai', 'Ask AI') ->icon('search') ->addToQuickActions() ->openRoute('ai.index');
QuickActionItem::icon(?string $symbolName): self
Sets the icon alias used by both platforms.
QuickActions::addItem('Search') ->icon('search') ->route('search');
QuickActionItem::route(string $name, array $parameters = []): self
Resolves a named Laravel route and stores the resulting in-app path.
QuickActions::addItem('Orders') ->icon('home') ->route('orders.index', ['status' => 'open']);
QuickActionItem::action(string $eventClass, array $payload = []): self
Creates a signed internal dispatch URL that resolves the given event class from the container using the payload as named constructor parameters.
QuickActions::addItem('Scan') ->icon('camera') ->action(\App\Events\OpenScanner::class, [ 'source' => 'quick-action', 'redirectTo' => '/scanner', ]);
The payload may include redirectTo; if omitted, the internal dispatch route redirects to /.
Surface methods
QuickActionItem::addToQuickActions(bool $enabled = true): selfQuickActionItem::addToShortcuts(bool $enabled = true): selfQuickActionItem::addToSpotlight(): self(alias ofaddToShortcuts())QuickActionItem::spotlight(bool $enabled = true): self(alias ofaddToShortcuts())
QuickActionItem::addToSpotlight(): self
Opt-in shortcuts surfaces for a launcher quick action.
QuickActions::addItem('Ask AI') ->icon('search') ->addToSpotlight() ->route('ai.index');
Only items marked with ->addToSpotlight() or ->addToShortcuts() are indexed into Spotlight/App Shortcuts when they start from QuickActions::addItem().
Fluent aliases
QuickActionItem::openRoute(string $name, array $parameters = []): selfQuickActionItem::dispatch(string $eventClass, array $payload = []): self
QuickActionsSync::sync(): void
Low-level sync service exposed through the QuickActionsSync facade alias. Most applications do not need to call this directly because the package syncs automatically.
use QuickActionsSync; QuickActionsSync::sync();
Usage (JavaScript)
This package also ships a small JavaScript helper in resources/js/index.js for advanced SPA-side bridge calls. The preferred and durable integration is still the PHP API above, because PHP registration is what persists and rehydrates shortcuts across app launches.
Re-export the helper from your frontend build:
// resources/js/nativephp-quick-actions.js export { QuickActionsBridge } from '../../vendor/zinxan/quick-actions/resources/js/index.js';
Then use it from Vue, React, or another SPA entrypoint:
import { QuickActionsBridge } from '@/nativephp-quick-actions'; await QuickActionsBridge.sync([ QuickActionsBridge.item({ id: 'scan', title: 'Scan', icon: 'camera', urlPath: '/scanner', quickAction: true, shortcut: true, }), ]);
QuickActionsBridge.sync() calls the same QuickActions.Sync bridge function used by the PHP synchronizer.
Events
This package does not dispatch its own fixed NativePHP event classes.
Instead, ->action() dispatches your event class when the signed quick-action URL is opened. The payload array is passed to Laravel as named constructor parameters.
Example:
namespace App\Events; class OpenScanner { public function __construct( public string $source, public string $redirectTo = '/scanner', ) {} }
Icon mapping
The package accepts a shared icon vocabulary and maps it to SF Symbols on iOS and framework drawables on Android.
icon() value |
iOS | Android |
|---|---|---|
photo, image, images, gallery, picture |
photo |
ic_menu_gallery |
camera, photo.camera |
camera |
ic_menu_camera |
search, find, magnifyingglass |
magnifyingglass |
ic_menu_search |
share, action, export |
square.and.arrow.up |
ic_menu_share |
settings, gear, preferences |
gearshape |
ic_menu_preferences |
home |
house |
ic_menu_compass |
star, favorite |
star |
star_big_on |
bell, notification |
bell |
fallback |
Unknown iOS icons are attempted as raw SF Symbols before falling back. Unknown Android icons log a warning and fall back to ic_menu_gallery.
Platform notes
- iOS shows at most four dynamic quick actions.
- iOS only indexes items into Spotlight / App Shortcuts when they belong to the shortcuts surface.
- Spotlight entries use the item title plus app-name keywords so searching for the app can surface opted-in actions more reliably.
- The package persists shortcut payloads in
storage/app/zinxan/quick-actions.json. - Action dispatch payloads are mirrored to
storage/app/zinxan/quick-actions-dispatch.jsonso they still work when cache is empty or split across workers. - The iOS post-compile hook patches generated
AppDelegate.swiftandContentView.swiftto support cold-start and scene-based shortcut handling. - Only one plugin should own iOS scene shortcut wiring in
application(_:configurationForConnecting:options:).
If you regenerate native iOS sources and shortcut handling stops working, rerun:
php artisan nativephp:quick-actions:post-compile \ --platform=ios \ --build-path=/absolute/path/to/nativephp/ios \ --no-interaction
Validation and testing
Recommended release checks:
php artisan native:plugin:validate
php artisan test --compact
php artisan native:install --no-interaction
For this package itself:
cd plugins/quick-actions composer dump-autoload composer test
Boost guidelines
The package includes Boost guidance in resources/boost/guidelines/core.blade.php so AI tooling can discover the supported PHP and JavaScript patterns.
Local development
When developing this package locally in a NativePHP app, add it as a path repository:
{
"repositories": [
{
"type": "path",
"url": "plugins/quick-actions",
"options": {
"symlink": true
}
}
],
"require": {
"zinxan/quick-actions": "@dev"
}
}
With "symlink": false, refresh the mirrored vendor copy after edits:
rm -rf vendor/zinxan/quick-actions && composer install
License
MIT