expo-share-intent

repository·main·Indexed 20 days ago

https://github.com/achorein/expo-share-intent

A high-performance native module for Expo (React Native) that enables apps to receive shared content—including URLs, text, images, videos, and files—from other iOS and Android applications. It provides a useShareIntent hook and ShareIntentProvider for state management and supports integration with Expo Router and React Navigation v6. Note: This package is not compatible with Expo Go and requires a development client.

Tokens
10.2K
Snippets
30
Records
43
Agent score
69%

What's inside expo-share-intent

  1. Handle iOS Custom Views via expo-share-extension

    main

    This project does not support iOS Custom Views (native views in the context of sharing intent). All sharing logic is managed within the main application.

    If your project requires iOS Custom View support, you should:

    1. Disable the iOS configuration of the expo-share-intent plugin in your app.json using disableIOS: true.
    2. Use the expo-share-extension package instead.
    // app.json snippet to disable iOS configuration
    {
      "expo": {
        "plugins": [
          ["expo-share-intent", { "disableIOS": true }]
        ]
      }
    }
  2. Understand the shareIntent data structure

    main

    The shareIntent object contains the data received from the external application. The available properties depend on the type of content shared.

    attributedescriptionexample
    shareIntent.textraw text from text/weburl (iOS) and text/* (Android)"some text", "http://example.com"
    shareIntent.webUrllink extracted from raw textnull, "http://example.com"
    shareIntent.filesarray of files with path, mimeType, fileName, size, and dimensions/duration[{ path: "file:///...", mimeType: "image/jpeg", ... }]
    shareIntent.metaobject containing extra metadata (e.g., title, og:image){ title: "My cool blog article" }
    shareIntent.meta.titleoptional title property (Android or iOS with NSExtensionActivationSupportsWebPageWithMaxCount)My cool blog article
    shareIntent.meta.xxxlist of webpage metadata from <meta> tags (iOS only, requires NSExtensionActivationSupportsWebPageWithMaxCount)
  3. Integrate with React Navigation v6

    main

    To handle share intents with React Navigation v6, you must:

    1. Use the ShareIntentProvider in your component tree.
    2. Add a custom mapping function to your linking configuration.

    Refer to the example/react-navigation directory in the repository for a complete implementation.

  4. Build your development client

    main

    Because this package uses native modules, you must run a prebuild and then execute the native run commands to generate the development client. You cannot use Expo Go.

    expo prebuild --no-install --clean
    expo run:ios
    expo run:android
  5. Integrate with Expo Router

    main
    When using expo-router, you must handle loading elements within your Layout component. This is the only way to correctly call the native module using a deep link URL. Refer to the example/expo-router directory in the repository for a complete implementation.
  6. Install expo-share-intent

    main

    To use expo-share-intent in your project, install the npm package and ensure you have expo-linking installed (required for Expo SDK 52+).

    Note: This package is not compatible with Expo Go; you must use a development client.

    yarn add expo-share-intent
    # or
    npm install expo-share-intent
    
    # Required for Expo SDK 52+
    expo install expo-linking
  7. Configure expo-share-intent in app.json

    main

    To enable the native module, you must add the expo-share-intent plugin to your app.json or app.config.js file. You should also define a custom scheme to allow the OS to redirect users to your application.

    By default, only text and URL sharing are activated.

    {
      "scheme": "my-app",
      "plugins": [
        "expo-share-intent"
      ]
    }
  8. Requirement: patch-package (for Expo SDK < 55)

    main

    If you are using an older version of the package (up to version 5.0, which corresponds to Expo SDK versions below 55), you must use patch-package to apply an Xcode patch.

    1. Install patch-package: yarn add patch-package.
    2. Copy the required Xcode patch into your project's patches directory.
    3. Add a postinstall script to your package.json:
    "scripts": {
      "postinstall": "patch-package"
    }
  9. Use a Custom Dev Client instead of Expo Go

    main

    Because expo-share-intent uses native code, it is not compatible with Expo Go. You must use a custom development client.

    To test in a simulator, use the following workflow instead of expo start --ios:

    1. Run expo prebuild --no-install.
    2. Run expo run:ios (or expo run:android).

    Note: Do not commit your ios/ or android/ folders to version control; rebuild them before running an EAS build.

    Tip: If you need to test other features of your app in Expo Go without the share intent functionality, you can temporarily disable the native module by calling useShareIntent({ disabled: true }).

    // Disable native module to allow testing in Expo Go
    useShareIntent({ disabled: true });
  10. Customize Webpage Data Extraction with `preprocessorInjectJS`

    main

    The plugin generates a ShareExtensionPreprocessor.js file that runs in the iOS Share Extension context. By default, it extracts the document title and all <meta> tag contents.

    You can inject custom JavaScript via the preprocessorInjectJS parameter to scrape additional data from the webpage. The injected code runs within the run({ completionFunction }) method. The completionFunction is then called with the extracted data.

    Example of what the generated preprocessor looks like:

    class ShareExtensionPreprocessor {
      run({ completionFunction }) {
        const metas = {
          title: document.title,
        };
    
        const metaElements = document.querySelectorAll("meta");
        for (const meta of metaElements) {
          const name = meta.getAttribute("name") || meta.getAttribute("property");
          const content = meta.getAttribute("content");
          if (name && content) {
            metas[name] = content;
          }
        }
    
        // YOUR INJECTED CODE GOES HERE
    
        completionFunction({
          baseURI: document.baseURI,
          meta: JSON.stringify(metas),
        });
      }
    }
    var ExtensionPreprocessingJS = new ShareExtensionPreprocessor();
  11. Configure content types in app.json

    main

    You can customize which content types your app accepts by configuring the expo-share-intent plugin in your app.json. This is necessary to define iOS activation rules and Android intent filters.

    {
      "plugins": [
        [
          "expo-share-intent",
          {
            "iosActivationRules": {
              "NSExtensionActivationSupportsWebURLWithMaxCount": 1,
              "NSExtensionActivationSupportsWebPageWithMaxCount": 1,
              "NSExtensionActivationSupportsImageWithMaxCount": 1,
              "NSExtensionActivationSupportsMovieWithMaxCount": 1
            },
            "androidIntentFilters": ["text/*", "image/*"]
          }
        ]
      ]
    }
      "plugins": [
          [
            "expo-share-intent",
            {
              "iosActivationRules": {
                "NSExtensionActivationSupportsWebURLWithMaxCount": 1,
                "NSExtensionActivationSupportsWebPageWithMaxCount": 1,
                "NSExtensionActivationSupportsImageWithMaxCount": 1,
                "NSExtensionActivationSupportsMovieWithMaxCount": 1,
              },
              "androidIntentFilters": ["text/*", "image/*"]
            }
          ],
      ],