Share Target

Your app in the share sheet.

Android
$ composer require all1web/nativephp-share-target
Share Target — Your app in the share sheet.

Your app appears in the OS share sheet and receives shared text, URLs and images straight into PHP.

  • Links, text, photos, videos and PDFs arrive as PHP objects
  • A native inbox buffers shares until your app reads them
  • ShareTarget::fake() with fluent queueUrl() for tests

Documentation

Synced from GitHub 0 seconds ago

📥 nativephp-share-target

Let people share into your app.

Share anything from any app straight into your Laravel code

When someone finds a link, a photo, or a piece of text anywhere on their phone and taps Share, your app is right there in the list. One tap later it's in your Laravel code, ready to save. You never write a line of native code — the plugin handles the Kotlin and Swift side for you.

User shares → native inbox → plain PHP → saved

Don't confuse this with outbound sharing. Sending content out of an app is the easy direction — one call with nativephp/mobile-share, and even a plain web page can do it with navigator.share(). Receiving is the hard direction: being listed as a share destination is an OS-level capability reserved for native apps — no WebView, no HTML API, and no PWA on iOS can put your app in that list. This plugin is that capability, delivered straight to your Laravel code. It's the only inbound share plugin in the NativePHP ecosystem.


✨ What you get

  • 📲 Your app in the Android share sheet for links, text, photos, videos, and PDFs — including multi-item shares.
  • 🐘 Everything arrives as simple PHP objects. Ask for waiting shares, get back tidy items that already know whether they're a URL, text, an image, or a file.
  • 🔒 Nothing gets lost. If your app wasn't running when the user shared, the share waits safely and is there the moment your app opens.
  • A heads-up event when a share arrives while your app is open, so you can react instantly.
  • 🍏 iOS support (beta) through a one-tap companion Shortcut — see iOS below.
  • 🧪 First-class testing: ShareTarget::fake() with fluent queueUrl() / queueImage() builders and assertions, so your test suite never needs a device.
  • Native save confirmation card (Android): a "Saved ✓" card with content preview and Open/Undo floats over the app the user shared from — they never lose their place. Or go full-quiet with:
  • 🤫 Silent capture mode: never pull users out of the app they're sharing from — store the share, confirm with a native "Saved ✓" toast, done. The classic read-it-later flow, one config line.
  • 🩺 php artisan share-target:doctor — diagnoses your whole setup (registration, native builds, bridge, config) and tells you the exact command that fixes whatever's wrong.

🚀 On the roadmap (v0.3 — in active development)

  • 🎯 Direct Share destinations: your app's notebooks, projects, or inboxes appear in the top ranked row of the Android share sheet with their own icons — one tap lands content in that exact destination, and ranking improves automatically with use.
  • 🗣️ Zero-setup Siri: "Hey Siri, save this to Reading List in ‹your app›" works the moment the app installs — every destination becomes its own Siri phrase, Spotlight action, and Action-button candidate.
  • Native save confirmations on iOS: the same floating "Saved ✓" card experience, rendered by Siri/Shortcuts, with a destination prompt when needed. (Android already has it — see above.)
  • 📋 Clipboard capture: silent copied-link detection plus Apple's own Paste button — no scary "pasted from Safari" alerts — feeding the same inbox as the share sheet.
  • 🛡️ Hardened receive pipeline: ClipData-only senders, split-screen shares, and every Android 12+ edge case handled out of the box.

📦 Install

After purchasing, connect Composer to the NativePHP plugin marketplace (your credentials are on your Purchased Plugins dashboard), then:

composer config repositories.nativephp-plugins composer https://plugins.nativephp.com
composer config http-basic.plugins.nativephp.com your-email@example.com your-license-key
composer require all1web/nativephp-share-target

Register the plugin (NativePHP plugins are opt-in for security) and rebuild:

php artisan native:plugin:register all1web/nativephp-share-target
php artisan native:install android --force
php artisan native:run android

The rebuild matters: Android decides which apps appear in the share sheet when the app is installed, so your app shows up only after this rebuild — not just a re-run of an old build.

# Early access via GitHub (licensees with repo access):
composer config repositories.share-target vcs https://github.com/all1web/nativephp-share-target
composer require "all1web/nativephp-share-target:dev-main"

# Local checkout (plugin development):
composer config repositories.share-target path ../nativephp-share-target
composer require "all1web/nativephp-share-target:*@dev"

🧑‍💻 Use it

Grab whatever's been shared — for example when a screen loads:

use All1web\ShareTarget\Facades\ShareTarget;

foreach (ShareTarget::pending() as $item) {
    match ($item->type()) {
        'url'   => $this->saveLink($item->firstUrl()),
        'text'  => $this->saveNote($item->text),
        default => $this->saveFiles($item->filePaths()),   // images & files
    };
}

That's genuinely the whole integration. Out of the box the plugin also drains and logs shares automatically on every request, so you can see it working before you write any code. (Draining it yourself, like the example above, is for when you turn that auto-drain off — one env line, SHARE_TARGET_AUTO_DRAIN=false; the Reference explains the one-drain-owner rule.)

Want to react the instant a share arrives, route shares into your own handler class, or open a beautiful pre-filled "save this?" screen? It's all supported:

Using JavaScript instead? (Inertia / Vue / React)

The same API ships as a JS module — alias it in Vite and pull shares straight from your components:

// vite.config.js → resolve.alias:
// '@share-target': '/vendor/all1web/nativephp-share-target/resources/js/shareTarget.js'
import shareTarget from '@share-target';

const items = await shareTarget.pending();   // requires SHARE_TARGET_AUTO_DRAIN=false
document.addEventListener('native-event', (e) => {
  if (e.detail.event.endsWith('ShareReceived')) refreshInbox();
});

Full per-stack snippets (Livewire v3/v4, Vue, React, vanilla): Reference → Per-stack usage.

  • Reference — the full API, events, and configuration.
  • Seamless capture guide — the step-by-step recipe for "share → app opens straight into a pre-filled capture screen."

🍏 iOS

Works via a companion Shortcut your users add with one tap (beta). Shared links, text, images, and files land in the exact same place as on Android — your PHP code doesn't change at all, and there's zero iOS configuration.

Worth knowing up front: the entry lands in the share sheet's actions list rather than the top app-icon row, and each user adds it once (the setup guide covers pinning it for quick access). A fully native Share Extension — app-icon row, no setup at all — is on the roadmap, waiting on upcoming NativePHP platform support. When it arrives, your PHP still doesn't change.

The complete iOS setup guide ships with the plugin: docs/IOS-SHARE-SHEET.md.


📋 Requirements

  • NativePHP Mobile ^3.0 || ^4.0
  • Android 8.0+ (minSdk 26) · iOS 18.2+
  • No runtime permissions needed

Same platform floors as nativephp/mobile-share, so the pair install together cleanly. Version-pinning details: Reference.


🔬 Digging deeper

Doc What's in it
Reference Full API, events, config, MIME types, backend forwarding
Seamless capture Share → pre-filled capture screen, end to end
iOS setup Building & distributing the companion Shortcut
Store review & cloud builds What Apple/Google review sees (nothing), Bifrost readiness
Design notes Architecture and the reasoning behind it
Changelog Version history

🛠️ Development

composer install
composer test

🔍 Under the hood

The fine print — everything below is why the three lines of PHP above just work.

⚙️ Engineering you don't have to think about: a strict one-drain-owner architecture makes double-consumption of shares impossible by design (middleware, your code, or JS — exactly one owner, enforced by config). Hardened intent parsing handles ClipData-only senders, multi-item shares, EXTRA_TITLE/EXTRA_SUBJECT variants, split-screen shares, and Android 12+ export rules. The share activity uses singleTop launch mode so the sending app's back stack is never hijacked. Files are copied to app-private storage the instant they arrive — before the OS revokes the sender's URI grant.

🧪 Verified, not vibes: 42 automated tests pin the manifest, config, normalization, testing-fake, and iOS contracts. The share pipeline is verified on physical hardware — warm-app and cold-launch delivery both — and the iOS App Intent code was reviewed line-by-line against current Apple documentation (Swift-6-safe, iOS 26 share-sheet changes accounted for). php artisan share-target:doctor re-verifies your whole setup any time.

🔧 We fix what we find: physical-device testing surfaced two underlying platform issues any NativePHP app can hit (a rare cold-boot crash on fast app-switching; a crash serving raw binary from on-device routes). Both have verified fixes in hand and are being reported upstream — with workarounds documented in docs/PLATFORM-NOTES.md so you never debug them yourself.

🏪 Review-proof by design: zero runtime permissions, zero usage-description strings, no private APIs, no extra build targets, no signing changes — invisible to Apple/Google review and safe in any cloud build pipeline. Details: docs/STORE-REVIEW.md. Your AI pair-programmer gets first-class knowledge too: Laravel Boost guidelines ship in the box.

📜 License

Commercial. Distributed as a paid plugin via the NativePHP Plugin Marketplace; each purchase grants a license key used for Composer authentication. Licensed by ALL 1, a Wyoming corporation. Source access is included for your own development; redistribution of source is not — see LICENSE for the full EULA.