Skip to content

Expo - React Native

Overview

Getting started for apps that are built with Expo utilizing Continuous Native Generation (CNG) and Prebuild.

If you're not using Expo, CNG and Prebuild, you should follow the React Native docs instead.

Not sure what CNG is? Read more about CNG here.

Installation

  1. Install the SDK

    $ npm install @movable/react-native-sdk
    
  2. iOS - Update your app.json to include the associatedDomains for your MovableInk domain. Also update the infoPlist to include the keys: movable_ink_universal_link_domains, movable_ink_api_key, and movable_ink_region.

    Key Description
    scheme If you don't already have a custom URI scheme for your app, add one here. This is required to support deeplinking - a scheme of myapp would allow links such as myapp://some/path to open your app.
    movable_ink_universal_link_domains The list of MovableInk domains that will open your app. This should match any MovableInk applinks in associatedDomains - Required for using Universal Links | App Links | Deeplinks
    movable_ink_api_key Your MovableInk SDK API Key - Required for using Behavior Events
    movable_ink_region Your MovableInk Region - Required for using Behavior Events
    {
      "expo": {
        "scheme": "myapp",
        "ios": {
          "associatedDomains": [
            "applinks:mi.domain.com"
          ],
          "infoPlist": {
            "movable_ink_universal_link_domains": [
              "mi.domain.com"
            ],
            "movable_ink_api_key": "API KEY",
            "movable_ink_region": "us" // or "eu"
          }
        }
      }
    }
    
  3. Android - Update your app.json to include the intentFilters for your MovableInk domain.

    {
      "expo": {
        "android": {
          "intentFilters": [
            {
              "action": "VIEW",
              "autoVerify": true,
              "data": [
                {
                  "scheme": "https",
                  "host": "mi.domain.com",
                  "pathPrefix": "/p/cpm"
                }
              ],
              "category": ["BROWSABLE", "DEFAULT"]
            },
            {
              "action": "VIEW",
              "data": [
                {
                  "scheme": "https",
                  "host": "mi.domain.com",
                  "pathPrefix": "/p/rpm"
                }
              ],
              "category": ["BROWSABLE", "DEFAULT"]
            },
            {
              "action": "VIEW",
              "data": [
                {
                  "scheme": "https",
                  "host": "mi.domain.com",
                  "pathPrefix": "/p/gom"
                }
              ],
              "category": ["BROWSABLE", "DEFAULT"]
            }
          ]
        }
      }
    }
    

    Make sure to update any instances of mi.domain.com to match your MovableInk domain.

    You'll also need to add a plugin to set your API Key:

    At the root of your project, create a folder called plugins if it doesn't already exist. In that plugins folder, create a file called mi_plugin.js

    .
    |- app/
    |  └─ plugins/
    |      └─ mi_plugin.js
    

    Add the following content:

    // mi_plugin.js
    const { withAndroidManifest, withAppBuildGradle } = require('@expo/config-plugins');
    
    module.exports = function movableInkPlugin(config, data) {
      // Handle AndroidManifest.xml
      config = withAndroidManifest(config, async (config) => {
        let androidManifest = config.modResults.manifest;
    
        // Handle application-level modifications
        if (androidManifest.application && androidManifest.application[0]) {
          const application = androidManifest.application[0];
    
          // Initialize meta-data array if it doesn't exist
          if (!application['meta-data']) {
            application['meta-data'] = [];
          }
    
          // Handle Movable Ink API key
          if (data.movable_ink_android_api_key) {
            application['meta-data'].push({
              $: {
                'android:name': 'com.movableink.inked.API_KEY',
                'android:value': data.movable_ink_android_api_key,
              },
            });
          }
        }
    
        return config;
      });
    
      // Handle build.gradle
      config = withAppBuildGradle(config, (config) => {
        const { modResults } = config;
    
        if (data.movable_ink_android_region) {
          const region = data.movable_ink_android_region.toUpperCase();
    
          // Add buildConfigField to defaultConfig
          const buildConfigField = `buildConfigField("String", "MOVABLE_INK_SDK_REGION", "\\"${region}\\"")`;
    
          // Find defaultConfig block and add the buildConfigField
          if (modResults.contents.includes('defaultConfig {')) {
            modResults.contents = modResults.contents.replace(
              /defaultConfig\s*\{/,
              `defaultConfig {\n        ${buildConfigField}`
            );
          }
        }
    
        return config;
      });
    
      return config;
    };
    

    Update your app.json to include the plugin:

    {
      "expo": {
        "plugins": [
          [
            "./plugins/mi_plugin",
            {
              "movable_ink_android_api_key": "API KEY",
              "movable_ink_android_region": "US" // or "EU"
            }
          ]
        ]
      }
    }
    
  4. Run prebuild

    $ npx expo prebuild
    
  5. Import RNMovableInk in your project and start the SDK as early as possible, such as in your app/_layout.tsx file:

    import RNMovableInk from '@movable/react-native-sdk';
    import { useEffect } from 'react';
    
    ...
    
    export default function RootLayout() {
      const colorScheme = useColorScheme();
    
      useEffect(() => {
        RNMovableInk.start(); 
      }, []);
    
      return (
        ...
      );
    }
    

For detailed information on specific features, please refer to the following sections:

Studio:

DaVinci:

SDK Size

The MovableInk SDK adds approximately 0.5 MB to the compressed app size and 1.8 MB to the uncompressed app size. The "compressed app size" refers to the size of the app when it is packaged and compressed for distribution, such as when it is downloaded. Once downloaded, the app is decompressed and installed on the user's device. The uncompressed size is what actually occupies space on the device.