blessedzulu / nativephp-deeplinks
Deep-link hardening for NativePHP Mobile: scope Android App Links to specific path prefixes and preserve array query params (Livewire #[Url]) through the WebView bridge. Build-time only, no native SDK.
Package info
github.com/blessedzulu/nativephp-deeplinks
Type:nativephp-plugin
pkg:composer/blessedzulu/nativephp-deeplinks
Requires
- php: ^8.2
- illuminate/support: ^11.0|^12.0|^13.0
- nativephp/mobile: ^3.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0
README
Deep-link hardening for NativePHP Mobile. Two build-time fixes, no native SDK, no runtime cost:
-
Scope Android App Links to specific paths. NativePHP generates the Android App Link intent-filter with a single
android:pathPrefix="/", so the installed app claims every path on your verified host - marketing pages, blog posts, anything. This plugin rewrites the generatedAndroidManifest.xmlto emit one<data>entry per configured path prefix. Everything else opens in the browser, as it should. -
Preserve array query params through the WebView bridge. NativePHP's Android
WebViewClientrebuilds each request's query string from Android'sUriparser - which mishandles bracketed keys likefoo[0][bar]- and re-serialises it without re-encoding. That silently corrupts array query parameters. The most common casualty is Livewire#[Url] public arrayproperties (e.g. add-a-row inputs), which serialise asallowances[0][type]=fixed: scalar params survive a deep link but array rows arrive empty, so the page loads with the wrong state. This plugin patches the generated Kotlin so the original percent-encoded query reaches PHP verbatim - exactly what a browser sends.
iOS needs neither fix: scoping is handled by your server-hosted apple-app-site-association paths array, and Swift's URL.query already preserves percent-encoding.
Install
composer require blessedzulu/nativephp-deeplinks php artisan vendor:publish --tag=nativephp-deeplinks-config
The plugin is auto-discovered by NativePHP (php artisan native:plugin:list to confirm). Its work runs automatically on native:run / native:package via a post_compile hook.
Configure
config/nativephp-deeplinks.php:
return [ // Path prefixes the Android app should claim. Glob ('/calculators/*') or // bare prefix ('/calculators') both work. Empty = NativePHP default (whole host). 'paths' => ['/calculators', '/tools', '/planners'], // Pass the original encoded query to PHP verbatim. Leave true. 'preserve_array_query' => true, ];
Or via env: NATIVEPHP_DEEPLINK_PATHS=/calculators,/tools,/planners.
You still need NativePHP's own NATIVEPHP_DEEPLINK_HOST set and your server-hosted assetlinks.json / apple-app-site-association for verification - this plugin only fixes scoping and query handling.
How it works
A post_compile hook runs after NativePHP generates the native project and before Gradle builds it, operating on the generated Android source tree. Every transform is idempotent (safe to re-run) and guarded: if an upstream anchor it expects has moved, it logs a warning and skips rather than failing the build - so a NativePHP upgrade degrades to "unpatched" loudly instead of breaking silently.
Compatibility
NativePHP Mobile ^3.0 (developed against 3.3.x). If upstream fixes these issues (the uri.query decode is a genuine bug - see [the encodedQuery discussion]), this plugin becomes a no-op and can be removed.
License
MIT © Blessed Zulu