diff --git a/app/Http/Controllers/ShowDocumentationController.php b/app/Http/Controllers/ShowDocumentationController.php
index bae2ce42..d4faeba2 100644
--- a/app/Http/Controllers/ShowDocumentationController.php
+++ b/app/Http/Controllers/ShowDocumentationController.php
@@ -46,7 +46,6 @@ public function __invoke(Request $request, string $platform, string $version, ?s
} catch (InvalidArgumentException $e) {
return $this->redirectToFirstNavigationPage($navigation, $page);
}
-
SEOTools::setTitle($pageProperties['title'].' - NativePHP '.$platform.' v'.$version);
SEOTools::setDescription(Arr::exists($pageProperties, 'description') ? $pageProperties['description'] : '');
@@ -65,7 +64,8 @@ protected function getPageProperties($platform, $version, $page = null): array
$pageProperties = $document->matter();
$versionProperties = YamlFrontMatter::parseFile(resource_path("views/docs/{$platform}/{$version}/_index.md"));
- $pageProperties = array_merge($pageProperties, $versionProperties->matter());
+
+ $pageProperties = array_merge($versionProperties->matter(), $pageProperties);
$pageProperties['platform'] = $platform;
$pageProperties['version'] = $version;
diff --git a/resources/views/docs/mobile/1/_index.md b/resources/views/docs/mobile/1/_index.md
index e69de29b..c719fbe2 100644
--- a/resources/views/docs/mobile/1/_index.md
+++ b/resources/views/docs/mobile/1/_index.md
@@ -0,0 +1,4 @@
+---
+title: Mobile
+order: 1
+---
diff --git a/resources/views/docs/mobile/1/apis/_index.md b/resources/views/docs/mobile/1/apis/_index.md
new file mode 100644
index 00000000..31293365
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/_index.md
@@ -0,0 +1,4 @@
+---
+title: APIs
+order: 4
+---
diff --git a/resources/views/docs/mobile/1/apis/biometrics.md b/resources/views/docs/mobile/1/apis/biometrics.md
new file mode 100644
index 00000000..1a6bff46
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/biometrics.md
@@ -0,0 +1,61 @@
+---
+title: Biometrics
+order: 100
+---
+
+## Overview
+
+The Biometrics API allows you to authenticate users using their device's biometric sensors like Face ID, Touch ID, or
+fingerprint scanners.
+
+```php
+use Native\Mobile\Facades\Biometrics;
+```
+
+## Methods
+
+### `promptForBiometricID()`
+
+Prompts the user for biometric authentication.
+
+```php
+use Native\Mobile\Facades\Biometrics;
+
+Biometrics::promptForBiometricID();
+```
+
+## Events
+
+### `Completed`
+
+Fired when biometric authentication completes (success or failure).
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\Biometric\Completed;
+
+#[On('native:'.Completed::class)]
+public function handleBiometricAuth(bool $success)
+{
+ if ($success) {
+ // User authenticated successfully
+ $this->unlockSecureFeature();
+ } else {
+ // Authentication failed
+ $this->showErrorMessage();
+ }
+}
+```
+
+## Platform Support
+
+- **iOS:** Face ID, Touch ID
+- **Android:** Fingerprint, Face unlock, other biometric methods
+- **Fallback:** System authentication (PIN, password, pattern)
+
+## Security Notes
+
+- Biometric authentication provides **convenience**, not absolute security
+- Always combine with other authentication factors for sensitive operations
+- Consider implementing session timeouts for unlocked states
+- Users can potentially bypass biometrics if their device is compromised
diff --git a/resources/views/docs/mobile/1/apis/browser.md b/resources/views/docs/mobile/1/apis/browser.md
new file mode 100644
index 00000000..5e51061a
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/browser.md
@@ -0,0 +1,58 @@
+---
+title: Browser
+order: 150
+---
+
+## Overview
+
+The Browser API provides three methods for opening URLs, each designed for specific use cases:
+in-app browsing, system browser navigation, and web authentication flows.
+
+```php
+use Native\Mobile\Facades\Browser;
+```
+
+## Methods
+
+### `inApp()`
+
+Opens a URL in an embedded browser within your app using Custom Tabs (Android) or SFSafariViewController (iOS).
+
+```php
+Browser::inApp('https://nativephp.com/mobile');
+```
+
+### `system()`
+
+Opens a URL in the device's default browser app, leaving your application entirely.
+
+```php
+Browser::system('https://nativephp.com/mobile');
+```
+
+### `auth()`
+
+Opens a URL in a specialized authentication browser designed for OAuth flows with automatic `nativephp://` redirect handling.
+
+```php
+Browser::auth('https://provider.com/oauth/authorize?client_id=123&redirect_uri=nativephp://127.0.0.1/auth/callback');
+```
+
+## Use Cases
+
+### When to Use Each Method
+
+**`inApp()`** - Keep users within your app experience:
+- Documentation, help pages, terms of service
+- External content that relates to your app
+- When you want users to easily return to your app
+
+**`system()`** - Full browser experience needed:
+- Complex web applications
+- Content requiring specific browser features
+- When users need bookmarking or sharing capabilities
+
+**`auth()`** - OAuth authentication flows:
+- Login with WorkOS, Auth0, Google, Facebook, etc.
+- Secure authentication with automatic redirects
+- Isolated browser session for security
diff --git a/resources/views/docs/mobile/1/apis/camera.md b/resources/views/docs/mobile/1/apis/camera.md
new file mode 100644
index 00000000..24841f0d
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/camera.md
@@ -0,0 +1,90 @@
+---
+title: Camera
+order: 200
+---
+
+## Overview
+
+The Camera API provides access to the device's camera for taking photos and selecting images from the gallery.
+
+```php
+use Native\Mobile\Facades\Camera;
+```
+
+## Methods
+
+### `getPhoto()`
+
+Opens the camera interface to take a photo.
+
+```php
+Camera::getPhoto();
+```
+
+### `pickImages()`
+
+Opens the gallery/photo picker to select existing images.
+
+**Parameters:**
+- `string $media_type` - Type of media to pick: `'all'`, `'images'`, `'videos'` (default: `'all'`)
+- `bool $multiple` - Allow multiple selection (default: `false`)
+
+**Returns:** `bool` - `true` if picker opened successfully
+
+```php
+// Pick a single image
+Camera::pickImages('images', false);
+
+// Pick multiple images
+Camera::pickImages('images', true);
+
+// Pick any media type
+Camera::pickImages('all', true);
+```
+
+## Events
+
+### `PhotoTaken`
+
+Fired when a photo is taken with the camera.
+
+**Payload:** `string $path` - File path to the captured photo
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\Camera\PhotoTaken;
+
+#[On('native:'.PhotoTaken::class)]
+public function handlePhotoTaken(string $path)
+{
+ // Process the captured photo
+ $this->processPhoto($path);
+}
+```
+
+### `MediaSelected`
+
+Fired when media is selected from the gallery.
+
+**Payload:** `array $media` - Array of selected media items
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\Gallery\MediaSelected;
+
+#[On('native:'.MediaSelected::class)]
+public function handleMediaSelected($success, $files, $count)
+{
+ foreach ($files as $file) {
+ // Process each selected media item
+ $this->processMedia($file);
+ }
+}
+```
+
+## Notes
+
+- The first time your app requests camera access, users will be prompted for permission
+- If permission is denied, camera functions will fail silently
+- Captured photos are stored in the app's temporary directory
+- File formats are platform-dependent (typically JPEG)
diff --git a/resources/views/docs/mobile/1/apis/dialog.md b/resources/views/docs/mobile/1/apis/dialog.md
new file mode 100644
index 00000000..ad7bc558
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/dialog.md
@@ -0,0 +1,103 @@
+---
+title: Dialog
+order: 300
+---
+
+## Overview
+
+The Dialog API provides access to native UI elements like alerts, toasts, and sharing interfaces.
+
+```php
+use Native\Mobile\Facades\Dialog;
+```
+
+## Methods
+
+### `alert()`
+
+Displays a native alert dialog with customizable buttons.
+
+**Parameters:**
+- `string $title` - The alert title
+- `string $message` - The alert message
+- `array $buttons` - Array of button labels (max 3 buttons)
+
+**Button Positioning:**
+- **1 button** - Positive (OK/Confirm)
+- **2 buttons** - Negative (Cancel) + Positive (OK/Confirm)
+- **3 buttons** - Negative (Cancel) + Neutral (Maybe) + Positive (OK/Confirm)
+
+```php
+Dialog::alert(
+ 'Confirm Action',
+ 'Are you sure you want to delete this item?',
+ ['Cancel', 'Delete']
+);
+```
+
+### `toast()`
+
+Displays a brief toast notification message.
+
+
+**Parameters:**
+- `string $message` - The message to display
+
+```php
+Dialog::toast('Item saved successfully!');
+```
+
+#### Good toast messages
+
+- Short and clear
+- Great for confirmations and status updates
+- Don't rely on them for critical information
+- Avoid showing multiple toasts in quick succession
+
+### `share()`
+
+Opens the native sharing interface.
+
+**Parameters:**
+- `string $title` - The share dialog title
+- `string $text` - Text content to share
+- `string $url` - URL to share
+
+```php
+Dialog::share(
+ 'Check this out!',
+ 'I found this amazing Laravel package for mobile development',
+ 'https://nativephp.com'
+);
+```
+
+## Events
+
+### `ButtonPressed`
+
+Fired when a button is pressed in an alert dialog.
+
+**Payload:**
+- `int $index` - Index of the pressed button (0-based)
+- `string $label` - Label/text of the pressed button
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\Alert\ButtonPressed;
+
+#[On('native:'.ButtonPressed::class)]
+public function handleAlertButton($index, $label)
+{
+ switch ($index) {
+ case 0:
+ // First button (usually Cancel)
+ Dialog::toast("You pressed '{$label}'");
+ break;
+ case 1:
+ // Second button (usually OK/Confirm)
+ $this->performAction();
+ Dialog::toast("You pressed '{$label}'");
+ break;
+ }
+}
+```
diff --git a/resources/views/docs/mobile/1/apis/geolocation.md b/resources/views/docs/mobile/1/apis/geolocation.md
new file mode 100644
index 00000000..0a2e4f84
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/geolocation.md
@@ -0,0 +1,155 @@
+---
+title: Geolocation
+order: 400
+---
+
+## Overview
+
+The Geolocation API provides access to the device's GPS and location services to determine the user's current position.
+
+```php
+use Native\Mobile\Facades\Geolocation;
+```
+
+## Methods
+
+### `getCurrentPosition()`
+
+Gets the current GPS location of the device.
+
+**Parameters:**
+- `bool $fineAccuracy` - Whether to use high accuracy mode (GPS vs network) (default: `false`)
+
+**Returns:** Location data via events
+
+```php
+// Get location using network positioning (faster, less accurate)
+Geolocation::getCurrentPosition();
+
+// Get location using GPS (slower, more accurate)
+Geolocation::getCurrentPosition(true);
+```
+
+### `checkPermissions()`
+
+Checks the current location permissions status.
+
+**Returns:** Permission status via events
+
+```php
+Geolocation::checkPermissions();
+```
+
+### `requestPermissions()`
+
+Requests location permissions from the user.
+
+**Returns:** Permission status after request via events
+
+```php
+Geolocation::requestPermissions();
+```
+
+## Events
+
+### `LocationReceived`
+
+Fired when location data is requested (success or failure).
+
+**Event Parameters:**
+- `bool $success` - Whether location was successfully retrieved
+- `float $latitude` - Latitude coordinate (when successful)
+- `float $longitude` - Longitude coordinate (when successful)
+- `float $accuracy` - Accuracy in meters (when successful)
+- `int $timestamp` - Unix timestamp of location fix
+- `string $provider` - Location provider used (GPS, network, etc.)
+- `string $error` - Error message (when unsuccessful)
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\Geolocation\LocationReceived;
+
+#[On('native:'.LocationReceived::class)]
+public function handleLocationReceived(
+ $success = null,
+ $latitude = null,
+ $longitude = null,
+ $accuracy = null,
+ $timestamp = null,
+ $provider = null,
+ $error = null
+) {
+ // ...
+}
+```
+
+### `PermissionStatusReceived`
+
+Fired when permission status is checked.
+
+**Event Parameters:**
+- `string $location` - Overall location permission status
+- `string $coarseLocation` - Coarse location permission status
+- `string $fineLocation` - Fine location permission status
+
+**Permission Values:**
+- `'granted'` - Permission is granted
+- `'denied'` - Permission is denied
+- `'not_determined'` - Permission not yet requested
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\Geolocation\PermissionStatusReceived;
+
+#[On('native:'.PermissionStatusReceived::class)]
+public function handlePermissionStatus($location, $coarseLocation, $fineLocation)
+{
+ // ...
+}
+```
+
+### `PermissionRequestResult`
+
+Fired when a permission request completes.
+
+**Event Parameters:**
+- `string $location` - Overall location permission result
+- `string $coarseLocation` - Coarse location permission result
+- `string $fineLocation` - Fine location permission result
+- `string $message` - Optional message (for permanently denied)
+- `bool $needsSettings` - Whether user needs to go to Settings
+
+**Special Values:**
+- `'permanently_denied'` - User has permanently denied permission
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\Geolocation\PermissionRequestResult;
+
+#[On('native:' . PermissionRequestResult::class)]
+public function handlePermissionRequest($location, $coarseLocation, $fineLocation, $message = null, $needsSettings = null)
+{
+ if ($location === 'permanently_denied') {
+ $this->error = 'Location permission permanently denied. Please enable in Settings.';
+ } elseif ($coarseLocation === 'granted' || $fineLocation === 'granted') {
+ $this->getCurrentLocation();
+ } else {
+ $this->error = 'Location permission is required for this feature.';
+ }
+}
+```
+
+## Privacy Considerations
+
+- **Explain why** you need location access before requesting
+- **Request at the right time** - when the feature is actually needed
+- **Respect denials** - provide alternative functionality when possible
+- **Use appropriate accuracy** - don't request fine location if coarse is sufficient
+- **Limit frequency** - don't request location updates constantly
+
+### Performance Considerations
+- **Battery Usage** - GPS uses more battery than network location
+- **Time to Fix** - GPS takes longer for initial position
+- **Indoor Accuracy** - GPS may not work well indoors
+- **Caching** - Consider caching recent locations for better UX
+
diff --git a/resources/views/docs/mobile/1/apis/haptics.md b/resources/views/docs/mobile/1/apis/haptics.md
new file mode 100644
index 00000000..2ec5c28b
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/haptics.md
@@ -0,0 +1,29 @@
+---
+title: Haptics
+order: 500
+---
+
+## Overview
+
+The Haptics API provides access to the device's vibration and haptic feedback system for tactile user interactions.
+
+```php
+use Native\Mobile\Facades\Haptics;
+```
+
+## Methods
+
+### `vibrate()`
+
+Triggers device vibration for tactile feedback.
+
+**Returns:** `void`
+
+```php
+Haptics::vibrate();
+```
+
+**Use haptics for:** Button presses, form validation, important notifications, game events.
+
+**Avoid haptics for:** Frequent events, background processes, minor updates.
+
diff --git a/resources/views/docs/mobile/1/apis/push-notifications.md b/resources/views/docs/mobile/1/apis/push-notifications.md
new file mode 100644
index 00000000..212bb675
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/push-notifications.md
@@ -0,0 +1,63 @@
+---
+title: PushNotifications
+order: 600
+---
+
+## Overview
+
+The PushNotifications API handles device registration for Firebase Cloud Messaging to receive push notifications.
+
+```php
+use Native\Mobile\Facades\PushNotifications;
+```
+
+## Methods
+
+### `enrollForPushNotifications()`
+
+Requests permission and enrolls the device for push notifications.
+
+**Returns:** `void`
+
+### `getPushNotificationsToken()`
+
+Retrieves the current FCM token for this device.
+
+**Returns:** `string|null` - The FCM token, or `null` if not available
+
+## Events
+
+### `TokenGenerated`
+
+Fired when a push notification token is successfully generated.
+
+**Payload:** `string $token` - The FCM token for this device
+
+```php
+use Livewire\Attributes\On;
+use Native\Mobile\Events\PushNotification\TokenGenerated;
+
+#[On('native:'.TokenGenerated::class)]
+public function handlePushToken(string $token)
+{
+ // Send token to your backend
+ $this->sendTokenToServer($token);
+}
+```
+
+## Permission Flow
+
+1. User taps "Enable Notifications"
+2. App calls `enrollForPushNotifications()`
+3. System shows permission dialog
+4. If granted, FCM generates token
+5. `TokenGenerated` event fires with token
+6. App sends token to backend
+7. Backend stores token for user
+8. Server can now send notifications to this device
+
+## Best Practices
+
+- Request permission at the right time (not immediately on app launch)
+- Explain the value of notifications to users
+- Handle permission denial gracefully
diff --git a/resources/views/docs/mobile/1/apis/secure-storage.md b/resources/views/docs/mobile/1/apis/secure-storage.md
new file mode 100644
index 00000000..14256a6e
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/secure-storage.md
@@ -0,0 +1,87 @@
+---
+title: SecureStorage
+order: 700
+---
+
+## Overview
+
+The SecureStorage API provides secure storage using the device's native keychain (iOS) or keystore (Android). It's
+ideal for storing sensitive data like tokens, passwords, and user credentials.
+
+```php
+use Native\Mobile\Facades\SecureStorage;
+```
+
+## Methods
+
+### `set()`
+
+Stores a secure value in the native keychain or keystore.
+
+**Parameters:**
+- `string $key` - The key to store the value under
+- `string|null $value` - The value to store securely
+
+**Returns:** `bool` - `true` if successfully stored, `false` otherwise
+
+```php
+SecureStorage::set('api_token', 'abc123xyz');
+```
+
+### `get()`
+
+Retrieves a secure value from the native keychain or keystore.
+
+**Parameters:**
+- `string $key` - The key to retrieve the value for
+
+**Returns:** `string|null` - The stored value or `null` if not found
+
+```php
+$token = SecureStorage::get('api_token');
+```
+
+### `delete()`
+
+Deletes a secure value from the native keychain or keystore.
+
+**Parameters:**
+- `string $key` - The key to delete the value for
+
+**Returns:** `bool` - `true` if successfully deleted, `false` otherwise
+
+## Platform Implementation
+
+### iOS - Keychain Services
+- Uses the iOS Keychain Services API
+- Data is encrypted and tied to your app's bundle ID
+- Survives app deletion and reinstallation if iCloud Keychain is enabled
+- Protected by device passcode/biometrics
+
+### Android - Keystore
+- Uses Android Keystore system
+- Hardware-backed encryption when available
+- Data is automatically deleted when app is uninstalled
+- Protected by device lock screen
+
+## Security Features
+
+- **Encryption:** All data is automatically encrypted
+- **App Isolation:** Data is only accessible by your app
+- **System Protection:** Protected by device authentication
+- **Tamper Resistance:** Hardware-backed security when available
+
+## What to Store
+- API tokens and refresh tokens
+- User credentials (if necessary)
+- Encryption keys
+- Sensitive user preferences
+- Two-factor authentication secrets
+
+## What NOT to Store
+- Large amounts of data (use encrypted database instead)
+- Non-sensitive data
+- Temporary data
+- Cached content
+
+
diff --git a/resources/views/docs/mobile/1/apis/system.md b/resources/views/docs/mobile/1/apis/system.md
new file mode 100644
index 00000000..de949e96
--- /dev/null
+++ b/resources/views/docs/mobile/1/apis/system.md
@@ -0,0 +1,36 @@
+---
+title: System
+order: 800
+---
+
+## Overview
+
+The System API provides access to basic system functions like flashlight control.
+
+```php
+use Native\Mobile\Facades\System;
+```
+
+## Methods
+
+### `flashlight()`
+
+Toggles the device flashlight (camera flash LED) on and off.
+
+**Returns:** `void`
+
+```php
+System::flashlight(); // Toggle flashlight state
+```
+
+### `isIos()`
+
+Determines if the current device is running iOS.
+
+**Returns:** `true` if iOS, `false` otherwise
+
+### `isAndroid()`
+
+Determines if the current device is running Android.
+
+**Returns:** `true` if Android, `false` otherwise
diff --git a/resources/views/docs/mobile/1/concepts/_index.md b/resources/views/docs/mobile/1/concepts/_index.md
new file mode 100644
index 00000000..97e3b3a0
--- /dev/null
+++ b/resources/views/docs/mobile/1/concepts/_index.md
@@ -0,0 +1,4 @@
+---
+title: Concepts
+order: 3
+---
diff --git a/resources/views/docs/mobile/1/concepts/ci-cd.md b/resources/views/docs/mobile/1/concepts/ci-cd.md
new file mode 100644
index 00000000..0e05bd2c
--- /dev/null
+++ b/resources/views/docs/mobile/1/concepts/ci-cd.md
@@ -0,0 +1,159 @@
+---
+title: CI/CD Integration
+order: 500
+---
+
+## Overview
+
+NativePHP for Mobile provides robust CLI commands designed for automated CI/CD environments. With proper configuration,
+you can build, package, and deploy mobile apps without manual intervention.
+
+## Key Commands for CI/CD
+
+### Installation Command
+
+Install NativePHP dependencies in automated environments:
+
+```shell
+# Install Android platform, overwriting existing files
+php artisan native:install android --force --no-tty
+
+# Install with ICU support for Filament/intl features
+php artisan native:install android --force --with-icu
+
+# Install both platforms
+php artisan native:install both --force
+```
+
+### Build Commands
+
+Build your app for different environments:
+
+```shell
+# Build debug version (development)
+php artisan native:run android --build=debug --no-tty
+
+# Build release version (production)
+php artisan native:run android --build=release --no-tty
+
+# Build app bundle for Play Store
+php artisan native:run android --build=bundle --no-tty
+```
+
+### Packaging Command
+
+Package signed releases for distribution:
+
+```bash
+# Package signed APK using environment variables
+php artisan native:package android --build-type=release --output=/artifacts --no-tty
+
+# Package signed App Bundle for Play Store
+php artisan native:package android --build-type=bundle --output=/artifacts --no-tty
+```
+
+## Environment Variables
+
+Store sensitive signing information in environment variables:
+
+```bash
+# Android Signing
+ANDROID_KEYSTORE_FILE="/path/to/keystore.jks"
+ANDROID_KEYSTORE_PASSWORD="your-keystore-password"
+ANDROID_KEY_ALIAS="your-key-alias"
+ANDROID_KEY_PASSWORD="your-key-password"
+```
+
+## Command Line Options
+
+### `--no-tty` Flag
+Essential for CI/CD environments where TTY is not available:
+- Disables interactive prompts
+- Provides non-interactive output
+- Shows build progress without real-time updates
+- Required for most automated environments
+
+### `--force` Flag
+Overwrites existing files and directories:
+- Useful for clean builds in CI
+- Ensures fresh installation of NativePHP scaffolding
+- Prevents build failures from existing files
+- Do this whenever you are updating the `nativephp/mobile` package.
+
+### Build Types
+- `--build=debug`: Development builds with debugging enabled
+- `--build=release`: Production builds optimized for distribution
+- `--build=bundle`: App bundles for Play Store distribution
+
+## Signing Configuration
+
+### Using Command Line Options
+```bash
+php artisan native:package android \
+ --build-type=release \
+ --keystore=/path/to/keystore.jks \
+ --keystore-password=your-password \
+ --key-alias=your-alias \
+ --key-password=your-key-password \
+ --output=./artifacts \
+ --no-tty
+```
+
+### Using Environment Variables (Recommended)
+```bash
+# Set environment variables in CI
+export ANDROID_KEYSTORE_FILE="/path/to/keystore.jks"
+export ANDROID_KEYSTORE_PASSWORD="your-password"
+export ANDROID_KEY_ALIAS="your-alias"
+export ANDROID_KEY_PASSWORD="your-key-password"
+
+# Run packaging command
+php artisan native:package android --build-type=release --output=./artifacts --no-tty
+```
+
+## Common CI Workflows
+
+### Development Pipeline
+1. Install dependencies: `composer install`
+2. Setup environment: copy `.env`, generate key
+3. Install NativePHP: `native:install android --force`
+4. Build debug: `native:run android --build=debug --no-tty`
+
+### Release Pipeline
+1. Install dependencies: `composer install --no-dev --optimize-autoloader`
+2. Setup environment with production settings
+3. Install NativePHP: `native:install android --force --with-icu`
+4. Package release: `native:package android --build-type=release --no-tty`
+
+### Play Store Pipeline
+1. Same as release pipeline through step 3
+2. Package bundle: `native:package android --build-type=bundle --no-tty`
+3. Upload to Play Console
+
+## Error Handling
+
+NativePHP commands provide proper exit codes for CI/CD:
+- `0`: Success
+- `1`: General error
+- Build errors are logged and reported
+
+Monitor build logs for:
+- Compilation errors
+- Signing failures
+- Missing dependencies
+- Permission issues
+
+## Performance Tips
+
+### Caching
+Cache these directories in CI for faster builds:
+- `vendor/` (Composer dependencies)
+- `nativephp/android/` (Android project)
+- Android SDK components
+
+### Optimization
+- Use `--no-dev` for production Composer installs
+- Enable Composer autoloader optimization
+- Minimize included files with cleanup configuration
+
+The `--no-tty` flag and environment variable support make NativePHP Mobile well-suited for modern CI/CD pipelines, enabling fully automated mobile app builds and deployments.
diff --git a/resources/views/docs/mobile/1/concepts/databases.md b/resources/views/docs/mobile/1/concepts/databases.md
new file mode 100644
index 00000000..4e66ca96
--- /dev/null
+++ b/resources/views/docs/mobile/1/concepts/databases.md
@@ -0,0 +1,149 @@
+---
+title: Databases
+order: 200
+---
+
+## Working with Databases
+
+You'll almost certainly want your application to persist structured data. For this, NativePHP supports
+[SQLite](https://sqlite.org/), which works on both iOS and Android devices.
+
+You can interact with SQLite from PHP in whichever way you're used to.
+
+## Configuration
+
+You do not need to do anything special to configure your application to use SQLite. NativePHP will automatically:
+- Switch to using SQLite when building your application.
+- Create the database for you in the app container.
+- Run your migrations each time your app starts, as needed.
+
+## Migrations
+
+When writing migrations, you need to consider any special recommendations for working with SQLite.
+
+For example, prior to Laravel 11, SQLite foreign key constraints are turned off by default. If your application relies
+upon foreign key constraints, [you need to enable SQLite support for them](https://laravel.com/docs/database#configuration) before running your migrations.
+
+**It's important to test your migrations on prod builds before releasing updates!** You don't want to accidentally
+delete your user's data when they update your app.
+
+## Seeding data with migrations
+
+Migrations are the perfect mechanism for seeding data in mobile applications. They provide the natural behavior you
+want for data seeding:
+
+- **Run once**: Each migration runs exactly once per installation.
+- **Tracked**: Laravel tracks which migrations have been executed.
+- **Versioned**: New app versions can include new data seeding migrations.
+- **Reversible**: You can create migrations to remove or update seed data.
+
+### Creating seed migrations
+
+Create dedicated migrations for seeding data:
+
+```shell
+php artisan make:migration seed_app_settings
+```
+
+```php
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Support\Facades\DB;
+
+return new class extends Migration
+{
+ public function up()
+ {
+ DB::table('categories')->insert([
+ ['name' => 'Work', 'color' => '#3B82F6'],
+ ['name' => 'Personal', 'color' => '#10B981'],
+ ]);
+ }
+};
+```
+
+### Test thoroughly
+
+This is the most important step when releasing new versions of your app, especially with new migrations.
+
+Your migrations should work both for users who are installing your app for the first time (or re-installing) _and_
+users who have updated your app to a new release.
+
+Make sure you test your migrations under the different scenarios that your users' databases are likely to be in.
+
+## Things to note
+
+- As your app is installed on a separate device, you do not have remote access to the database.
+- If a user deletes your application from their device, any databases are also deleted.
+
+## Can I get MySQL/Postgres/other support?
+
+No.
+
+SQLite being the only supported database driver is a deliberate security decision to prevent developers from
+accidentally embedding production database credentials directly in mobile applications. Why?
+
+- Mobile apps are distributed to user devices and can be reverse-engineered.
+- Database credentials embedded in apps may be accessible to anyone with the app binary.
+- Direct database connections bypass important security layers like rate limiting and access controls.
+- Network connectivity issues make direct database connections unreliable from mobile devices and can be troublesome
+ for your database to handle.
+
+## API-first
+
+If a key part of your application relies on syncing data between a central database and your client apps, we strongly
+recommend that you do so via a secure API backend that your mobile app can communicate with.
+
+This provides multiple security and architectural benefits:
+
+**Security Benefits:**
+- Database credentials never leave your server
+- Implement proper authentication and authorization
+- Rate limiting and request validation
+- Audit logs for all data access
+- Ability to revoke access instantly
+
+**Technical Benefits:**
+- Better error handling and offline support
+- Easier to scale and maintain
+- Version your API for backward compatibility
+- Transform data specifically for mobile consumption
+
+### Securing your API
+
+For the same reasons that you shouldn't share database credentials in your `.env` file or elsewhere in your app code,
+you shouldn't store API keys or tokens either.
+
+If anything, you should provide a client key that **only** allows client apps to request tokens. Once you have
+authenticated your user, you can pass an access token back to your mobile app and use this for communicating with your
+API.
+
+Store these tokens on your users' devices securely with the [`SecureStorage`](/docs/mobile/1/apis/secure-storage) API.
+
+It's a good practice to ensure these tokens have high entropy so that they are very hard to guess and a short lifespan.
+Generating tokens is cheap; leaking personal customer data can get _very_ expensive!
+
+Use industry-standard tools like OAuth-2.0-based providers, Laravel Passport, or Laravel Sanctum.
+
+
+
+#### Considerations
+
+In your mobile apps:
+
+- Always store API tokens using `SecureStorage`
+- Use HTTPS for all API communications
+- Cache data locally using SQLite for offline functionality
+- Check for connectivity before making API calls
+
+And on the API side:
+
+- Use token-based authentication
+- Implement rate limiting to prevent abuse
+- Validate and sanitize all input data
+- Use HTTPS with proper SSL certificates
+- Log all authentication attempts and API access
diff --git a/resources/views/docs/mobile/1/concepts/deep-links.md b/resources/views/docs/mobile/1/concepts/deep-links.md
new file mode 100644
index 00000000..3bb8a305
--- /dev/null
+++ b/resources/views/docs/mobile/1/concepts/deep-links.md
@@ -0,0 +1,92 @@
+---
+title: Deep Links
+order: 300
+---
+
+## Overview
+
+NativePHP for Mobile supports **deep linking** into your app via Custom URL Schemes and Associated Domains:
+
+- **Custom URL Scheme**
+ ```
+ myapp://some/path
+ ```
+- **Associated Domains** (a.k.a. Universal Links on iOS, App Links on Android)
+ ```
+ https://example.net/some/path
+ ```
+
+In each case, your app can be opened directly at the route matching `/some/path`.
+
+Each method has its use cases, and NativePHP handles all the platform-specific configuration automatically when you
+provide the proper environment variables.
+
+You can even use both approaches at the same time in a single app!
+
+## Custom URL Scheme
+
+Custom URL schemes are a great way to allow apps to pass data between themselves. If your app is installed when a user
+uses a deep link that incorporates your custom scheme, your app will open immediately to the desired route.
+
+But note that custom URL schemes can only work when your app has been installed and cannot aid in app discovery. If a
+user interacts with URL with a custom scheme for an app they don't have installed, there will be no prompt to install
+an app that can load that URL.
+
+To enable your app's custom URL scheme, define it in your `.env`:
+
+```dotenv
+NATIVEPHP_DEEPLINK_SCHEME=myapp
+```
+
+You should choose a scheme that is unique to your app to avoid confusion with other apps. Note that some schemes are
+reserved by the system and cannot be used (e.g. `https`).
+
+## Associated domains
+
+Universal Links/App Links allow real HTTPS URLs to open your app instead of in a web browser, if the app is installed.
+If the app is not installed, the URL will load as normal in the browser.
+
+This flow increases the opportunity for app discovery dramatically and provides a much better overall user experience.
+
+### How it works
+
+1. You must prove to the operating system on the user's device that your app is legitimately associated with the domain
+ you are trying to redirect by hosting special files on your server:
+ - `.well-known/apple-app-site-association` (for iOS)
+ - `.well-known/assetlinks.json` (for Android)
+2. The mobile OS reads these files to verify the link association
+3. Once verified, tapping a real URL will open your app instead of opening it in the user's browser
+
+**NativePHP handles all the technical setup automatically** - you just need to host the verification files and
+configure your domain correctly.
+
+To enable an app-associated domain, define it in your `.env`:
+
+```dotenv
+NATIVEPHP_DEEPLINK_HOST=example.net
+```
+
+## Testing & troubleshooting
+
+Associated Domains do not usually work in simulators. Testing on a real device that connects to a publicly-accessible
+server for verification is often the best way to ensure these are operating correctly.
+
+If you are experiencing issues getting your associated domain to open your app, try:
+- Completely deleting and reinstalling the app. Registration verifications (including failures) are often cached
+ against the app.
+- Validating that your associated domain verification files are formatted correctly and contain the correct data.
+
+There is usually no such limitation for Custom URL Schemes.
+
+## Use cases
+
+Deep linking is great for bringing users from another context directly to a key place in your app. Universal/App Links
+are usually the more appropriate choice for this because of their flexibility in falling back to simple loading a URL
+in the browser.
+
+They're also more likely to behave the same across both platforms.
+
+Then you could use Universal/App Links in:
+- NFC tags
+- QR codes
+- Email/SMS marketing
diff --git a/resources/views/docs/mobile/1/concepts/push-notifications.md b/resources/views/docs/mobile/1/concepts/push-notifications.md
new file mode 100644
index 00000000..07ee6d72
--- /dev/null
+++ b/resources/views/docs/mobile/1/concepts/push-notifications.md
@@ -0,0 +1,93 @@
+---
+title: Push Notifications
+order: 400
+---
+
+## Overview
+
+NativePHP for Mobile uses Firebase Cloud Messaging (FCM) to send push notifications to your users on both iOS and
+Android devices.
+
+To send a push notification to a user, your app must request a token. That token must then be stored securely (ideally
+on a server application via a secure API) and associated with that user/device.
+
+Requesting push notification will trigger an alert for the user to either approve or deny your request. If they approve,
+your app will receive the token.
+
+When you want to send a notification to that user, you pass this token along with a request to the FCM service and
+Firebase handles sending the message to the right device.
+
+
+
+## Firebase
+
+1. Create a [Firebase](https://firebase.google.com/) account
+2. Create a project
+3. Download the `google-services.json` file (for Android) and `GoogleService-Info.plist` file (for iOS)
+4. These files contain the configuration for your app and is used by the Firebase SDK to retrieve tokens for each device
+
+Place these files in the root of your application and NativePHP will automatically handle setting them up appropriately
+for each platform.
+
+You can ignore Firebase's further setup instructions as this is already taken care of by NativePHP.
+
+### Service account
+
+For sending push notifications from your server-side application, you'll also need a Firebase service account:
+
+1. Go to your Firebase Console → Project Settings → Service Accounts
+2. Click "Generate New Private Key" to download the service account JSON file
+3. Save this file as `fcm-service-account.json` somewhere safe in your server application
+
+## Getting push tokens
+
+It's common practice to request push notification permissions during app bootup as tokens can change when:
+- The app is restored on a new device
+- The app data is restored from backup
+- The app is updated
+- Other internal FCM operations
+
+To request a token, use the `PushNotifications::getPushNotificationsToken()` method:
+
+```php
+use Native\Mobile\Facades\PushNotifications;
+
+PushNotifications::getPushNotificationsToken();
+```
+
+If the user has approved your app to use push notifications and the request to FCM succeeded, a `TokenGenerated` event
+will fire.
+
+Listen for this event to receive the token. Here's an example in a Livewire component:
+
+```php
+use App\Services\APIService;
+use Livewire\Attributes\On;
+use Native\Mobile\Facades\PushNotifications;
+use Native\Mobile\Events\PushNotification\TokenGenerated;
+
+class PushNotifications extends Component
+{
+ #[On('native:'.TokenGenerated::class)]
+ public function storePushToken(APIService $api, string $token)
+ {
+ $api->storePushToken($token);
+ }
+}
+```
+
+## Sending push notifications
+
+Once you have a token, you may use it from your server-side applications to trigger Push Notifications directly to your
+user's device.
+
+
diff --git a/resources/views/docs/mobile/1/digging-deeper/security.md b/resources/views/docs/mobile/1/concepts/security.md
similarity index 98%
rename from resources/views/docs/mobile/1/digging-deeper/security.md
rename to resources/views/docs/mobile/1/concepts/security.md
index 6b8254b3..2abb9acf 100644
--- a/resources/views/docs/mobile/1/digging-deeper/security.md
+++ b/resources/views/docs/mobile/1/concepts/security.md
@@ -27,4 +27,4 @@ level of entropy, as this makes them hard to guess and hard to abuse.
If your application allows users to connect _their own_ API keys for a service, you should treat these keys with great
care. If you choose to store them anywhere (either in a [File](files) or
[Database](databases)), make sure you store them
-[encrypted](../the-basics/system#encryption-decryption) and decrypt them only when needed.
+[encrypted](../the-basics/system#encryption-decryption) and decrypt them only when needed.
\ No newline at end of file
diff --git a/resources/views/docs/mobile/1/digging-deeper/_index.md b/resources/views/docs/mobile/1/digging-deeper/_index.md
deleted file mode 100644
index 7d67168d..00000000
--- a/resources/views/docs/mobile/1/digging-deeper/_index.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Digging Deeper
-order: 3
----
diff --git a/resources/views/docs/mobile/1/digging-deeper/databases.md b/resources/views/docs/mobile/1/digging-deeper/databases.md
deleted file mode 100644
index fdccaf8f..00000000
--- a/resources/views/docs/mobile/1/digging-deeper/databases.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: Databases
-order: 200
----
-
-## Working with Databases
-
-You'll almost certainly want your application to persist structured data. For this, NativePHP supports
-[SQLite](https://sqlite.org/), which works on both iOS and Android devices.
-
-You can interact with SQLite from PHP in whichever way you're used to.
-
-## Configuration
-
-You do not need to do anything special to configure your application to use SQLite. NativePHP will automatically:
-- Switch to using SQLite when building your application.
-- Create the database for you in the app container.
-- Run your migrations each time your app starts, as needed.
-
-## Migrations
-
-When writing migrations, you need to consider any special recommendations for working with SQLite.
-
-For example, prior to Laravel 11, SQLite foreign key constraints are turned off by default. If your application relies
-upon foreign key constraints, [you need to enable SQLite support for them](https://laravel.com/docs/database#configuration) before running your migrations.
-
-**It's important to test your migrations on prod builds before releasing updates!** You don't want to accidentally
-delete your user's data when they update your app.
-
-## Things to note
-
-- As your app is installed on a separate device, you do not have remote access to the database.
-- If a user deletes your application from their device, any databases are also deleted.
diff --git a/resources/views/docs/mobile/1/digging-deeper/push-notifications.md b/resources/views/docs/mobile/1/digging-deeper/push-notifications.md
deleted file mode 100644
index a1b47a3a..00000000
--- a/resources/views/docs/mobile/1/digging-deeper/push-notifications.md
+++ /dev/null
@@ -1,96 +0,0 @@
----
-title: Push Notifications
-order: 400
----
-
-
-## Overview
-
-NativePHP for Mobile uses [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) to send push notifications to your users.
-
-## Setting up your app
-
-Once you create a Firebase account and create a project you will be offered to download a `google-services.json` file.
-
-This file contains the configuration for your app and is used by the Firebase SDK to retrieve tokens for each device using your app.
-
-Simply drag this file into the root of your Laravel project, enable `push_notifications` in the [config](/docs/mobile/1/getting-started/configuration) it will be used automatically.
-
-You will see more instructions on how to configure your app in the Firebase documentation, you can ignore all of those, NativePHP handles all of that for you.
-
-## Receiving Push Tokens
-
-To receive push notifications, you must register a listener for the event. For example,
-take a look at how easy it is to listen for a `TokenGenerated` event in Livewire:
-
-```php
-use Livewire\Attributes\On;
-use Livewire\Component;
-use Native\Mobile\Facades\System;
-use Native\Mobile\Events\PushNotification\TokenGenerated;
-
-class PushNotifications extends Component
-{
- public function render()
- {
- return view('livewire.system.push-notifications');
- }
-
- #[On('native:' . TokenGenerated::class)]
- public function handlePushNotifications(string $token)
- {
- // Do something with the token...
- }
-}
-```
-
-Because of the nature of mobile applications you need an api server to handle these tokens. You can use Laravel's built-in `Http` facade to
-`POST` the token to your server, on the server side you need to associate the token with the "user" that owns the device.
-
-We **strongly** recommend using [Sanctum](https://laravel.com/docs/12.x/sanctum#main-content) to handle this for you.
-
-## The flow
-
-Your app authenticates users against your own api server, when users create an account or login the server validates and authenticates the user and passes back a Sanctum token.
-
-The token is stored in your apps `session` and is used on subsequent requests to the api server.
-
-When a push notification is received, the token is sent to your api server and the server stores it for the user who sent it.
-
-> Optionally, you can have a `HasMany` relationship between your users and devices,
-> this allows you to associate a device with a user and then use the device's token
-> to send push notifications to that users devices.
-
-## Sending Push Notifications
-
-Once you have the token, you may use it from your server-based applications to trigger Push Notifications directly to
-your user's device. We use a package like [google/apiclient](https://github.com/googleapis/google-api-php-client) to send the notifications.
-
-This is the exact code used by the NativePHP Kitchen Sink App (available soon on all app stores and GitHub):
-
-```php
-Route::group(['middleware' => 'auth:sanctum'], function () {
- Route::post('send-push-notification', PushNotificationController::class)->name('send-push-notification');
-});
-```
-
-```php
-namespace App\Http\Controllers;
-
-use App\Jobs\SendPushNotification;
-use Illuminate\Http\Request;
-
-class PushNotificationController extends Controller
-{
- public function __invoke(Request $request)
- {
- $token = $request->get('token');
-
- $request->user()->update([
- 'push_token' => $token
- ]);
-
- SendPushNotification::dispatch($token)->delay(now()->addMinutes(1));
- }
-}
-```
diff --git a/resources/views/docs/mobile/1/getting-started/_index.md b/resources/views/docs/mobile/1/getting-started/_index.md
index 7f67f577..5c684744 100644
--- a/resources/views/docs/mobile/1/getting-started/_index.md
+++ b/resources/views/docs/mobile/1/getting-started/_index.md
@@ -1,4 +1,4 @@
---
title: Getting Started
order: 1
----
+---
\ No newline at end of file
diff --git a/resources/views/docs/mobile/1/getting-started/configuration.md b/resources/views/docs/mobile/1/getting-started/configuration.md
index c6cf39b2..78293577 100644
--- a/resources/views/docs/mobile/1/getting-started/configuration.md
+++ b/resources/views/docs/mobile/1/getting-started/configuration.md
@@ -5,19 +5,20 @@ order: 200
## Overview
-NativePHP for Mobile is designed so that most configuration happens **inside your Laravel application**, without requiring you to manually open Xcode or Android Studio.
+NativePHP for Mobile is designed so that most configuration happens **inside your Laravel application**, without
+requiring you to manually open Xcode or Android Studio.
-After installation, NativePHP sets up the necessary native scaffolding, but your primary interaction remains inside Laravel itself.
-
-This page explains the key configuration points you can control directly through Laravel.
+This page explains the key configuration points you can control through Laravel.
## The `nativephp.php` Config File
-The nativephp.php config file is where you can configure the native project for your application.
+The `config/nativephp.php` config file contains a number of useful options.
-NativePHP uses sensible defaults and makes several assumptions based on default installations for tools required to build and run apps from your computer.
+NativePHP uses sensible defaults and makes several assumptions based on default installations for tools required to
+build and run apps from your computer.
-You can override these defaults by editing the `nativephp.php` config file in your Laravel project or changing environment variables.
+You can override these defaults by editing the `nativephp.php` config file in your Laravel project, and in many case
+simply by changing environment variables.
```dotenv
NATIVEPHP_APP_VERSION
@@ -30,6 +31,42 @@ NATIVEPHP_GRADLE_PATH
NATIVEPHP_ANDROID_SDK_LOCATION
```
+## `NATIVEPHP_APP_ID`
+
+You must set your app ID to something unique. A common practice is to use a reverse-DNS-style name, e.g.
+`com.yourcompany.yourapp`.
+
+Your app ID (also known as a *Bundle Identifier*) is a critical piece of identification across both Android and iOS
+platforms. Different app IDs are treated as separate apps.
+
+And it is often referenced across multiple services, such as Apple Developer Center and the Google Play Console.
+
+So it's not something you want to be changing very often.
+
+## `NATIVEPHP_APP_VERSION`
+
+The `NATIVEPHP_APP_VERSION` environment variable controls your app's versioning behavior.
+
+When your app is compiling, NativePHP first copies the relevant Laravel files into a temporary directory, zips them up,
+and embeds the archive into the native application.
+
+When your app boots, it checks the embedded version against the previously installed version to see if it needs to
+extract the bundled Laravel application.
+
+If the versions match, the app uses the existing files without re-extracting the archive.
+
+To force your application to always install the latest version of your code - especially useful during development -
+set this to `DEBUG`:
+
+```dotenv
+NATIVEPHP_APP_VERSION=DEBUG
+```
+
+Note that this will make your application's boot up slightly slower as it must unpack the zip every time it loads.
+
+But this ensures that you can iterate quickly during development, while providing a faster, more stable experience for
+end users once an app is published.
+
## Cleanup `env` keys
The `cleanup_env_keys` array in the config file allows you to specify keys that should be removed from the `.env` file before bundling.
@@ -41,12 +78,30 @@ The `cleanup_exclude_files` array in the config file allows you to specify files
This is useful for removing files like logs or other temporary files.
## Permissions
-In general, the app stores don't want apps to request permissions that they don't need.
-To enable some permissions your app needs you simply need to change their values in the permissions section.
+In general, the app stores don't want your app to have permissions (a.k.a entitlements) it doesn't need.
-```dotenv
-biometric
-camera
-nfc
-push_notifications
+By default, all optional permissions are disabled.
+
+You may enable the features you intend to use simply by changing the value of the appropriate permission to `true`:
+
+```php
+
+ 'permissions' => [
+
+ 'biometric' => true,
+
+ ],
```
+
+### Available permissions
+
+- `biometric` - Allows your application to use fingerprint or face-recognition hardware (with a fallback to PIN code)
+ to secure parts of your application.
+- `camera` - Allows your application to request access to the device's camera, if present. Note that the user may deny
+ access and any camera functions will then result in a no-op.
+- `nfc` - Allows your application to request access to the device's NFC reader, if present.
+- `push_notifications` - Allows your application to request permissions to send push notifications. Note that the user
+ may deny this and any push notification functions will then result in a no-op.
+- `location` - Allows your application to request access to the device's GPS receiver, if present. Note that the user
+ may deny this and any location functions will then result in a no-op.
+
diff --git a/resources/views/docs/mobile/1/getting-started/development.md b/resources/views/docs/mobile/1/getting-started/development.md
index 0097512c..4ada4598 100644
--- a/resources/views/docs/mobile/1/getting-started/development.md
+++ b/resources/views/docs/mobile/1/getting-started/development.md
@@ -3,30 +3,114 @@ title: Development
order: 300
---
+## Building
-## The `nativephp` Directory
+Building your NativePHP apps can be done completely in the browser with the workflows you're already familiar with.
-After running: `php artisan native:install` you’ll see a new `nativephp` directory at the root of your Laravel project as well as a `nativephp.php` config file in your config folder in the Laravel root.
+This allows you to iterate rapidly on parts like the UI and major functionality, even using your favorite tools for
+testing etc.
-This folder contains all the native project files that NativePHP generates for you.
+But when you want to test _native_ features, then you must run it on a real/emulated device.
-You should not need to manually open or edit any native project files under normal circumstances.
-NativePHP handles the heavy lifting for you.
+Whether you run your native app on an emulated or real device, it will always require compilation after changes have
+been made.
-## NATIVEPHP_APP_VERSION
+We've worked incredibly hard to ensure that your apps will operate almost identically across both platforms - aside
+from obvious platform differences. For the most part, you should be able to build without thinking about which platform
+your app is running on, but if you do need to, you can check by using one of the following helper methods:
-The NATIVEPHP_APP_VERSION environment variable controls your app's versioning behavior.
+```php
+use Native\Mobile\Facades\System;
-When building for Android, NativePHP first copies the relevant Laravel files into a temporary directory, zips them, and embeds the archive into the Android project. When the app boots, it checks the embedded version against the previously installed version.
+System::isIos() // -> `true` on iOS
+System::isAndroid() // -> `true` on Android
+```
-If the versions match, the app uses the existing files without re-extracting the archive.
+To compile and run your app, simply run:
-If the versions differ — or if the version is set to ***DEBUG*** — the app updates itself by re-extracting the new bundle.
+```shell
+php artisan native:run --build=debug
+```
-This mechanism ensures developers can iterate quickly during development, while providing a faster, more stable experience for end users once an app is published.
+This single command takes care of everything and allows you to run new builds of your application without having to
+learn any new editors or platform-specific tools.
-> Rule of Thumb:
-> During development, keep NATIVEPHP_APP_VERSION set to DEBUG to always refresh the app.
-> When preparing a new release, update it to a semantic version (e.g., 1.2.3) to enable versioned updates for your users.
+
+
+## Working with Xcode or Android Studio
+
+On occasion, it is useful to compile your app from inside the target platform's dedicated development tools, Android
+Studio and Xcode.
+
+If you're familiar with these tools, you can easily open the projects using the following Artisan command:
+
+```shell
+php artisan native:open
+```
+
+## Hot Reloading (Experimental)
+
+You can enable hot reloading by adding the `--watch` flag when running the `native:run` command:
+
+```shell
+php artisan native:run --watch
+```
+
+This is useful during development for quickly testing changes without rebuilding the entire app.
+
+### Caveats
+
+- This feature is currently best suited for **Blade** and **Livewire** applications.
+- It does **not** currently detect or sync **compiled frontend assets**, such as those built with Vite or used by
+ **Inertia.js**.
+- If you're working with a JavaScript-heavy stack (Vue, React, Inertia), you should continue
+ [building your frontend](/docs/mobile/1/the-basics/assets) before launching the app with `native:run`.
+
+## Releasing
+
+To prepare your app for release, you should set the version number to a new version number that you have not used
+before and increment the build number:
+
+```dotenv
+NATIVEPHP_APP_VERSION=1.2.3
+NATIVEPHP_APP_VERSION_CODE=48
+```
+
+### Versioning
+
+You have complete freedom in how you version your applications. You may use semantic versioning, codenames,
+date-based versions, or any scheme that works for your project, team or business.
+
+Remember that your app versions are usually public-facing (e.g. in store listings and on-device settings and update
+screens) and can be useful for customers to reference if they need to contact you for help and support.
+
+The build number is managed via the `NATIVEPHP_APP_VERSION` key in your `.env`.
+
+### Build numbers
+
+Both the Google Play Store and Apple App Store require your app's build number to increase for each release you submit.
+
+The build number is managed via the `NATIVEPHP_APP_VERSION_CODE` key in your `.env`.
+
+### Run a `release` build
+
+Then run a release build:
+
+```shell
+php artisan native:run --build=release
+```
+
+This builds your application with various optimizations that reduce its overall size and improve its performance, such
+as removing debugging code and unnecessary features (i.e. Composer dev dependencies).
+
+**You should test this build on a real device.** Once you're happy that everything is working as intended you can then
+submit it to the stores for approval and distribution.
+
+- [Google Play Store submission guidelines](https://support.google.com/googleplay/android-developer/answer/9859152?hl=en-GB#zippy=%2Cmaximum-size-limit)
+- [Apple App Store submission guidelines](https://developer.apple.com/ios/submit/)
diff --git a/resources/views/docs/mobile/1/getting-started/environment-setup.md b/resources/views/docs/mobile/1/getting-started/environment-setup.md
new file mode 100644
index 00000000..561a5c95
--- /dev/null
+++ b/resources/views/docs/mobile/1/getting-started/environment-setup.md
@@ -0,0 +1,132 @@
+---
+title: Environment Setup
+order: 100
+---
+
+## Requirements
+
+1. PHP 8.3+
+2. Laravel 11+
+3. [A NativePHP for Mobile license](https://nativephp.com/mobile)
+
+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!
+
+## iOS Requirements
+
+
+
+1. macOS (required - iOS development is only possible on a Mac)
+2. [Xcode 16.0 or later](https://apps.apple.com/app/xcode/id497799835)
+3. Xcode Command Line Tools
+4. Homebrew & CocoaPods
+5. _Optional_ iOS device for testing
+
+### Setting up iOS Development Environment
+
+1. **Install Xcode**
+ - Download from the [Mac App Store](https://apps.apple.com/app/xcode/id497799835)
+ - Minimum version: Xcode 16.0
+
+2. **Install Xcode Command Line Tools**
+ ```shell
+ xcode-select --install
+ ```
+ Verify installation:
+ ```shell
+ xcode-select -p
+ ```
+
+3. **Install Homebrew** (if not already installed)
+ ```shell
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
+ ```
+
+4. **Install CocoaPods**
+ ```shell
+ brew install cocoapods
+ ```
+ Verify installation:
+ ```shell
+ pod --version
+ ```
+
+### Apple Developer Account
+You **do not** need to enroll in the [Apple Developer Program](https://developer.apple.com/programs/enroll/) ($99/year)
+to develop and test your apps on a Simulator. However, you will need to enroll when you want to:
+- Test your apps on real devices
+- Distribute your apps via the App Store
+
+## Android Requirements
+
+1. [Android Studio 2024.2.1 or later](https://developer.android.com/studio)
+2. Android SDK with API 23 or higher
+3. **Windows only**: You must have [7zip](https://www.7-zip.org/) installed.
+
+
+
+### Setting up Android Studio and SDK
+
+1. **Download and Install Android Studio**
+ - Download from the [Android Studio download page](https://developer.android.com/studio)
+ - Minimum version required: Android Studio 2024.2.1
+
+2. **Install Android SDK**
+ - Open Android Studio
+ - Navigate to **Tools → SDK Manager**
+ - In the **SDK Platforms** tab, install at least one Android SDK platform for API 23 or higher
+ - Latest stable version: Android 15 (API 35)
+ - You only need to install one API version to get started
+ - In the **SDK Tools** tab, ensure **Android SDK Build-Tools** and **Android SDK Platform-Tools** are installed
+
+That's it! Android Studio handles all the necessary configuration automatically.
+
+### Preparing for NativePHP
+
+1. Check that you can run `java -v` and `adb devices` from the terminal.
+2. The following environment variables set:
+
+#### On macOS
+```shell
+export JAVA_HOME=$(/usr/libexec/java_home -v 17) // This isn't required if JAVA_HOME is already set in your environment variables (check using `printenv | grep JAVA_HOME`)
+export ANDROID_HOME=$HOME/Library/Android/sdk
+export PATH=$PATH:$JAVA_HOME/bin:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
+```
+
+#### On Windows
+```shell
+set ANDROID_HOME=C:\Users\yourname\AppData\Local\Android\Sdk
+set PATH=%PATH%;%JAVA_HOME%\bin;%ANDROID_HOME%\platform-tools
+
+# This isn't required if JAVA_HOME is already set in the Windows Env Variables
+set JAVA_HOME=C:\Program Files\Microsoft\jdk-17.0.8.7-hotspot
+```
+
+## Testing on Real Devices
+
+You don't _need_ a physical iOS/Android device to compile and test your application, as NativePHP for Mobile supports
+the iOS Simulator and Android emulators. However, we highly recommend that you test your application on a real device
+before submitting to the Apple App Store and Google Play Store.
+
+### On iOS
+If you want to run your app on a real iOS device, you need to make sure it is in
+[Developer Mode](https://developer.apple.com/documentation/xcode/enabling-developer-mode-on-a-device)
+and that it's been added to your Apple Developer account as
+[a registered device](https://developer.apple.com/account/resources/devices/list).
+
+### On Android
+On Android you need to [enable developer options](https://developer.android.com/studio/debug/dev-options#enable)
+and have USB debugging (ADB) enabled.
diff --git a/resources/views/docs/mobile/1/getting-started/installation.md b/resources/views/docs/mobile/1/getting-started/installation.md
index 6f930534..a9f64b18 100644
--- a/resources/views/docs/mobile/1/getting-started/installation.md
+++ b/resources/views/docs/mobile/1/getting-started/installation.md
@@ -3,63 +3,33 @@ title: Installation
order: 100
---
-## Requirements
+## Get a license
-1. PHP 8.3+
-2. Laravel 10 or higher
-3. [A NativePHP for Mobile license](https://nativephp.com/mobile)
+Before you begin, you will need to [purchase a license](/mobile).
-### For iOS
-1. An Apple Silicon Mac running macOS 12+ with [Xcode 16+](https://apps.apple.com/app/xcode/id497799835)
-2. An active [Apple Developer account](https://developer.apple.com/)
-3. _Optional_ iOS device
-
-You **do not** need to enroll in the [Apple Developer Program](https://developer.apple.com/programs/enroll/) ($99/year)
-to develop and test your apps on a Simulator. But you will need to when you want to test your apps on real devices
-and start distributing them to your users via the App Store.
-
-> **Note** You cannot build iOS apps on Windows or Linux
-
-### For Android
-1. [Android Studio Giraffe (or later)](https://developer.android.com/studio)
-2. The following environment variables set.
-3. You should be able to successfully run `java -v` and `adb devices` from the terminal.
-4. **Windows only**: You must have [7zip](https://www.7-zip.org/) installed.
-
-#### On macOS
-```shell
-export JAVA_HOME=$(/usr/libexec/java_home -v 17) // This isn't required if JAVA_HOME is already set in your environment variables (check using `printenv | grep JAVA_HOME`)
-export ANDROID_HOME=$HOME/Library/Android/sdk
-export PATH=$PATH:$JAVA_HOME/bin:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
-```
-
-#### On Windows
-```shell
-set ANDROID_HOME=C:\Users\yourname\AppData\Local\Android\Sdk
-set PATH=%PATH%;%JAVA_HOME%\bin;%ANDROID_HOME%\platform-tools
-
-# This isn't required if JAVA_HOME is already set in the Windows Env Variables
-set JAVA_HOME=C:\Program Files\Microsoft\jdk-17.0.8.7-hotspot
-```
+To make NativePHP for Mobile a reality has taken a lot of work and will continue to require even more. For this reason,
+it's not open source, and you are not free to distribute or modify its source code.
-You don't _need_ a physical iOS/Android device to compile and test your application, as NativePHP for Mobile supports
-the iOS Simulator and Android emulators. However, we highly recommend that you test your application on a real device before submitting to the
-Apple App Store and Google Play Store.
+Your license fee goes straight back into the NativePHP project and community, enabling us to:
+- Develop premium features for everyone.
+- Provide first-class support.
+- Sponsor our dependencies.
+- Donate to our contributors.
+- Support community events.
+- Ensure that the whole NativePHP project remains viable for a long time to come.
-## Laravel
+Thank you for supporting the project in this way! 🙏
-NativePHP for Mobile is built to work with Laravel. You can install it into an existing Laravel application, or
-[start a new one](https://laravel.com/docs/installation). 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!
+## Install the Composer package
+
Once you have your license, you will need to add the following to your `composer.json`:
@@ -76,7 +46,21 @@ Then run:
```shell
composer require nativephp/mobile
```
-*If you experience a cURL error when running this command make sure you are running PHP v8.3+ in your CLI.*
+
+
+
If this is the first time you're installing the package, you will be prompted to authenticate. Your username is the
email address you used when purchasing your license. Your password is your license key.
@@ -84,7 +68,7 @@ email address you used when purchasing your license. Your password is your licen
This package contains all the libraries, classes, commands, and interfaces that your application will need to work with
iOS and Android.
-**Before** running the `install` command it is important to set the following variables in your `.env`:
+**Before** running the `install` command, it is important to set the following variables in your `.env`:
```shell
NATIVEPHP_APP_ID=com.yourcompany.yourapp
@@ -100,6 +84,34 @@ php artisan native:install
The NativePHP installer takes care of setting up and configuring your Laravel application to work with iOS and Android.
+You may be prompted about whether you would like to install the ICU-enabled PHP binaries. You should install these if
+your application relies on the `intl` PHP extension.
+
+If you don't need `intl` or are not sure, choose the default, non-ICU builds.
+
+
+
+### The `nativephp` Directory
+
+After running: `php artisan native:install` you’ll see a new `nativephp` directory at the root of your Laravel project
+as well as a `config/nativephp.php` config file.
+
+The `nativephp` folder contains the native application project files needed to build your app for the desired platforms.
+
+You should not need to manually open or edit any native project files under normal circumstances. NativePHP handles
+the heavy lifting for you.
+
+**You should treat this directory as ephemeral.** When upgrading the NativePHP package, it will be necessary to run
+`php artisan native:install --force`, which completely rebuilds this directory, deleting all files within.
+
+For this reason, we also recommend you add the `nativephp` folder to your `.gitignore`.
+
## Start your app
**Heads up!** Before starting your app in a native context, try running it in the browser. You may bump into exceptions
@@ -111,7 +123,7 @@ Once you're ready:
php artisan native:run
```
-This will start compiling your application and boot it on whichever device you select.
+Just follow the prompts! This will start compiling your application and boot it on whichever device you select.
### Running on a real device
diff --git a/resources/views/docs/mobile/1/getting-started/introduction.md b/resources/views/docs/mobile/1/getting-started/introduction.md
index c313a037..a4a91c4b 100644
--- a/resources/views/docs/mobile/1/getting-started/introduction.md
+++ b/resources/views/docs/mobile/1/getting-started/introduction.md
@@ -5,22 +5,37 @@ order: 001
## Welcome to the revolution!
-NativePHP for Mobile is a first of its kind library that allows PHP developers to run PHP applications natively on
-all sorts of mobile devices _without a web server_.
+NativePHP for Mobile is the first library of its kind that lets you run full PHP applications natively on mobile
+devices — no web server required.
-We've combined the statically compiling PHP as an embeddable C library with the flexibility of Laravel and the rich
-native APIs of each support platform, unlocking the power and convenience of Laravel for building performant, native
-_mobile_ applications using PHP.
+By embedding a statically compiled PHP runtime alongside Laravel, and bridging directly into each platform’s native
+APIs, NativePHP brings the power of modern PHP to truly native mobile apps. Build performant, offline-capable
+experiences using the tools you already know.
**It's never been this easy to build beautiful, local-first apps for iOS and Android.**
+## What makes NativePHP for Mobile special?
+
+- 📱 **Native performance**
+ Your app runs natively through an embedded PHP runtime optimized for each platform.
+- 🔥 **True mobile APIs**
+ Access camera, biometrics, push notifications, and more. One cohesive library that does it all.
+- ⚡ **Laravel powered**
+ Leverage the entire Laravel ecosystem and your existing skillset.
+- 🚫 **No web server required**
+ Your app runs entirely on-device and can operate completely offline-first.
+- 🔄 **Cross platform**
+ Build apps for both iOS and Android from a single codebase.
+
## Old tools, new tricks
-With NativePHP for Mobile, you don't have to learn any new languages or ecosystems. Stop fighting with other package
-managers and build tools. Stay in the comfort of PHP and Composer!
+With NativePHP for Mobile, you don’t need to learn Swift, Kotlin, or anything new.
+No new languages. No unfamiliar build tools. No fighting with Gradle or Xcode.
+
+Just PHP.
-PHP developers all over the world are building incredible mobile experiences with the skills they already possess.
-In just a few hours you can build an app and have it submitted to the app stores for review.
+Developers around the world are using the skills they already have to build and ship real mobile apps — faster than
+ever. In just a few hours, you can go from code to app store submission.
## How does it work?
@@ -28,8 +43,8 @@ On the simplest level:
1. A statically-compiled version of PHP is bundled with your code into a Swift/Kotlin shell application.
2. NativePHP's custom Swift/Kotlin bridges manage the PHP environment, running your PHP code directly.
-3. A custom PHP extension is compiled into PHP, that exposes PHP interfaces to native functions.
-4. Your app renders in a native web view, so you can continue developing your UI the way you're used to.
+3. A custom PHP extension is compiled into PHP, that exposes PHP interfaces to native functions.
+4. Your app renders in a native web view, so you can continue developing your UI the way you're used to.
You simply interact with an easy-to-use set of functions from PHP and everything just works!
@@ -38,16 +53,22 @@ You simply interact with an easy-to-use set of functions from PHP and everything
NativePHP for Mobile is way more than just a web view wrapper for your server-based application. Your application lives
_on device_ and is shipped with each installation.
-Thanks to our custom PHP extension, you can interact with many native APIs today, with more coming each week, including:
+Thanks to our custom PHP extension, you can interact with many native APIs today, with more coming all the time,
+including:
-- Camera & Microphone
-- Biometric ID
-- Vibration
-- Accelerometer, GPS and other sensors
-- Push notifications, native alerts and other native UI elements
+- 📷 Camera & Gallery access
+- 🔐 Biometric authentication (Face ID, Touch ID, Fingerprint)
+- 🔔 Push notifications via APNs (for iOS) or Firebase (both)
+- 💬 Native dialogs & toasts
+- 🔗 Deep links & universal links
+- 📳 Haptic feedback & vibration
+- 🔦 Flashlight control
+- 📤 Native sharing
+- 🔒 Secure storage (Keychain/Keystore)
+- 📍 Location services
You have the full power of PHP and Laravel at your fingertips... literally! And you're not sandboxed into the web view;
-this goes way beyond what's possible with PWAs and WASM without any of the complexity... we've got full-cream PHP ready
-to go!
+this goes way beyond what's possible with PWAs and WASM without any of the complexity... we've got full-cream PHP at
+the ready!
-**What are you waiting for!? [Let's go!](installation)**
+**What are you waiting for!? [Let's go!](quick-start)**
diff --git a/resources/views/docs/mobile/1/getting-started/quick-start.md b/resources/views/docs/mobile/1/getting-started/quick-start.md
new file mode 100644
index 00000000..0e209a59
--- /dev/null
+++ b/resources/views/docs/mobile/1/getting-started/quick-start.md
@@ -0,0 +1,35 @@
+---
+title: Quick Start
+order: 099
+---
+
+## Let's go!
+
+
+
+Get your first mobile app running in minutes:
+
+```bash
+# Install NativePHP for Mobile into a new Laravel app
+composer require nativephp/mobile
+
+# Ready your app to go native
+php artisan native:install
+
+# Run your app on a mobile device
+php artisan native:run
+```
+
+## Need help?
+
+- **Community** - Join our [Discord](/discord) for support and discussions.
+- **Examples** - Check out the [Kitchen Sink demo app](https://play.google.com/store/apps/details?id=com.nativephp.kitchensinkapp)
+ on Android (coming soon to iOS!)
+
+Ready to build your first mobile app with PHP? [Let's get started! 🚀](/docs/mobile/1/getting-started/introduction)
diff --git a/resources/views/docs/mobile/1/getting-started/roadmap.md b/resources/views/docs/mobile/1/getting-started/roadmap.md
index 4899aa01..0991db47 100644
--- a/resources/views/docs/mobile/1/getting-started/roadmap.md
+++ b/resources/views/docs/mobile/1/getting-started/roadmap.md
@@ -1,31 +1,13 @@
---
title: Roadmap
-order: 099
+order: 098
---
-## Current Status
-
-NativePHP for Mobile v1 is here. While we're still in the process of adding more and more
-native API's and other features we believe it's robust enough to build useful applications that can be
-distributed to users.
-
-Presently, NativePHP for Mobile offers the following "native" functionality:
-
-- Vibrate
-- Show Toasts
-- Show Alerts
-- Share
-- Camera
-- Flashlight
-- Biometric ID
-- Push Notifications
-- Deep Links
-- NFC
+NativePHP for Mobile is stable and already deployed in production apps released on the app stores. But it's still early
+days. We haven't yet built interfaces to all of the available mobile APIs.
We're working on adding more and more features, including (in no particular order):
- - Secure Storage
- Microphone access
- - Location
- Bluetooth
- SMS (Android only)
- File picker
@@ -33,7 +15,6 @@ We're working on adding more and more features, including (in no particular orde
- Document scanner
- Background tasks
- Geofencing
- - Native image picker
- Calendar access
- Local notifications, scheduled notifications
- Clipboard API
@@ -45,11 +26,20 @@ We're working on adding more and more features, including (in no particular orde
- Gyroscope
- Accelerometer
- Screen brightness
- - Haptic feedback
+ - More Haptic feedback
- Network info access
- Battery status
- - CPU information
+ - CPU/Device information
- Ads
- In-app billing
- - Splash screen
+
diff --git a/resources/views/docs/mobile/1/getting-started/versioning.md b/resources/views/docs/mobile/1/getting-started/versioning.md
new file mode 100644
index 00000000..13369dc3
--- /dev/null
+++ b/resources/views/docs/mobile/1/getting-started/versioning.md
@@ -0,0 +1,69 @@
+---
+title: Versioning Policy
+order: 50
+---
+
+NativePHP for Mobile follows [semantic versioning](https://semver.org) with a mobile-specific approach that distinguishes between
+Laravel-only changes and native code changes. This ensures predictable updates and optimal compatibility.
+
+Our aim is to limit the amount of work you need to do to get the latest updates and ensure everything works.
+
+We will aim to post update instructions with each release.
+
+## Release types
+
+### Patch releases
+
+Patch releases of `nativephp/mobile` should have **no breaking changes** and **only change Laravel/PHP code**.
+This will typically include bug fixes and dependency updates that don't affect native code.
+
+These releases should be completely compatible with the existing version of your native applications.
+
+This means that you can:
+
+- Safely update via `composer update`.
+- Avoid a complete rebuild (no need to `native:install --force`).
+- Allow for easier app updates avoiding the app stores.
+
+### Minor releases
+
+Minor releases may contain **native code changes**. Respecting semantic versioning, these still should not contain
+breaking changes, but there may be new native APIs, Kotlin/Swift updates, platform-specific features, or native
+dependency changes.
+
+Minor releases will:
+
+- Require a complete rebuild (`php artisan native:install --force`) to work with the latest APIs.
+- Need app store submission for distribution.
+- Include advance notice and migration guides where necessary.
+
+### Major releases
+
+Major releases are reserved for breaking changes. This will usually follow a period of deprecations so that you have
+time to make the necessary changes to your application code.
+
+## Version constraints
+
+We recommend using the [tilde range operator](https://getcomposer.org/doc/articles/versions.md#tilde-version-range-)
+with a full minimum patch release defined in your `composer.json`:
+
+```json
+{
+ "require": {
+ "nativephp/mobile": "~1.1.0"
+ }
+}
+```
+
+This automatically receives patch updates while giving you control over minor releases.
+
+## Your application versioning
+
+Just because we're using semantic versioning for the `nativephp/mobile` package, doesn't mean your app must follow that
+same scheme.
+
+You have complete freedom in versioning your own applications! You may use semantic versioning, codenames,
+date-based versions, or any scheme that works for your project, team or business.
+
+Remember that your app versions are usually public-facing (e.g. in store listings and on-device settings and update
+screens) and can be useful for customers to reference if they need to contact you for help and support.
diff --git a/resources/views/docs/mobile/1/the-basics/_index.md b/resources/views/docs/mobile/1/the-basics/_index.md
index e8a6458a..373920fa 100644
--- a/resources/views/docs/mobile/1/the-basics/_index.md
+++ b/resources/views/docs/mobile/1/the-basics/_index.md
@@ -1,4 +1,4 @@
---
title: The Basics
order: 2
----
+---
\ No newline at end of file
diff --git a/resources/views/docs/mobile/1/the-basics/app-assets.md b/resources/views/docs/mobile/1/the-basics/app-assets.md
deleted file mode 100644
index b8346f00..00000000
--- a/resources/views/docs/mobile/1/the-basics/app-assets.md
+++ /dev/null
@@ -1,69 +0,0 @@
----
-title: App Assets
-order: 200
----
-
-## Customizing Your App Icon
-
-NativePHP makes it easy to apply a custom app icon to your iOS and Android builds.
-
-### Step 1: Provide Your Icon
-
-Place a single high-resolution icon file at: `public/icon.png`
-
-
-### Requirements:
-- Format: PNG
-- Size: 1024 × 1024 pixels
-- Shape: Square
-- Background: Transparent or solid — your choice
-
-Note: This image will be automatically resized for all Android densities and used as the base iOS app icon.
-
----
-
-## Compiling CSS and JavaScript
-
-Your device behaves like a server, so assets must be compiled before deployment.
-
-To ensure your latest styles and JavaScript are included, run: `npm run build` before running: `php artisan native:run`.
-
-If you’ve made changes to your frontend, this step is required to see them reflected in the app.
-
----
-
-## Using the --watch Flag (Experimental)
-
-NativePHP includes an experimental `--watch` flag that enables automatic file syncing while the app is running:
-
-php artisan native:run --watch
-
-This is useful during development for quickly testing changes without rebuilding the entire app.
-
-### Caveats
-
-- This feature is currently best suited for **Blade** and **Livewire** applications.
-- It does **not** currently detect or sync **compiled frontend assets**, such as those built with Vite or used by **Inertia.js**.
-- If you're working with a JavaScript-heavy stack (Vue, React, Inertia), you should continue using `npm run build` before launching the app with `native:run`.
-
-### Recommendation
-
-Use `--watch` when you're iterating on Blade views or Livewire components. For all other use cases, treat this flag as experimental and optional.
-
----
-
-## Optional: Installing with ICU Support
-
-By default, NativePHP installs a smaller PHP runtime without ICU (International Components for Unicode) to keep app size minimal.
-
-If your Laravel app uses features that rely on `intl` (such as number formatting, localized date handling, or advanced string collation), you’ll need ICU support enabled.
-
-To include ICU during installation, select it when running: `php artisan native:install`.
-
-This will install a version of PHP with full ICU support. Note that it increases the PHP binary size significantly (typically from ~16MB to ~44MB).
-
-**Important:** If you plan to use [Filament](https://filamentphp.com/) in your app, you must enable this option. Filament relies on the `intl` extension for formatting and localization features.
-
-
-
-
diff --git a/resources/views/docs/mobile/1/the-basics/app-icon.md b/resources/views/docs/mobile/1/the-basics/app-icon.md
new file mode 100644
index 00000000..f20f4dbe
--- /dev/null
+++ b/resources/views/docs/mobile/1/the-basics/app-icon.md
@@ -0,0 +1,24 @@
+---
+title: App Icons
+order: 300
+---
+
+NativePHP makes it easy to apply a custom app icon to your iOS and Android apps.
+
+## Supply your icon
+
+Place a single high-resolution icon file at: `public/icon.png`.
+
+### Requirements
+- Format: PNG
+- Size: 1024 × 1024 pixels
+- Background: Transparent or solid — your choice
+
+This image will be automatically resized for all Android densities and used as the base iOS app icon.
+You must have the GD extension installed in your development machine's PHP environment for this to work.
+
+
diff --git a/resources/views/docs/mobile/1/the-basics/assets.md b/resources/views/docs/mobile/1/the-basics/assets.md
new file mode 100644
index 00000000..a38f1f76
--- /dev/null
+++ b/resources/views/docs/mobile/1/the-basics/assets.md
@@ -0,0 +1,28 @@
+---
+title: Assets
+order: 500
+---
+
+## Compiling CSS and JavaScript
+
+If you are using React, Vue or another JavaScript library, or Tailwind CSS, tools that requires your frontend to be
+built by build tooling like Vite, you will need to run your build process _before_ compiling the native application.
+
+For example, if you're using Vite with NPM to build a React application that is using Tailwind, to ensure that your
+latest styles and JavaScript are included, always run `npm run build` before running `php artisan native:run`.
+
+## Other files
+
+NativePHP will include all files from the root of your Laravel application. So you can store any files that you wish to
+make available to your application wherever makes the most sense for you.
+
+
diff --git a/resources/views/docs/mobile/1/the-basics/deep-links.md b/resources/views/docs/mobile/1/the-basics/deep-links.md
deleted file mode 100644
index 804bb0b1..00000000
--- a/resources/views/docs/mobile/1/the-basics/deep-links.md
+++ /dev/null
@@ -1,109 +0,0 @@
----
-title: Deep, Universal, App Links and NFC
-order: 500
----
-
-## Overview
-
-NativePHP for Mobile supports both **deep linking** and **web-based linking** into your mobile apps.
-
-There are two types of link integrations you can configure:
-
-- **Deep Links** (myapp://some/path)
-- **Universal Links (iOS)** and **App Links (Android)** (https://example.net/some/path)
-
-Each method has its use case, and NativePHP allows you to configure and handle both easily.
-
----
-
-## Deep Links
-
-Deep links use a **custom URL scheme** to open your app.
-
-For example:
-
-```
-myapp://profile/123
-```
-
-
-When a user taps a deep link, the mobile operating system detects the custom scheme and opens your app directly.
-
-### Configuration
-
-To enable deep linking, you must define:
-
-- **Scheme**: The protocol (e.g., myapp)
-- **Host**: An optional domain-like segment (e.g., open)
-
-These are configured in your .env:
-
-```dotenv
-NATIVEPHP_DEEPLINK_SCHEME=myapp
-NATIVEPHP_DEEPLINK_HOST=open
-```
-
-## Universal Links (iOS) and App Links (Android)
-
-Universal Links and App Links allow real HTTPS URLs to open your app instead of a web browser, if the app is installed.
-
-For example:
-```dotenv
-https://example.net/property/456
-```
-
-When a user taps this link:
-
- - If your app is installed, it opens directly into the app.
- - If not, it opens normally in the browser.
-
-This provides a seamless user experience without needing a custom scheme.
-
-### How It Works
-1. You must prove to iOS and Android that you own the domain by hosting a special file:
- - .well-known/apple-app-site-association (for iOS)
- - .well-known/assetlinks.json (for Android)
-2. The mobile OS reads these files to verify the link association.
-3. Once verified, tapping a real URL will open your app instead of Safari or Chrome.
-
-NativePHP for Mobile handles all of this for you.
-
-### Configuration
-
-To enable Universal Links and App Links, you must define:
-
-- **Host**: The domain name (e.g., example.net)
-
-These are configured in your .env:
-
-```dotenv
-NATIVEPHP_DEEPLINK_HOST=example.net
-```
-
-## Handling Universal/App Links
-
-Once you've configured your deep link settings, you can handle the link in your app.
-
-Simply set up a route in your web.php file and the deeplink will redirect to your route.
-
-```dotenv
-https://example.net/profile/123
-```
-
-```php
-Route::get('/profile/{id}', function ($id) {
- // Handle the deep link
-});
-```
-
-## NFC
-NFC is a technology that allows you to read and write NFC tags.
-
-NativePHP handles NFC tag "bumping" just like a Universal/App Link.
-You can use a tool like [NFC Tools](https://www.wakdev.com/en/) to test write NFC tags.
-
-Set the url to a Universal/App Link and the tag will be written to the NFC tag.
-"Bumping" the tag will open the app.
-
-
-
diff --git a/resources/views/docs/mobile/1/the-basics/dialogs.md b/resources/views/docs/mobile/1/the-basics/dialogs.md
deleted file mode 100644
index 4ccba9c4..00000000
--- a/resources/views/docs/mobile/1/the-basics/dialogs.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-title: Dialogs
-order: 300
----
-
-## Native Dialogs
-
-NativePHP allows you to trigger many native dialogs.
-
-Dialogs are created using the `Dialog` facade.
-
-```php
-use Native\Mobile\Facades\Dialog;
-```
-
-### The Share Dialog
-
-You may open the native share dialog by using the `Dialog::share()` method.
-
-```php
-Dialog::share('Title', 'Description', 'URL');
-```
-
-### The Alert Dialog
-
-You may open a native alert dialog by using the `Dialog::alert()` method.
-
-```php
-Dialog::alert('Title', 'Message');
-```
-
-### The Toast Dialog
-
-You may open a native toast dialog by using the `Dialog::toast()` method. There is not a toast dialog on iOS,
-on iOS we will simply show an Alert Dialog with just an `OK` button.
-
-```php
-Dialog::toast('Message');
-```
diff --git a/resources/views/docs/mobile/1/the-basics/events.md b/resources/views/docs/mobile/1/the-basics/events.md
new file mode 100644
index 00000000..07b7b7ae
--- /dev/null
+++ b/resources/views/docs/mobile/1/the-basics/events.md
@@ -0,0 +1,112 @@
+---
+title: Events
+order: 200
+---
+
+## Overview
+
+Many native mobile operations take time to complete and await user interaction. PHP isn't really set up to handle this
+sort of asynchronous behaviour; it is built to do its work, send a response and move on as quickly as possible.
+
+NativePHP for Mobile smooths over this disparity between the different paradigms using a simple event system that
+handles completion of asynchronous methods using a webhook-/websocket-style approach to notify your Laravel app.
+
+## Understanding Async vs Sync
+
+Not all actions are async. Some methods run immediately, and in some cases return a result straight away.
+
+Here are a few of the **synchronous** APIs:
+
+```php
+Haptics::vibrate();
+System::flashlight();
+Dialog::toast('Hello!');
+```
+Asynchronous actions trigger operations that may complete later. These return immediately, usually with a `bool` or
+`void`, allowing PHP's execution to finish. In many of these cases, the user interacts directly with a native component.
+When the user has completed their task and the native UI is dismissed, the native app
+
+```php
+// These trigger operations and fire events when complete
+Camera::getPhoto(); // → PhotoTaken event
+Biometrics::promptForBiometricID(); // → Completed event
+PushNotifications::enrollForPushNotifications(); // → TokenGenerated event
+```
+
+## Basic Event Structure
+
+All events are standard [Laravel Event classes](https://laravel.com/docs/12.x/events#defining-events). The public
+properties of the events contain the pertinent data coming from the native app side.
+
+## Event Handling
+
+All asynchronous methods follow the same pattern:
+
+1. **Call the method** to trigger the operation.
+2. **Listen for the appropriate events** to handle the result.
+3. **Update your UI** based on the outcome.
+
+All events get sent directly to JavaScript in the web view _and_ to your PHP application via a special route. This
+allows you to listen for these events in the context that best suits your application.
+
+### On the frontend
+
+Events are 'broadcast' to the frontend of your application via the web view through a custom `Native` helper. You can
+easily listen for these events in JavaScript in two ways:
+
+- The `Native.on()` helper
+- Livewire's `#[On()]` attribute
+
+#### The `Native.on()` helper
+
+Register the event listener directly in JavaScript:
+
+```blade
+@@use(Native\Mobile\Events\Alert\ButtonPressed)
+
+
+```
+
+#### Livewire's `#[On()]` attribute
+
+Livewire makes listening to 'broadcast' events simple. Just add the event name, prefixed by `native:` to the `#[On()]`
+attribute attached to the method you want to use as its handler:
+
+```php
+use Native\Mobile\Events\Camera\PhotoTaken;
+
+#[On('native:'.PhotoTaken::class)]
+public function handlePhoto(string $path)
+{
+ // Handle captured photo
+}
+```
+
+### On the backend
+
+You can also listen for these events on the PHP side as they are simultaneously passed to your Laravel application.
+
+Simply [add a listener](https://laravel.com/docs/12.x/events#registering-events-and-listeners) as you normally would:
+
+```php
+use App\Services\APIService;
+use Native\Mobile\Events\Camera\PhotoTaken;
+
+class UpdateAvatar
+{
+ public function __construct(private APIService $api) {}
+
+ public function handle(PhotoTaken $event): void
+ {
+ $imageData = base64_encode(
+ file_get_contents($event->path)
+ );
+
+ $this->api->updateAvatar($imageData);
+ }
+}
+```
diff --git a/resources/views/docs/mobile/1/the-basics/native-functions.md b/resources/views/docs/mobile/1/the-basics/native-functions.md
index 3260b32f..6ff841b1 100644
--- a/resources/views/docs/mobile/1/the-basics/native-functions.md
+++ b/resources/views/docs/mobile/1/the-basics/native-functions.md
@@ -3,68 +3,29 @@ title: Native Functions
order: 100
---
-Nearly any basic Laravel app will work as a mobile app with NativePHP for Mobile. However, what makes NativePHP
-unique is that it allows you to call native functions from your PHP code.
+Our custom PHP extension enables tight integration with each platform, providing a consistent and performant abstraction
+that lets you focus on building your app. Build for both platforms while you develop on one.
-These functions are called from your PHP code using one of an ever-growing list of facades.
+Native device functions are called directly from your PHP code, giving you access to platform-specific features while
+maintaining the productivity and familiarity of Laravel development.
-Currently, there are two facades available:
+These functions are called from your PHP code using an ever-growing list of classes. These classes are also wrapped in
+Laravel Facades for ease of access and testing:
-- `Native\Mobile\Facades\System`
+- `Native\Mobile\Facades\Biometrics`
+- `Native\Mobile\Facades\Camera`
- `Native\Mobile\Facades\Dialog`
+- `Native\Mobile\Facades\Geolocation`
+- `Native\Mobile\Facades\Haptics`
+- `Native\Mobile\Facades\PushNotifications`
+- `Native\Mobile\Facades\SecureStorage`
+- `Native\Mobile\Facades\System`
-## System
-
-The `System` facade is used to call native functions that access system resources.
-
-For example, you may use the `System::camera()` method to request access to the device's camera.
-
-
-## Synchronous vs. Asynchronous Methods
-
-It is important to understand the difference between synchronous and asynchronous methods. Some methods
-like `flashlight` and `vibrate` are synchronous, meaning that they will block the current thread until the
-operation is complete.
-
-Other methods like `camera` and `biometric` are asynchronous, meaning that they
-will return immediately and the operation will be performed in the background. When the operation is
-complete, the method will `broadcast an event` to your frontend via an injected javascript event as well
-as a traditional [Laravel Event](https://laravel.com/docs/12.x/events#main-content) that you can listen for within your app.
-
-In order to receive these events, you must register a listener for the event. For example,
-take a look at how easy it is to listen for a `PhotoTaken` event in Livewire:
-
-```php
-use Livewire\Attributes\On;
-use Livewire\Component;
-use Native\Mobile\Facades\System;
-use Native\Mobile\Events\Camera\PhotoTaken;
-
-class Camera extends Component
-{
- public string $photoDataUrl = '';
-
- public function camera()
- {
- System::camera();
- }
-
- #[On('native:' . PhotoTaken::class)]
- public function handleCamera($path)
- {
- $data = base64_encode(file_get_contents($path));
- $mime = mime_content_type($path);
+
diff --git a/resources/views/docs/mobile/1/the-basics/overview.md b/resources/views/docs/mobile/1/the-basics/overview.md
new file mode 100644
index 00000000..3ef606ce
--- /dev/null
+++ b/resources/views/docs/mobile/1/the-basics/overview.md
@@ -0,0 +1,58 @@
+---
+title: Overview
+order: 50
+---
+
+NativePHP for Mobile is made up of multiple parts:
+
+- A Laravel application (PHP)
+- The `nativephp/mobile` Composer package
+- A custom build of PHP with custom NativePHP extension
+- Native applications (Swift & Kotlin)
+
+## Your Laravel app
+
+You can build your Laravel application just as you normally would, for the most part, sprinkling native functionality
+in where desired by using NativePHP's built-in APIs.
+
+## `nativephp/mobile`
+
+The package is a pretty normal Composer package. It contains the PHP code needed to interface with the NativePHP
+extension, the tools to install and run your applications, and all the code for each native application - iOS and
+Android.
+
+## The PHP builds
+
+When you run the `native:install` Artisan command, the package will fetch the appropriate versions of the custom-built
+PHP binaries.
+
+NativePHP for Mobile currently bundles **PHP 8.4**. You should ensure that your application is built to work with this
+version of PHP.
+
+These custom PHP builds have been compiled specifically to target the mobile platforms and cannot be used in other
+contexts.
+
+They are compiled as embeddable C libraries and embedded _into_ the native application. In this way, PHP doesn't run as
+a separate process/service under a typical web server environment; essentially, the native application itself is
+extended with the capability to execute your PHP code.
+
+Your Laravel application is then executed directly by the native app, using the embedded PHP engine to run the code.
+This runs PHP as close to natively as it can get. It is very fast and efficient on modern hardware.
+
+## The native apps
+
+NativePHP ships one app for iOS and one for Android. When you run the `native:run` Artisan command, your Laravel app is
+packaged up and copied into one of these apps.
+
+To build for both platforms, you must run the `native:run` command twice, targeting each platform.
+
+Each native app "shell" runs a number of steps to prepare the environment each time your application is booted,
+including:
+
+- Checking to see if the bundled version of your Laravel app is newer than the installed version
+ - Installing the newer version if necessary
+- Running migrations
+- Clearing caches
+
+Normally, this process takes just a couple of seconds in normal use. After your app has been updated, it will take a
+few seconds longer.
diff --git a/resources/views/docs/mobile/1/the-basics/splash-screens.md b/resources/views/docs/mobile/1/the-basics/splash-screens.md
new file mode 100644
index 00000000..eedcd1d5
--- /dev/null
+++ b/resources/views/docs/mobile/1/the-basics/splash-screens.md
@@ -0,0 +1,17 @@
+---
+title: Splash Screens
+order: 400
+---
+
+NativePHP makes it easy to add custom splash screens to your iOS and Android apps.
+
+## Supply your Splash Screens
+
+Place the relevant files in the locations specified:
+
+- `public/splash.png` - for the Light Mode splash screen
+- `public/splash-dark.png` - for the Dark Mode splash screen
+
+### Requirements
+- Format: PNG
+- Minimum Size/Ratio: 1080 × 1920 pixels
diff --git a/resources/views/docs/mobile/1/the-basics/system.md b/resources/views/docs/mobile/1/the-basics/system.md
deleted file mode 100644
index 8e87a747..00000000
--- a/resources/views/docs/mobile/1/the-basics/system.md
+++ /dev/null
@@ -1,134 +0,0 @@
----
-title: System
-order: 400
----
-
-## Native System
-
-NativePHP allows you to trigger many native system functions.
-
-System functions are called using the `System` facade.
-
-```php
-use Native\Mobile\Facades\System;
-```
----
-
-# Synchronous Functions
----
-
-### Vibration
-
-You may vibrate the user's device by calling the `vibrate` method:
-
-```php
-System::vibrate()
-```
----
-### Flashlight
-
-You may toggle the device flashlight (on/off) by calling the `flashlight` method:
-
-```php
-System::flashlight()
-```
----
-
-# Asynchronous Functions
----
-
-### Camera
-```php
-Front End Event: `native:Native\Mobile\Events\Camera\PhotoTaken`
-Back End Event: `Native\Mobile\Events\Camera\PhotoTaken`
-```
-
-You may request the native camera interface to take a photograph by calling the `System::camera()` method:
-
-When the user takes a photograph the event is fired with a payload array that contains one item: `path`
-which is a string containing the path to the photo.
-
-```php
-use Native\Mobile\Events\Camera\PhotoTaken;
-
-System::camera();
-
-// Later...
-#[On('native:' . PhotoTaken::class)]
-public function handlePhotoTaken($path)
-{
- $data = base64_encode(file_get_contents($path));
- $mime = mime_content_type($path);
-
- $this->photoDataUrl = "data:$mime;base64,$data";
-}
-```
-
-**Note: The first time your application asks to use the camera, the user will be prompted to grant permission. If they
-decline, triggering the camera API will silently fail.**
-
----
-
-### Push Notifications
-```php
-Front End Event: `native:Native\Mobile\Events\PushNotification\TokenGenerated`
-Back End Event: `Native\Mobile\Events\PushNotification\TokenGenerated`
-```
-Currently, NativePHP uses [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) to send push notifications to your users.
-
-Simply use the `enrollForPushNotifications` method to trigger enrolment. If this is the first time that your app tries
-to enrol this device for push notifications, the user will be presented with a native alert, allowing them to opt-in.
-
-Then use the `getPushNotificationsToken` method to retrieve the token. If enrolment was unsuccessful for some reason,
-this method will return `null`.
-
-```php
-use Native\Mobile\Events\PushNotification\TokenGenerated;
-
-System::enrollForPushNotifications();
-
-// Later...
-#[On('native:' . TokenGenerated::class)]
-public function handlePushNotifications(string $token)
-{
- // Do something with the token...
-}
-```
-Once you have the token, you may use it from your server-based applications to trigger Push Notifications directly to
-your user's device.
-
-> Learn more about [what to do with push tokens here](/docs/mobile/1/digging-deeper/push-notifications).
-
----
-
-### Biometric ID
-```php
-Front End Event: `native:Native\Mobile\Events\Biometric\Completed`
-Back End Event: `Native\Mobile\Events\Biometric\Completed`
-```
-
-For devices that support some form of biometric identification, you can use this to protect and unlock various parts
-of your application.
-
-```php
-use Native\Mobile\Events\Biometric\Completed;
-
-System::promptForBiometricID()
-
-// Later...
-#[On('native:' . Completed::class)]
-public function handleBiometricAuth(boolean $success)
-{
- if ($success) {
- // Do your super secret activity here
- }
-}
-```
-
-Using this, you can gate certain parts of your app, allowing you to offer an extra layer of protection for your user's
-data.
-
-**Note: Despite the name, Biometric identification only gives you *greater confidence* that the person using your app
-is *someone* who has the capacity to unlock the device your app is installed on. It does not allow you to *identify*
-that user or prove that they are willingly taking this action.**
-