Home Screen Shortcuts Plugin for NativePHP Mobile#
Home Screen long-press shortcuts for NativePHP Mobile: register iOS UIApplicationShortcutItem / Android App Shortcuts that deep-link into a named route.
Overview#
Long-press the launcher icon and most apps show 2–4 shortcuts. This plugin is one facade: pass up to four { id, title, route|path } items and it registers them with the OS.
Without the plugin, the same feature requires app-specific ShortcutManagerCompat Kotlin and UIApplicationShortcutItem Swift. Your application supplies shortcut definitions; the plugin owns the platform registration.
A tap is a normal deep link through NATIVEPHP_DEEPLINK_SCHEME. NativePHP's own router opens the screen. The plugin does not dispatch a tap event.
How a tap gets into your app:
- Android (warm and cold): the shortcut launches
HomeScreenShortcutsTrampolineActivity, which forwardsACTION_VIEWto the launcher activity withCLEAR_TOP | SINGLE_TOP. That avoidsNEW_TASK | CLEAR_TASKtearing down a runningMainActivity(which can let a stale route win). - iOS, warm resume:
application(_:performActionFor:completionHandler:)forwards the stored URL intoDeepLinkRouter. - iOS, cold start (force-quit): not covered. iOS delivers
.shortcutItemtodidFinishLaunchingWithOptions. NativePHP'sAppDelegatealready implements that method and only checks.url/.userActivityDictionary. A Swift extension cannot override it. Closing the gap needs an upstream change innativephp/mobile.
Installation#
composer require partek/home-screen-shortcuts
Don't forget to register the plugin:
php artisan native:plugin:register partek/home-screen-shortcuts
Set NATIVEPHP_DEEPLINK_SCHEME in .env. Shortcuts will not open a screen without it, and HomeScreenShortcuts::set() throws if the scheme is missing.
Rebuild after you add or change shortcuts (php artisan native:run android / ios). Composer install alone does not update the launcher.
Usage#
PHP (Super Native / Livewire / Blade)#
The facade is for Super Native first — and the same call works from Livewire or Blade.
Where to call this: call HomeScreenShortcuts::set() once at app boot in a service provider (NativeServiceProvider::boot or AppServiceProvider::boot). Call clear() on logout from wherever you handle logout. Do not put set() inside a one-off screen component.
// app/Providers/NativeServiceProvider.php (or AppServiceProvider) use PARTek\HomeScreenShortcuts\Facades\HomeScreenShortcuts; public function boot(): void{ HomeScreenShortcuts::set([ ['id' => 'today', 'title' => "Today's Walk", 'route' => 'walk.today'], ['id' => 'talk', 'title' => 'Ask Pauly', 'subtitle' => "Open Let's Talk", 'route' => 'talk'], ['id' => 'new-post', 'title' => 'New Post', 'path' => '/posts/create'], ]);}
On logout (wherever you already sign the user out):
HomeScreenShortcuts::clear();
Each action needs id and title, plus exactly one of:
route— named route, optionalparams, resolved withroute($name, $params, absolute: false)path— raw relative path, used as-is
subtitle is optional (iOS shows it; Android may ignore it). More than four actions: extras are dropped.
JavaScript (Vue/React/Inertia)#
import { set, clear } from '../../vendor/partek/home-screen-shortcuts/resources/js'; // JS talks to the same HomeScreenShortcuts.Set / Clear bridges.// PHP is what resolves route/path into a NATIVEPHP_DEEPLINK_SCHEME URL;// from JS pass that already-built url on each action.await set([ { id: 'today', title: "Today's Walk", url: 'myapp://walk/today' }, { id: 'talk', title: 'Ask Pauly', subtitle: "Open Let's Talk", url: 'myapp://talk' }, { id: 'new-post', title: 'New Post', url: 'myapp://posts/create' },]); await clear();
Lowercase set / clear are the primary JavaScript API. Set / Clear aliases are also exported for existing code that mirrors the native bridge names. set and Set accept either an actions array or { actions: [...] }.
Events#
This plugin dispatches no events. There is no ShortcutTapped (or any other plugin event) to listen for.
A shortcut tap is a deep link. The native side stores NATIVEPHP_DEEPLINK_SCHEME://… on the shortcut; NativePHP's own router opens that path — the same mechanism as any other link on your scheme. Handle the destination as a normal Laravel route.
Methods#
set(array $actions)#
Replace all dynamic shortcuts. Returns bool.
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | yes | Stable id for the OS |
title |
string | yes | Launcher label |
route |
string | one of route/path | Named Laravel route |
params |
array | no | Route parameters |
path |
string | one of route/path | Relative path |
subtitle |
string | no | iOS subtitle |
The PHP facade resolves route/path into { id, title, subtitle, url } before calling HomeScreenShortcuts.Set. Extra actions beyond 4 are dropped.
clear()#
Remove all dynamic shortcuts. Returns bool. Calls HomeScreenShortcuts.Clear.
Platform Behavior#
Android#
ShortcutManagerCompat; no-op below API 25- Default icon = app launcher icon
- Min SDK 24
- No extra permissions
- Trampoline activity is the warm and cold tap path (see Overview)
iOS#
UIApplicationShortcutItem- Min iOS 14.0
- No extra permissions
- Warm resume works via the AppDelegate extension; cold start / force-quit does not (see Overview)
Testing#
vendor/bin/phpunit
Notes#
- Requires
NATIVEPHP_DEEPLINK_SCHEME. - Changed shortcut lists need a native rebuild.
- This is not
nativephp/mobile-shareand not a notification plugin. - No additional Android or iOS permissions.
License#
Proprietary commercial software. See LICENSE.