From 25abddb147dd60a060f523db9a857f4844d324e1 Mon Sep 17 00:00:00 2001 From: Wessel Verheij Date: Sat, 5 Sep 2026 02:41:47 +0200 Subject: [PATCH 1/6] docs(mobile,desktop): fix config defaults, command options, and version requirements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corrects several places where docs had drifted from the actual package source (verified against nativephp/mobile-air and nativephp/desktop): - open_browser's real default is false, not true (mobile config + native:jump guide) — the terminal already renders a scannable QR code. - status_bar_style isn't env()-wrapped in the real config; the docs implied an override env var that doesn't exist. - Environment setup listed PHP 8.3+/Laravel 11+; composer.json requires PHP 8.4+ and supports Laravel 10+. - native:install's option table had the --force/--fresh/--without-icu semantics backwards or fabricated: overwriting is actually the default, --no-force opts out, --without-icu doesn't exist, and --force actually means "re-download PHP binaries", not "overwrite". - native:run/native:jump were missing real options (--build=profileable, --browser). - Desktop's "Default Configuration File" reference had drifted significantly from the real config/nativephp.php: missing Azure Trusted Signing / Bifrost cleanup_env_keys entries, a completely different cleanup_exclude_files list, missing updater provider keys (autoupdate_token, public_url), and four undocumented top-level sections (queue_workers, prebuild/postbuild, nsis, binary_path). Co-Authored-By: Claude Sonnet 5 --- .../2/getting-started/configuration.md | 65 ++++++++++++++++++- .../docs/mobile/4/getting-started/commands.md | 14 ++-- .../mobile/4/getting-started/configuration.md | 8 +-- .../4/getting-started/environment-setup.md | 4 +- .../views/docs/mobile/4/the-basics/jump.md | 2 +- 5 files changed, 77 insertions(+), 16 deletions(-) diff --git a/resources/views/docs/desktop/2/getting-started/configuration.md b/resources/views/docs/desktop/2/getting-started/configuration.md index 625940bbe..4980bea0e 100644 --- a/resources/views/docs/desktop/2/getting-started/configuration.md +++ b/resources/views/docs/desktop/2/getting-started/configuration.md @@ -22,7 +22,7 @@ return [ * usually in the form of a reverse domain name. * For example: com.nativephp.app */ - 'app_id' => env('NATIVEPHP_APP_ID'), + 'app_id' => env('NATIVEPHP_APP_ID', 'com.nativephp.app'), /** * If your application allows deep linking, you can specify the scheme @@ -69,13 +69,19 @@ return [ */ 'cleanup_env_keys' => [ 'AWS_*', + 'AZURE_*', 'GITHUB_*', 'DO_SPACES_*', '*_SECRET', + 'BIFROST_*', 'NATIVEPHP_UPDATER_PATH', 'NATIVEPHP_APPLE_ID', 'NATIVEPHP_APPLE_ID_PASS', 'NATIVEPHP_APPLE_TEAM_ID', + 'NATIVEPHP_AZURE_PUBLISHER_NAME', + 'NATIVEPHP_AZURE_ENDPOINT', + 'NATIVEPHP_AZURE_CERTIFICATE_PROFILE_NAME', + 'NATIVEPHP_AZURE_CODE_SIGNING_ACCOUNT_NAME', ], /** @@ -84,9 +90,11 @@ return [ * You may use glob / wildcard patterns here. */ 'cleanup_exclude_files' => [ + 'build', + 'temp', 'content', - 'storage/app/framework/{sessions,testing,cache}', - 'storage/logs/laravel.log', + 'node_modules', + '*/tests', ], /** @@ -103,6 +111,7 @@ return [ /** * The updater provider to use. * Supported: "github", "s3", "spaces" + * Note: The "s3" provider is compatible with S3-compatible services like Cloudflare R2. */ 'default' => env('NATIVEPHP_UPDATER_PROVIDER', 'spaces'), @@ -114,6 +123,7 @@ return [ 'token' => env('GITHUB_TOKEN'), 'vPrefixedTagName' => env('GITHUB_V_PREFIXED_TAG_NAME', true), 'private' => env('GITHUB_PRIVATE', false), + 'autoupdate_token' => env('GITHUB_AUTOUPDATE_TOKEN'), // Read-only token used by the updater for private repos 'channel' => env('GITHUB_CHANNEL', 'latest'), 'releaseType' => env('GITHUB_RELEASE_TYPE', 'draft'), ], @@ -126,6 +136,13 @@ return [ 'bucket' => env('AWS_BUCKET'), 'endpoint' => env('AWS_ENDPOINT'), 'path' => env('NATIVEPHP_UPDATER_PATH', null), + /** + * Optional public URL for serving updates (e.g., CDN or custom domain). + * When set, updates will be downloaded from this URL instead of the S3 endpoint. + * Useful for S3 with CloudFront or Cloudflare R2 with public access + * Example: 'https://updates.yourdomain.com' + */ + 'public_url' => env('AWS_PUBLIC_URL'), ], 'spaces' => [ @@ -138,9 +155,51 @@ return [ ], ], ], + + /** + * The queue workers that get auto-started on your application start. + */ + 'queue_workers' => [ + 'default' => [ + 'queues' => ['default'], + 'memory_limit' => 128, + 'timeout' => 60, + 'sleep' => 3, + ], + ], + + /** + * Define your own scripts to run before and after the build process. + */ + 'prebuild' => [ + // 'npm run build', + ], + + 'postbuild' => [ + // 'rm -rf public/build', + ], + + /** + * The NSIS installer configuration for Windows builds. + * + * @see https://www.electron.build/generated/nsisoptions + */ + 'nsis' => [ + 'delete_app_data_on_uninstall' => env('NATIVEPHP_NSIS_DELETE_APP_DATA', false), + ], + + /** + * Custom PHP binary path. + */ + 'binary_path' => env('NATIVEPHP_PHP_BINARY_PATH', null), ]; ``` +- `queue_workers` — named queue-worker pools that start automatically alongside your app, each with its own queues, memory limit, timeout, and sleep interval — handy if part of your app's work needs to run on a queue other than `default`. +- `prebuild` / `postbuild` — shell commands run immediately before and after the build step (e.g. `npm run build` to compile assets first, or cleanup afterward). +- `nsis` — options passed to the [NSIS installer](https://www.electron.build/generated/nsisoptions) electron-builder generates for Windows. +- `binary_path` — overrides the PHP binary NativePHP bundles with your own, when set. + ## Customize php.ini When your NativePHP application starts, you may want to customize php.ini directives that will be used for your application. diff --git a/resources/views/docs/mobile/4/getting-started/commands.md b/resources/views/docs/mobile/4/getting-started/commands.md index f3c32f055..3e1b6d77b 100644 --- a/resources/views/docs/mobile/4/getting-started/commands.md +++ b/resources/views/docs/mobile/4/getting-started/commands.md @@ -18,11 +18,10 @@ php artisan native:install {platform?} | Option | Description | |--------|-------------| | `platform` | Target platform: `android`, `ios`, or `both` | -| `--force` | Overwrite existing files | -| `--fresh` | Alias for `--force` | +| `--no-force` | Keep existing files instead of overwriting them (overwriting is the default) | | `--with-icu` | Include ICU support for Android (adds ~30MB) | -| `--without-icu` | Exclude ICU support for Android | -| `--skip-php` | Do not download PHP binaries | +| `--skip-php` | Do not download the PHP binaries | +| `-F`, `--force` | Force re-download of the PHP binaries by clearing the cache | ### native:run @@ -36,7 +35,7 @@ php artisan native:run {os?} {udid?} |--------|---------------------------------------------------| | `os` | Target platform: `ios/i` or `android/a` | | `udid` | Specific device/simulator UDID | -| `--build=debug` | Build type: `debug`, `release`, or `bundle` | +| `--build=debug` | Build type: `debug`, `release`, `bundle`, or `profileable` | | `--watch` | Enable hot reloading during development | | `--vite` | Start the Vite dev server for JS/CSS HMR (opt-in; off by default) | | `--start-url=` | Initial URL/path to load (e.g., `/dashboard`) | @@ -90,6 +89,7 @@ php artisan native:jump | `--no-serve` v3.3+ | Do not start `artisan serve` automatically (use if running your own server) | | `--laravel-port=` | Laravel dev server port (defaults to `8000`; auto-detected when `artisan serve` is managed) | | `--no-mdns` | Disable mDNS service advertisement | +| `--browser` | Open the QR code page in the default browser (useful when terminal rendering is unreliable) | ### native:open @@ -229,9 +229,11 @@ php artisan native:package {platform} | Option | Description | |--------|---------------------------------------------------| | `platform` | Target platform: `android/a` or `ios/i` | +| `--ios` | Target iOS platform (shorthand for `platform=ios`) | +| `--android` | Target Android platform (shorthand for `platform=android`) | | `--build-type=release` | Build type: `release` or `bundle` | | `--output=` | Output directory for signed artifacts | -| `--jump-by=` | Skip ahead in version numbering | +| `--jump-by=` | Add extra number to the suggested version, e.g. `--jump-by=10` to skip ahead | | `--no-tty` | Disable TTY mode for non-interactive environments | **Android Options:** diff --git a/resources/views/docs/mobile/4/getting-started/configuration.md b/resources/views/docs/mobile/4/getting-started/configuration.md index 9b9a8d452..264248c67 100644 --- a/resources/views/docs/mobile/4/getting-started/configuration.md +++ b/resources/views/docs/mobile/4/getting-started/configuration.md @@ -252,11 +252,11 @@ Control the color of the status bar and navigation bar icons: ```php 'android' => [ - 'status_bar_style' => env('NATIVEPHP_ANDROID_STATUS_BAR_STYLE', 'auto'), + 'status_bar_style' => 'auto', ], ``` -Options: `auto` (detect from system theme), `light` (white icons), or `dark` (dark icons). +Options: `auto` (detect from system theme), `light` (white icons), or `dark` (dark icons). This isn't wrapped in an `env()` call — change the value directly in the published config to override it. ## Development Server @@ -267,14 +267,14 @@ Configure the development server used by `native:jump` and `native:watch`: 'http_port' => env('NATIVEPHP_HTTP_PORT', 3000), 'ws_port' => env('NATIVEPHP_WS_PORT', 8081), 'service_name' => env('NATIVEPHP_SERVICE_NAME', 'NativePHP Server'), - 'open_browser' => env('NATIVEPHP_OPEN_BROWSER', true), + 'open_browser' => env('NATIVEPHP_OPEN_BROWSER', false), ], ``` - `http_port` — The port for serving your app during development. (default: `3000`) - `ws_port` — The WebSocket port for hot reload communication. (default: `8081`) - `service_name` — The mDNS service name advertised on your network. (default: `NativePHP Server`) -- `open_browser` — Automatically open a browser with a QR code when the server starts. (default: `true`) +- `open_browser` — Automatically open a browser with a QR code when the server starts. (default: `false` — the terminal already renders a scannable QR code; pass `--browser` to `native:jump`, or set `NATIVEPHP_OPEN_BROWSER=true`, to opt in) ## Hot Reload diff --git a/resources/views/docs/mobile/4/getting-started/environment-setup.md b/resources/views/docs/mobile/4/getting-started/environment-setup.md index a196c6c10..2f3b043e8 100644 --- a/resources/views/docs/mobile/4/getting-started/environment-setup.md +++ b/resources/views/docs/mobile/4/getting-started/environment-setup.md @@ -5,8 +5,8 @@ order: 100 ## Requirements -1. PHP 8.3+ -2. Laravel 11+ +1. PHP 8.4+ +2. Laravel 10+ If you don't already have PHP installed on your machine, the most painless way to get PHP up and running on Mac and Windows is with [Laravel Herd](https://herd.laravel.com). It's fast and free! diff --git a/resources/views/docs/mobile/4/the-basics/jump.md b/resources/views/docs/mobile/4/the-basics/jump.md index a067acdf0..a24d9ddbb 100644 --- a/resources/views/docs/mobile/4/the-basics/jump.md +++ b/resources/views/docs/mobile/4/the-basics/jump.md @@ -106,7 +106,7 @@ The dev server is configured under the `server` key in your `config/nativephp.ph 'http_port' => env('NATIVEPHP_HTTP_PORT', 3000), 'ws_port' => env('NATIVEPHP_WS_PORT', 8081), 'service_name' => env('NATIVEPHP_SERVICE_NAME', 'NativePHP Server'), - 'open_browser' => env('NATIVEPHP_OPEN_BROWSER', true), + 'open_browser' => env('NATIVEPHP_OPEN_BROWSER', false), ], ``` From 457bc8f4b5709e6b6b5aac0bed8b27903ace5075 Mon Sep 17 00:00:00 2001 From: Wessel Verheij Date: Sat, 5 Sep 2026 02:56:00 +0200 Subject: [PATCH 2/6] docs(mobile,desktop): document previously undocumented features Adds coverage for real, shipped features found with no docs home, verified against nativephp/mobile-air and nativephp/desktop source: - Mobile: MobileWallet facade (Apple Pay/Google Pay via Stripe) and its three payment events, a Motion page for the shake-detection event, an UpdateInstalled note on the versioning page, and a Bifrost overview page (mobile build support is live; desktop's is marked "coming soon" on Bifrost's own site, so it's mobile-only for now). - Desktop: a Nightwatch integration page (auto-wired when both the package and NIGHTWATCH_TOKEN are present), the missing AutoUpdater::downloadUpdate() method and UpdateCancelled event, a handful of Window/MenuBar/System methods that existed in the facades but were never mentioned (Window::reload/unmaximize/position-by-id, MenuBar::icon/contextMenu/showOnAllWorkspaces, System::printFile), and a new Command Reference page mirroring mobile's. - Bumped config('docs.released_versions.mobile.4') to include the real 4.3.0/4.3.1 releases. Co-Authored-By: Claude Sonnet 5 --- config/docs.php | 2 +- .../desktop/2/digging-deeper/nightwatch.md | 35 ++++++ .../desktop/2/getting-started/commands.md | 117 ++++++++++++++++++ .../docs/desktop/2/publishing/updating.md | 26 ++++ .../docs/desktop/2/the-basics/menu-bar.md | 27 ++++ .../views/docs/desktop/2/the-basics/system.md | 9 ++ .../docs/desktop/2/the-basics/windows.md | 24 ++++ .../mobile/4/getting-started/versioning.md | 16 +++ .../docs/mobile/4/plugins/core/motion.md | 34 +++++ .../docs/mobile/4/plugins/core/wallet.md | 78 ++++++++++++ .../views/docs/mobile/4/publishing/bifrost.md | 38 ++++++ 11 files changed, 405 insertions(+), 1 deletion(-) create mode 100644 resources/views/docs/desktop/2/digging-deeper/nightwatch.md create mode 100644 resources/views/docs/desktop/2/getting-started/commands.md create mode 100644 resources/views/docs/mobile/4/plugins/core/motion.md create mode 100644 resources/views/docs/mobile/4/plugins/core/wallet.md create mode 100644 resources/views/docs/mobile/4/publishing/bifrost.md diff --git a/config/docs.php b/config/docs.php index 92c545a15..83ff60cb6 100644 --- a/config/docs.php +++ b/config/docs.php @@ -59,7 +59,7 @@ 1 => ['1.0', '1.1'], 2 => ['2.0'], 3 => ['3.0', '3.1', '3.2', '3.3'], - 4 => ['4.0', '4.1', '4.2'], + 4 => ['4.0', '4.1', '4.2', '4.3'], ], ], diff --git a/resources/views/docs/desktop/2/digging-deeper/nightwatch.md b/resources/views/docs/desktop/2/digging-deeper/nightwatch.md new file mode 100644 index 000000000..c91e99ef8 --- /dev/null +++ b/resources/views/docs/desktop/2/digging-deeper/nightwatch.md @@ -0,0 +1,35 @@ +--- +title: Nightwatch +order: 800 +--- + +[Laravel Nightwatch](https://nightwatch.laravel.com) is a first-party observability product for Laravel applications +— requests, queries, queue jobs, exceptions, and more. NativePHP wires it up automatically for your packaged desktop +app when it detects Nightwatch is installed. + +## Enabling it + +Install Nightwatch in your app as you would for any Laravel project, and set your `NIGHTWATCH_TOKEN`: + +```dotenv +NIGHTWATCH_TOKEN=your-token +``` + +When your app is packaged and launched, NativePHP checks for both `laravel/nightwatch` in your dependencies and a +`NIGHTWATCH_TOKEN`. If both are present, it starts a local Nightwatch ingest agent (`php artisan nightwatch:agent`) +alongside your bundled PHP process and wires it up automatically — there's nothing else to configure. + +If a token is set but Nightwatch isn't installed, NativePHP skips starting the agent rather than failing. + + + +## Internal routes are excluded + +NativePHP's own internal bridge routes (`_native/api/*`, used for communication between your PHP app and the native +shell) are sampled at 0% when Nightwatch is installed, so this internal plumbing never shows up in your Nightwatch +dashboard alongside your actual application traffic. diff --git a/resources/views/docs/desktop/2/getting-started/commands.md b/resources/views/docs/desktop/2/getting-started/commands.md new file mode 100644 index 000000000..8bf8b6a6a --- /dev/null +++ b/resources/views/docs/desktop/2/getting-started/commands.md @@ -0,0 +1,117 @@ +--- +title: Command Reference +order: 375 +--- + +A complete reference of the `native:*` Artisan commands available in NativePHP Desktop. + +## Development Commands + +### native:install + +Install NativePHP into your Laravel application. + +```shell +php artisan native:install +``` + +| Option | Description | +|--------|-------------| +| `--force` | Overwrite existing files by default | +| `--publish` | Publish the Electron project to your project's root | +| `--installer=npm` | The package installer to use: `npm` or `yarn` | + +### native:run + +Start the NativePHP development server, which builds and runs your Electron app locally. + +```shell +php artisan native:run +``` + +| Option | Description | +|--------|-------------| +| `--no-queue` | Don't start a queue worker alongside the app | +| `--no-focus` | Don't focus the app window on launch | +| `-D`, `--no-dependencies` | Skip installing npm dependencies | +| `--installer=npm` | The package installer to use: `npm` or `yarn` | + + + +### native:debug + +Generate debug information to include when opening an issue. + +```shell +php artisan native:debug {output} +``` + +| Option | Description | +|--------|-------------| +| `output` | Where to send the debug output: `File`, `Clipboard`, or `Console` | + +### native:reset + +Clear all build and dist files, useful when you want a clean slate before rebuilding. + +```shell +php artisan native:reset +``` + +| Option | Description | +|--------|-------------| +| `--with-app-data` | Also clear the app's stored data | + +## Database Commands + +These mirror Laravel's own `migrate`/`db:seed`/`db:wipe` commands, scoped to the database used by your NativePHP +development environment. + +| Command | Description | +|---------|-------------| +| `native:migrate` | Run the database migrations | +| `native:migrate:fresh` | Drop all tables and re-run every migration | +| `native:seed` | Seed the database — accepts the same `--class=` option as `db:seed` | +| `native:db:wipe` | Wipe the database | + +## Building & Release Commands + +### native:build + +Build the NativePHP application for a specific operating system and architecture. + +```shell +php artisan native:build {os?} {arch?} +``` + +| Option | Description | +|--------|-------------| +| `os` | Operating system to build for: `all`, `linux`, `mac`, or `win` | +| `arch` | Processor architecture to build for: `x64` or `arm64` | +| `--publish` | Publish the app after building | + +### native:publish + +Build and publish the NativePHP app for a specific operating system and architecture. This is equivalent to running +`native:build` with `--publish`. + +```shell +php artisan native:publish {os?} {arch?} +``` + +| Option | Description | +|--------|-------------| +| `os` | Operating system to build for: `all`, `linux`, `mac`, or `win` | +| `arch` | Processor architecture to build for: `x64` or `arm64` | + + diff --git a/resources/views/docs/desktop/2/publishing/updating.md b/resources/views/docs/desktop/2/publishing/updating.md index 66795ec3a..8430bb579 100644 --- a/resources/views/docs/desktop/2/publishing/updating.md +++ b/resources/views/docs/desktop/2/publishing/updating.md @@ -108,6 +108,17 @@ AutoUpdater::checkForUpdates(); **Note:** If an update is available, it will be downloaded automatically. Calling `AutoUpdater::checkForUpdates() twice will download the update two times. +## Manually downloading an update + +An update found by `checkForUpdates()` downloads automatically, so you won't usually need this — but if a download +was cancelled (see the `UpdateCancelled` event below) or otherwise didn't complete, `downloadUpdate()` re-triggers it: + +```php +use Native\Desktop\Facades\AutoUpdater; + +AutoUpdater::downloadUpdate(); +``` + ## Quit and Install You can quit the application and install the update by calling the `quitAndInstall` method on the `AutoUpdater` facade: @@ -163,6 +174,21 @@ The event contains the following properties: - `releaseNotes`: The release notes of the update. - `releaseName`: The name of the update. +### `UpdateCancelled` + +The `Native\Desktop\Events\AutoUpdater\UpdateCancelled` event is dispatched when an in-progress download is +cancelled before it finishes. + +The event contains the following properties: + +- `version`: The version of the update that was being downloaded. +- `files`: The release's file manifest. +- `releaseDate`: The release date of the update in ISO 8601 format. +- `releaseName`: The name of the update. +- `releaseNotes`: The release notes of the update. +- `stagingPercentage`: The staged-rollout percentage this release is limited to, if any. +- `minimumSystemVersion`: The minimum OS version the update requires, if any. + ### `Error` The `Native\Desktop\Events\AutoUpdater\Error` event is dispatched when there is an error while updating. diff --git a/resources/views/docs/desktop/2/the-basics/menu-bar.md b/resources/views/docs/desktop/2/the-basics/menu-bar.md index 98a0d01fb..18e98613a 100644 --- a/resources/views/docs/desktop/2/the-basics/menu-bar.md +++ b/resources/views/docs/desktop/2/the-basics/menu-bar.md @@ -165,6 +165,13 @@ MenuBar::create() ->icon(storage_path('app/menuBarIconTemplate.png')); ``` +Like `label()` and `tooltip()`, the icon can also be changed after creation by calling `icon()` directly on the +`MenuBar` facade: + +```php +MenuBar::icon(storage_path('app/menuBarIconAlert.png')); +``` + ### Vibrancy and Background Color For macOS, you may use the `vibrancy` method to apply window vibrancy effects: @@ -222,6 +229,14 @@ MenuBar::create() ->alwaysOnTop(); ``` +Similarly, `showOnAllWorkspaces()` keeps the menu bar window visible across every virtual desktop/Space (macOS) rather +than just the one it was opened on. + +```php +MenuBar::create() + ->showOnAllWorkspaces(); +``` + ## Menu Bar Context Menu You may add a context menu to your menu bar icon. This context menu will be shown when the user right-clicks on the menu bar icon. @@ -252,6 +267,18 @@ MenuBar::create() To learn more about the `Menu` facade, please refer to the [Application Menu](/docs/the-basics/application-menu) documentation. +You may also set or replace the context menu after the menu bar has already been created by calling `contextMenu()` +directly on the `MenuBar` facade: + +```php +MenuBar::contextMenu( + Menu::make( + Menu::label('Updated'), + Menu::quit() + ) +); +``` + ### Opening a Context Menu You can programmatically display the context menu that has been configured for your Menu Bar app using the `showContextMenu()` method. This method will show the same context menu that appears when a user clicks on the Menu Bar app. diff --git a/resources/views/docs/desktop/2/the-basics/system.md b/resources/views/docs/desktop/2/the-basics/system.md index dd6e5e219..67d194e6d 100644 --- a/resources/views/docs/desktop/2/the-basics/system.md +++ b/resources/views/docs/desktop/2/the-basics/system.md @@ -108,6 +108,15 @@ System::print('...', $printer); If no `$printer` object is provided, the default printer and settings will be used. +To print an existing file — a PDF, for example — instead of an HTML string, use `printFile()`: + +```php +System::printFile('/path/to/file.pdf', $printer); +``` + +It returns `true` once the file has been sent to the printer, and accepts the same `$printer` and `$settings` +arguments as `print()`. + You can also print directly to PDF: ```php diff --git a/resources/views/docs/desktop/2/the-basics/windows.md b/resources/views/docs/desktop/2/the-basics/windows.md index 05ffc03a8..f49132cb1 100644 --- a/resources/views/docs/desktop/2/the-basics/windows.md +++ b/resources/views/docs/desktop/2/the-basics/windows.md @@ -106,6 +106,22 @@ Window::open() ->maximized(); ``` +To reverse a maximize, use `Window::unmaximize()`. It accepts the same optional window ID as `maximize()`. + +```php +Window::unmaximize('secondary'); +``` + +#### Reloading a Window + +To reload a window's content, you may use the `Window::reload()` method. It accepts the same optional window ID as +`resize()` and `close()`. + +```php +Window::reload(); +Window::reload('settings'); +``` + ### Changing the URL While the URL in a window will change based on user activity, your Laravel routes and the flow of your application, @@ -242,6 +258,14 @@ Window::open() ->position(100, 100); ``` +You can also move an already-open window with `Window::position($x, $y, $animated, $id)` — pass `true` for `$animated` +to smoothly move the window into place, and a window ID if you're not repositioning the window matching the current +route. + +```php +Window::position(200, 200, animated: true, id: 'settings'); +``` + ### Remembering Window State The users of your application may resize or move the window and expect it to be in the same position and size the next diff --git a/resources/views/docs/mobile/4/getting-started/versioning.md b/resources/views/docs/mobile/4/getting-started/versioning.md index 7c4cea919..1291fe079 100644 --- a/resources/views/docs/mobile/4/getting-started/versioning.md +++ b/resources/views/docs/mobile/4/getting-started/versioning.md @@ -57,6 +57,22 @@ with a full minimum patch release defined in your `composer.json`: This automatically receives patch updates while giving you control over minor releases. +## Detecting an app update + +When a user's app store update finishes installing, NativePHP dispatches `Native\Mobile\Events\App\UpdateInstalled` +with the new `version` and a `timestamp`. Listen for it to show a "what's new" screen or re-sync anything that +depends on the app version: + +```php +use Native\Mobile\Events\App\UpdateInstalled; + +#[On(UpdateInstalled::class)] +public function onUpdateInstalled(string $version, int $timestamp): void +{ + $this->showWhatsNew = true; +} +``` + ## Version labels Anything documented in this version of the docs has been here since 4.0 unless it carries a label. Labels appear next diff --git a/resources/views/docs/mobile/4/plugins/core/motion.md b/resources/views/docs/mobile/4/plugins/core/motion.md new file mode 100644 index 000000000..73a097768 --- /dev/null +++ b/resources/views/docs/mobile/4/plugins/core/motion.md @@ -0,0 +1,34 @@ +--- +title: Motion +order: 950 +--- + +## Shake Detection + +NativePHP detects when the user shakes their device — `motionEnded(.motionShake)` on iOS, the accelerometer on +Android — and delivers it as a [native event](../../the-basics/events), with no facade or setup required. + +Listen for it with `#[On]`: + +```php +use Native\Mobile\Events\Motion\ShakeDetected; + +class FeedbackScreen extends NativeComponent +{ + #[On(ShakeDetected::class)] + public function onShake(): void + { + $this->showFeedbackSheet = true; + } +} +``` + +A shake carries no reliable magnitude on iOS, so the event's payload is minimal — just an optional `id` correlation +token, unset unless a future emitter sets one. + + diff --git a/resources/views/docs/mobile/4/plugins/core/wallet.md b/resources/views/docs/mobile/4/plugins/core/wallet.md new file mode 100644 index 000000000..75b57ea0a --- /dev/null +++ b/resources/views/docs/mobile/4/plugins/core/wallet.md @@ -0,0 +1,78 @@ +--- +title: Mobile Wallet +order: 1350 +--- + +## Overview + +The `MobileWallet` facade lets your app accept payments through Apple Pay (iOS) and Google Pay (Android) using +[Stripe](https://stripe.com) under the hood. Your Laravel backend creates a payment intent, the device presents the +native payment sheet for the user to authorize with Face ID, Touch ID, or their device PIN, and your backend confirms +the result. + +```php +use Native\Mobile\Facades\MobileWallet; +``` + +## Checking availability + +Not every device supports Apple Pay or Google Pay. Check before showing a "Pay" button: + +```php +if (MobileWallet::isAvailable()) { + // Show the wallet payment option +} +``` + +## Taking a payment + +The flow has three steps: create a payment intent on your backend, present the native payment sheet, then confirm +the result. + +```php +$intent = MobileWallet::createPaymentIntent( + amount: 1999, // $19.99, in cents + currency: 'usd', + metadata: ['order_id' => $order->id], +); + +$result = MobileWallet::presentPaymentSheet( + clientSecret: $intent->client_secret, + merchantDisplayName: 'Acme Widgets', + publishableKey: config('services.stripe.key'), + merchantId: 'merchant.com.acme.widgets', // Your Apple Pay merchant ID +); + +$confirmation = MobileWallet::confirmPayment($intent->id); +``` + +- `createPaymentIntent()` — `$amount` is in the smallest currency unit (cents for USD), `$currency` is a lowercase + ISO code, and `$metadata` is attached to the Stripe payment intent for your own bookkeeping. +- `presentPaymentSheet()` — shows the native card/wallet picker. `$merchantId` is your registered Apple Pay merchant + identifier; `$merchantCountryCode` defaults to `US`. +- `confirmPayment($paymentIntentId)` — confirms the payment with whichever method the user selected. + +You can also poll the current status of a payment at any time: + +```php +$status = MobileWallet::getPaymentStatus($intent->id); +``` + + + +## Events + +Alongside the return values above, the payment sheet also dispatches [native events](../../the-basics/events) as the +user completes, cancels, or fails a payment — listen for these if a screen other than the one that started the +payment needs to react: + +- `Native\Mobile\Events\Wallet\PaymentCompleted` — `paymentIntentId`, `amount`, `currency`, `status`, `metadata`. +- `Native\Mobile\Events\Wallet\PaymentCancelled` — `paymentIntentId`, `reason`. +- `Native\Mobile\Events\Wallet\PaymentFailed` — `paymentIntentId`, `errorCode`, `errorMessage`, `metadata`. diff --git a/resources/views/docs/mobile/4/publishing/bifrost.md b/resources/views/docs/mobile/4/publishing/bifrost.md new file mode 100644 index 000000000..ff77c4e56 --- /dev/null +++ b/resources/views/docs/mobile/4/publishing/bifrost.md @@ -0,0 +1,38 @@ +--- +title: Bifrost +order: 15 +--- + +## Overview + +[Bifrost](https://bifrost.nativephp.com) is NativePHP's cloud build platform — sign in with GitHub, and a push, tag, +or release kicks off a signed iOS and Android build without you touching a keystore, provisioning profile, or CI +config. + +- **Managed signing** — paste one App Store Connect key and Bifrost creates and renews your certificates and + provisioning profiles for you. No CSR-on-a-Mac, no yearly renewal chores. +- **Build from a push** — a PR, push, tag, or release triggers a build; you get notified in Slack, Discord, or email + when it's done. +- **AI build diagnosis** — a failed build gets its log read automatically, with the root cause and a suggested fix, + free on every plan. +- **Monorepo-aware** — point Bifrost at the folder your app lives in; it works alongside a Laravel API or web app in + the same repository. +- **Workflows** — chain steps (build, notify, distribute) so a single trigger does everything you need. + +## Getting started + +Sign in to [Bifrost](https://bifrost.nativephp.com) with GitHub, attach a NativePHP license to your team, and pick +the folder your app lives in — Bifrost detects the app for you. From there, pushing to your configured branch (or +tagging a release) starts a build. + +## Documentation + +Bifrost has its own documentation covering Teams, Projects, Credentials, Builds, and Workflows in depth: + +[**Read the Bifrost docs →**](https://bifrost.nativephp.com/docs/mobile) + + From 7e9388c33d79d88f58ce69256605e80e8a10fe9a Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 20 Sep 2026 01:30:29 +0100 Subject: [PATCH 3/6] Remove Bifrost reference for now --- .../views/docs/desktop/2/getting-started/commands.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/resources/views/docs/desktop/2/getting-started/commands.md b/resources/views/docs/desktop/2/getting-started/commands.md index 8bf8b6a6a..3f433c3cc 100644 --- a/resources/views/docs/desktop/2/getting-started/commands.md +++ b/resources/views/docs/desktop/2/getting-started/commands.md @@ -107,11 +107,3 @@ php artisan native:publish {os?} {arch?} |--------|-------------| | `os` | Operating system to build for: `all`, `linux`, `mac`, or `win` | | `arch` | Processor architecture to build for: `x64` or `arm64` | - - From 0d0c6923c6e96781e8c0b5ada7e450bd1fd23cf8 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 20 Sep 2026 02:14:29 +0100 Subject: [PATCH 4/6] Drop the UpdateInstalled section from the mobile versioning docs Nothing dispatches Native\Mobile\Events\App\UpdateInstalled. The event class exists in mobile-air and the JS constant is exported, but no Swift or Kotlin code sends it, so a listener would never fire. The dispatch only exists in the older nativephp/mobile repo, where AppUpdateManager fires it after downloading an OTA zip. Even there it has nothing to do with an app store update finishing, which is what this section claimed. Dropping it until the event is wired up again. Co-Authored-By: Claude Opus 5 (1M context) --- .../docs/mobile/4/getting-started/versioning.md | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/resources/views/docs/mobile/4/getting-started/versioning.md b/resources/views/docs/mobile/4/getting-started/versioning.md index 1291fe079..7c4cea919 100644 --- a/resources/views/docs/mobile/4/getting-started/versioning.md +++ b/resources/views/docs/mobile/4/getting-started/versioning.md @@ -57,22 +57,6 @@ with a full minimum patch release defined in your `composer.json`: This automatically receives patch updates while giving you control over minor releases. -## Detecting an app update - -When a user's app store update finishes installing, NativePHP dispatches `Native\Mobile\Events\App\UpdateInstalled` -with the new `version` and a `timestamp`. Listen for it to show a "what's new" screen or re-sync anything that -depends on the app version: - -```php -use Native\Mobile\Events\App\UpdateInstalled; - -#[On(UpdateInstalled::class)] -public function onUpdateInstalled(string $version, int $timestamp): void -{ - $this->showWhatsNew = true; -} -``` - ## Version labels Anything documented in this version of the docs has been here since 4.0 unless it carries a label. Labels appear next From e25beecdeb80b9192e6912b4f349aedfe3e1df3d Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 20 Sep 2026 02:15:57 +0100 Subject: [PATCH 5/6] Delete Motion --- .../docs/mobile/4/plugins/core/motion.md | 34 ------------------- 1 file changed, 34 deletions(-) delete mode 100644 resources/views/docs/mobile/4/plugins/core/motion.md diff --git a/resources/views/docs/mobile/4/plugins/core/motion.md b/resources/views/docs/mobile/4/plugins/core/motion.md deleted file mode 100644 index 73a097768..000000000 --- a/resources/views/docs/mobile/4/plugins/core/motion.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Motion -order: 950 ---- - -## Shake Detection - -NativePHP detects when the user shakes their device — `motionEnded(.motionShake)` on iOS, the accelerometer on -Android — and delivers it as a [native event](../../the-basics/events), with no facade or setup required. - -Listen for it with `#[On]`: - -```php -use Native\Mobile\Events\Motion\ShakeDetected; - -class FeedbackScreen extends NativeComponent -{ - #[On(ShakeDetected::class)] - public function onShake(): void - { - $this->showFeedbackSheet = true; - } -} -``` - -A shake carries no reliable magnitude on iOS, so the event's payload is minimal — just an optional `id` correlation -token, unset unless a future emitter sets one. - - From da77f5b27f9b4ca4f7a922565b6e27353edec759 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 20 Sep 2026 02:16:12 +0100 Subject: [PATCH 6/6] Delete Wallet --- .../docs/mobile/4/plugins/core/wallet.md | 78 ------------------- 1 file changed, 78 deletions(-) delete mode 100644 resources/views/docs/mobile/4/plugins/core/wallet.md diff --git a/resources/views/docs/mobile/4/plugins/core/wallet.md b/resources/views/docs/mobile/4/plugins/core/wallet.md deleted file mode 100644 index 75b57ea0a..000000000 --- a/resources/views/docs/mobile/4/plugins/core/wallet.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Mobile Wallet -order: 1350 ---- - -## Overview - -The `MobileWallet` facade lets your app accept payments through Apple Pay (iOS) and Google Pay (Android) using -[Stripe](https://stripe.com) under the hood. Your Laravel backend creates a payment intent, the device presents the -native payment sheet for the user to authorize with Face ID, Touch ID, or their device PIN, and your backend confirms -the result. - -```php -use Native\Mobile\Facades\MobileWallet; -``` - -## Checking availability - -Not every device supports Apple Pay or Google Pay. Check before showing a "Pay" button: - -```php -if (MobileWallet::isAvailable()) { - // Show the wallet payment option -} -``` - -## Taking a payment - -The flow has three steps: create a payment intent on your backend, present the native payment sheet, then confirm -the result. - -```php -$intent = MobileWallet::createPaymentIntent( - amount: 1999, // $19.99, in cents - currency: 'usd', - metadata: ['order_id' => $order->id], -); - -$result = MobileWallet::presentPaymentSheet( - clientSecret: $intent->client_secret, - merchantDisplayName: 'Acme Widgets', - publishableKey: config('services.stripe.key'), - merchantId: 'merchant.com.acme.widgets', // Your Apple Pay merchant ID -); - -$confirmation = MobileWallet::confirmPayment($intent->id); -``` - -- `createPaymentIntent()` — `$amount` is in the smallest currency unit (cents for USD), `$currency` is a lowercase - ISO code, and `$metadata` is attached to the Stripe payment intent for your own bookkeeping. -- `presentPaymentSheet()` — shows the native card/wallet picker. `$merchantId` is your registered Apple Pay merchant - identifier; `$merchantCountryCode` defaults to `US`. -- `confirmPayment($paymentIntentId)` — confirms the payment with whichever method the user selected. - -You can also poll the current status of a payment at any time: - -```php -$status = MobileWallet::getPaymentStatus($intent->id); -``` - - - -## Events - -Alongside the return values above, the payment sheet also dispatches [native events](../../the-basics/events) as the -user completes, cancels, or fails a payment — listen for these if a screen other than the one that started the -payment needs to react: - -- `Native\Mobile\Events\Wallet\PaymentCompleted` — `paymentIntentId`, `amount`, `currency`, `status`, `metadata`. -- `Native\Mobile\Events\Wallet\PaymentCancelled` — `paymentIntentId`, `reason`. -- `Native\Mobile\Events\Wallet\PaymentFailed` — `paymentIntentId`, `errorCode`, `errorMessage`, `metadata`.