Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
d55f311
Add share target support for Android
Choochmeque Dec 30, 2025
14c7b38
Fix image preview by enabling asset protocol correctly
Choochmeque Dec 30, 2025
ebaa00b
Add share target support for Android
Choochmeque Dec 30, 2025
bc3932b
Fix image preview by enabling asset protocol correctly
Choochmeque Dec 30, 2025
891fb19
Merge branch 'share-target' of github.com:Choochmeque/tauri-plugin-sh…
Choochmeque Dec 30, 2025
7eb2c11
Fixed formatting
Choochmeque Dec 30, 2025
2ca6042
Added ios extension
Choochmeque Jan 1, 2026
14bf0a9
Added macos xcode project to demo app
Choochmeque Jan 1, 2026
9492f3c
Fix macOS Share Extension image and file handling
Choochmeque Jan 1, 2026
2584028
Add Windows Share Target support for receiving shared content
Choochmeque Jan 3, 2026
9c65685
Update cspell.json
Choochmeque Jan 3, 2026
42af830
Update cspell.json
Choochmeque Jan 3, 2026
8b8edbd
Update documentation
Choochmeque Jan 3, 2026
c077d78
Update build scripts for macos
Choochmeque Jan 4, 2026
a6dc523
Update build scripts for macos
Choochmeque Jan 4, 2026
f80e847
Merge branch 'main' into share-target
Choochmeque Jan 5, 2026
dc1e708
Added windows configuration
Choochmeque Jan 5, 2026
99ad853
Cleanup
Choochmeque Jan 5, 2026
ff74bb2
Merge branch 'main' into share-target
Choochmeque Jan 5, 2026
f5f5085
Fixed clippy warning
Choochmeque Jan 5, 2026
8714cec
Fixed build on windows
Choochmeque Jan 6, 2026
a015673
Fixed build on windows
Choochmeque Jan 6, 2026
a954883
Fixed build on windows
Choochmeque Jan 6, 2026
54f9a58
Fixed build on windows
Choochmeque Jan 6, 2026
9dc8bb9
Fixed build on windows
Choochmeque Jan 6, 2026
3fe74d9
Fixed build on windows
Choochmeque Jan 6, 2026
6f95b52
Fixed build on windows
Choochmeque Jan 6, 2026
6dac590
Fixed clippy warning
Choochmeque Jan 6, 2026
72de8d8
Merge branch 'main' into share-target
Choochmeque Jan 6, 2026
a8729cf
Fixed clippy warning on windows
Choochmeque Jan 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
node-version: "20"
cache: "pnpm"
- run: pnpm install
- run: pnpm run format-check
- run: pnpm run format:check

# Static analyzer.
clippy:
Expand Down Expand Up @@ -79,14 +79,6 @@ jobs:
- run: cargo doc --no-deps -p tauri-plugin-sharekit
- run: cargo deadlinks --no-build

# Check links in markdown files.
mlc:
name: mlc
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: becheran/mlc@v1

# Spellcheck.
spellcheck:
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ node_modules
schema.json
target
**/gen/*
**/.svelte-kit/
18 changes: 17 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ serde_repr = "0.1"
[target.'cfg(target_os = "macos")'.dependencies]
objc2 = "0.6"
objc2-core-foundation = "0.3"
objc2-foundation = { version = "0.3", features = ["NSString"] }
objc2-foundation = { version = "0.3", features = [
"NSString",
"NSBundle",
"NSUserDefaults",
"NSData",
"NSFileManager",
"NSURL",
"NSPathUtilities",
] }
objc2-app-kit = { version = "0.3", features = ["NSSharingService", "NSView", "NSResponder"] }

[target.'cfg(target_os = "windows")'.dependencies]
Expand All @@ -29,10 +37,18 @@ windows = { version = "0.61", features = [
"Foundation",
"Foundation_Collections",
"Storage",
"Storage_FileProperties",
"Storage_Search",
"Storage_Streams",
"Win32_System_WinRT",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
# Share Target support
"ApplicationModel",
"ApplicationModel_Activation",
"ApplicationModel_Core",
"ApplicationModel_DataTransfer_ShareTarget",
"Win32_Storage_Packaging_Appx",
] }
windows-collections = "0.2"

Expand Down
222 changes: 222 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,228 @@ await shareText('Hello!', {
});
```

### Receiving Shared Content (Share Target)

Your app can receive content shared from other apps:

```javascript
import {
getPendingSharedContent,
clearPendingSharedContent,
onSharedContent
} from "@choochmeque/tauri-plugin-sharekit-api";

// Check for shared content on app startup (cold start)
const content = await getPendingSharedContent();
if (content) {
if (content.type === 'text') {
console.log('Received text:', content.text);
} else if (content.type === 'files') {
for (const file of content.files) {
console.log('Received file:', file.name, file.path);
}
}
await clearPendingSharedContent();
}

// Listen for shares while app is running (warm start)
const unlisten = await onSharedContent((content) => {
console.log('Received:', content);
});
```

## Platform Setup

### Android

To receive shared content on Android, add intent filters to your `AndroidManifest.xml`:

`src-tauri/gen/android/app/src/main/AndroidManifest.xml`

Add these intent filters inside your `<activity>` tag:

```xml
<!-- Receive text shares -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>

<!-- Receive image shares -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>

<!-- Receive any file -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>

<!-- Receive multiple files -->
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
```

You can customize the `mimeType` values to only accept specific file types.

### iOS

To receive shared content on iOS, you need to add a Share Extension. Use the `@choochmeque/tauri-apple-extensions` tool after initializing your iOS project:

```bash
# First, initialize the iOS project if you haven't already
tauri ios init

# Then add the Share Extension
npx @choochmeque/tauri-apple-extensions ios add share --plugin @choochmeque/tauri-plugin-sharekit-api
```

The setup tool will:
1. Create a Share Extension target in your Xcode project
2. Configure App Groups for communication between the extension and main app
3. Add a URL scheme for the extension to open your app

**After running the script, you must:**

1. Open the Xcode project (`src-tauri/gen/apple/*.xcodeproj`)
2. Select your Apple Developer Team for both targets:
- Main app target (e.g., `myapp_iOS`)
- Share Extension target (e.g., `myapp-ShareExtension`)
3. Enable the "App Groups" capability for **both** targets in Xcode
4. In Apple Developer Portal, create the App Group (e.g., `group.com.your.app`) and add it to both App IDs

**App Group Configuration:**

The extension and main app communicate via App Groups. The setup script uses `group.{your.bundle.id}` as the App Group identifier. Make sure this is configured in:
- Apple Developer Portal (create the App Group)
- Both App IDs (main app and extension)
- Xcode capabilities for both targets

### macOS

To receive shared content on macOS, you need to add a Share Extension. First, create the macOS Xcode project, then add the extension:

```bash
# First, create the macOS Xcode project
npx @choochmeque/tauri-macos-xcode init

# Then add the Share Extension
npx @choochmeque/tauri-apple-extensions macos add share --plugin @choochmeque/tauri-plugin-sharekit-api
```

The setup tool will:
1. Create a Share Extension target in your Xcode project
2. Configure App Groups for communication between the extension and main app
3. Add a URL scheme for the extension to open your app

**After running the script, you must:**

1. Open the Xcode project (`src-tauri/gen/apple-macos/*.xcodeproj`)
2. Select your Apple Developer Team for both targets:
- Main app target (e.g., `myapp_macOS`)
- Share Extension target (e.g., `myapp-ShareExtension`)
3. Enable the "App Groups" capability for **both** targets in Xcode
4. In Apple Developer Portal, create the App Group (e.g., `group.com.your.app`) and add it to both App IDs

**Development workflow:**

```bash
# Start the dev server and open Xcode
pnpm tauri:macos:dev

# Then press Cmd+R in Xcode to build and run
```

### Windows

To receive shared content on Windows, your app must be packaged as MSIX.

**Requirements:**
- Windows 10 version 2004+ (build 19041)
- MSIX packaging (use [@choochmeque/tauri-windows-bundle](https://github.com/Choochmeque/tauri-windows-bundle))

**Setup:**

1. Initialize Windows bundle (if not already done) and add share target extension:

```bash
npx @choochmeque/tauri-windows-bundle init
npx @choochmeque/tauri-windows-bundle extension add share-target
```

2. Add share target handling to your Tauri setup:

`src-tauri/src/main.rs`

```rust
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_sharekit::init())
.setup(|app| {
#[cfg(target_os = "windows")]
{
use tauri_plugin_sharekit::ShareExt;
if app.share().handle_share_activation()? {
app.handle().exit(0);
}
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```

### Displaying Received Images

To display received images in your app, enable the asset protocol feature and configure the scope.

`src-tauri/Cargo.toml`

```toml
[dependencies]
tauri = { version = "2", features = ["protocol-asset"] }
```

`src-tauri/tauri.conf.json`

```json
{
"app": {
"security": {
"assetProtocol": {
"enable": true,
"scope": [
"$CACHE/**",
"$APPCACHE/**",
"**/Containers/Shared/AppGroup/**"
]
}
}
}
}
```

The `**/Containers/Shared/AppGroup/**` scope is required on iOS to access files shared via the Share Extension (works for both simulator and real devices).

Then in your frontend:

```javascript
import { convertFileSrc } from "@tauri-apps/api/core";

// file.path is from SharedContent.files
const imageUrl = convertFileSrc(file.path);
// Use imageUrl in an <img> tag
```

## Contributing

PRs accepted. Please make sure to read the Contributing Guide before making a pull request.
Expand Down
Loading