This project demonstrates a functional share intent in an Expo (React Native) project. It allows to use Expo's auto-configuration for the react-native-receive-sharing-intent
package.
This demo works with Expo SDK 48. Is compatible with Android and iOS and support URL, text, images, videos and files sharing.
More Demo :
- Expo 46 available here (compatible iOS 12.4)
- Expo 47 available here
- Expo 49 available here (or with expo-router)
yarn install
yarn prebuild
yarn ios
yarn android
We're using and tweaking two awesome projects:
And to make life easier, we've got patch-package doing the heavy lifting for patching. Check out the "patches" directory for details.
Thanks to the expo-config-plugin-ios-share-extension
package, manual configuration, as described in the original documentation, is not needed.
Simply choose content types you need :
"plugins": [
[
"expo-config-plugin-ios-share-extension",
{
"activationRules": {
"NSExtensionActivationSupportsText": true,
"NSExtensionActivationSupportsWebURLWithMaxCount": 1,
"NSExtensionActivationSupportsWebPageWithMaxCount": 1,
"NSExtensionActivationSupportsImageWithMaxCount": 1,
"NSExtensionActivationSupportsMovieWithMaxCount": 1,
}
}
],
],
Option | Values |
---|---|
activationRules | Allow text sharing with "NSExtensionActivationSupportsText": true Url sharing with "NSExtensionActivationSupportsWebURLWithMaxCount": 1 and "NSExtensionActivationSupportsWebPageWithMaxCount": 1 Images sharing with "NSExtensionActivationSupportsImageWithMaxCount": 1 Videos sharing with "NSExtensionActivationSupportsImageWithMaxCount": 1 default value: { "NSExtensionActivationSupportsWebURLWithMaxCount": 1, "NSExtensionActivationSupportsWebPageWithMaxCount": 1 }" |
WIP: There's a matching PR for "expo-config-plugin-ios-share-extension"
For Android, a config plugin has been added (see plugins/withAndroidShareExtension
directory) to add missing elements and automate the steps from the documentation.
Simply choose content types you need :
"plugins": [
[
"./plugins/withAndroidShareExtension/index",
{
"androidIntentFilters": [
"text/*",
"image/*",
"video/*"
],
}
],
],
Option | Values |
---|---|
androidIntentFilters | array of MIME types :"text/*" / "image/*" / "video/*" / "*/*" default value: ["text/*"] (text and url) |
androidMainActivityAttributes | default value: { "android:launchMode": "singleTask" } |
androidExtraBuildProperties | https://docs.expo.dev/versions/latest/sdk/build-properties/#pluginconfigtypeandroid example: { "targetSdkVersion": 33 } , default value: {} |
With expo-router
you need to handle loading elements on Layout. It's the only way to call the native module using deeplink url (useShareIntent hook).
An example is available with Expo Router v2 on branch expo49-expo-router
If you want to handle share intent with react-navigation (v6), you could add a custom mapping function in our linking configuration like this :
// see: https://reactnavigation.org/docs/configuring-links/#advanced-cases
getStateFromPath(path, config) {
if (path?.includes(`dataurl=${Constants.expoConfig.scheme}sharekey`)) {
return {
routes: [{ name: 'HomeStackScreen', params: { screen: 'ShareIntentScreen' } }],
};
}
return getStateFromPath(path, config);
},
When building on EAS you should only have one extension target (during credentials setting process).
To avoid expo auto configuration to add an experimental "appExtensions" to app.json
you must manually configure your eas build (projectId in app.json
and a eas.json
file).
More details in #1
We are using native code to make share intent works, so we can't use Expo Go and have to use a custom dev client, that's why the demo use expo prebuild --no-install
command and then expo run:ios
, instead of a simple expo start --ios
-> More information here
That way you can test your share intent into simulator, but that does not exempt you to test a complete build on device at the end of your development process to make sure all works as excepted.
NB: don't commit your ios/ and android/ folder, rebuild it before EAS build.
This project does not support iOS custom view (native view in share intent context). Everything must be handle into React Native code.
Enjoying this project? Wanna show some love? Drop a star and consider buying me a coffee to keep me fueled and motivated