Migration Steps

Use these steps to migrate your app from the Engagement-specific React Native plugin to the React Native unified plugins.

Swap Dependencies 

  1. Remove the Marketing Cloud Engagement-specific package.
Remove Engagement-specific package
1yarn remove react-native-marketingcloudsdk
  1. Add the unified product package.
Add unified product package
1yarn add @sfmc/react-native-marketingcloudsdk
  1. To use the push or IAM feature packages, add them to your configuration.
Add optional feature packages
1yarn add @sfmc/react-native-push
2yarn add @sfmc/react-native-iam
  1. Reinstall iOS pods.
Reinstall iOS pods
1cd ios
2pod install

Update the Initialization Model 

  1. Replace static MCReactModule usage with module initialization through requestSdk().
  2. Initialize required modules at app startup and reuse those instances.
Initialize unified modules
1import { SFMCSdkModule } from '@sfmc/react-native-sfmc-core';
2import { PushModule } from '@sfmc/react-native-push';
3import { MCModule } from '@sfmc/react-native-marketingcloudsdk';
4
5const [sfmc, push, mc] = await Promise.all([
6  SFMCSdkModule.requestSdk(),
7  PushModule.requestSdk(),
8  MCModule.requestSdk(),
9]);

requestSdk() caches the initialized SDK instance, so calling it again returns the same module instance.

Migrate JavaScript and TypeScript Call Sites 

  1. Update method calls based on module ownership and method renames.
Engagement-specific React Native usageReact Native unified plugin usageModule
setContactKey, getContactKeysetProfileId, getProfileIdSFMCSdkModule
setAttribute, getAttributes, tracksame methods (moved)SFMCSdkModule
getSystemTokengetPushTokenPushModule
getMessages, setMessageRead, deleteMessagegetAllMessages, markMessageRead, markMessageDeletedMCModule
tags, analytics, registrationmodule-specific methodsMCModule
  1. Find references to previous plugin call sites and update them.
Find previous call sites
1rg "MCReactModule\\."
2rg "setContactKey|getContactKey|getSystemToken|setMessageRead|deleteMessage"
  1. Apply essential method renames:
  • getSystemToken -> getPushToken
  • setMessageRead -> markMessageRead
  • deleteMessage -> markMessageDeleted
  1. Apply these additional required call-site updates:
  • Replace analytics boolean setters with explicit methods:
    • setAnalyticsEnabled(true|false) -> enableAnalytics() / disableAnalytics()
    • setPiAnalyticsEnabled(true|false) -> enablePiAnalytics() / disablePiAnalytics()
  • Replace identity APIs:
    • setContactKey / getContactKey -> setProfileId / getProfileId
  • Update logging and SDK state handling:
    • enableLogging / disableLogging -> setLogging('DEBUG'|'NONE') (or module-specific logging APIs)
    • logSdkState() -> getSdkState() and log the returned object in your app.

Migrate the Event Model 

  1. Replace event classes from the previous plugin with unified event objects that use objType.
Migrate event tracking
1// Previous Plugin
2// MCReactModule.track(new CustomEvent('Purchase', { Total: 1234 }));
3
4// Unified
5sfmc.track({ objType: 'CustomEvent', name: 'Purchase', attributes: { Total: 1234 } });
  1. Validate event attribute value types. Unified event attributes supports these value types:
  • string
  • number
  • boolean
  1. Convert unsupported payload values from the previous plugin before tracking.

If payload from the previous plugin contain nested objects, arrays, or null, convert them to supported value types.

  1. Remove unsupported event patterns from the previous plugin:
  • IdentityEvent has no direct equivalent in the unified model. Use core identity APIs instead.
  • CustomEvent category argument is not supported in unified event objects.

Migrate Event Listeners 

  1. Move listener logic to module emitters.
Module event subscriptions
1import { MCModule } from '@sfmc/react-native-marketingcloudsdk';
2import { PushModule } from '@sfmc/react-native-push';
3import { IamModule, IamEvent } from '@sfmc/react-native-iam';
4
5// Engagement registration changes:
6const regSub = MCModule.getEmitter().addListener('sfmc_mc_registration', (reg) => {
7  console.log('registration', reg);
8});
9
10// Push token refresh (Android):
11const tokenSub = PushModule.getEmitter().addListener('sfmc_push_token_refreshed', (token) => {
12  console.log('new token', token);
13});
14
15// In-App Messaging lifecycle:
16const willShow = IamModule.getEmitter().addListener(IamEvent.WillShowMessage, (msg) => { /* ... */ });
17const didShow  = IamModule.getEmitter().addListener(IamEvent.DidShowMessage,  (msg) => { /* ... */ });
18const didClose = IamModule.getEmitter().addListener(IamEvent.DidCloseMessage, (msg) => { /* ... */ });
19
20// Always remove listeners on unmount:
21regSub.remove(); tokenSub.remove(); willShow.remove(); didShow.remove(); didClose.remove();
  1. Enable registration callback before subscribing.

Call setRegistrationCallback() before subscribing to registration events.

  1. Apply platform listener caveats:
  • IAM event constants are exported via IamEvent.
  • Engagement and push event names are subscribed using string event names.
  • Push token refresh listener is Android-only.
  • Inbox response listener behavior differs by platform; validate behavior on both Android and iOS.
  1. (Optional) Gate whether an in-app message displays.

Use this only if your app needs to allow or suppress in-app messages based on runtime logic.

In-app message decision handler
1IamModule.setInAppMessageDecisionHandler((message) => {
2  // return (or resolve) true to display, false to suppress
3  return message.title !== 'Suppress me';
4});
5
6// Clear the handler (restore default "always show"):
7IamModule.setInAppMessageDecisionHandler(null);

Update Native Configuration (Android and iOS) 

  1. Update both native platforms to the module-based unified configuration model.
  • Android: migrate MainApplication.kt setup to module-based config blocks. For more information about Android configuration, see Integrate the Android SDK.
  • iOS: migrate AppDelegate.swift setup to module-based config blocks. For more information about iOS configuration, see Integrate the iOS SDK.
  • Reapply existing notification, URL-handling, and delegate customization in the new module configuration.
  1. Update Android native initialization using module-based configuration.
MainApplication.kt
1import com.salesforce.marketingcloud.MarketingCloudConfig
2import com.salesforce.marketingcloud.pushfeature.config.PushFeatureConfig
3import com.salesforce.marketingcloud.inappmessagingfeature.config.InAppMessagingFeatureConfig
4import com.salesforce.marketingcloud.sfmcsdk.SFMCSdk
5import com.salesforce.marketingcloud.sfmcsdk.SFMCSdkModuleConfig
6
7SFMCSdk.configure(this, SFMCSdkModuleConfig.build {
8    engagementModuleConfig = MarketingCloudConfig.builder()
9        .setApplicationId(BuildConfig.MC_APP_ID)
10        .setAccessToken(BuildConfig.MC_ACCESS_TOKEN)
11        .setMarketingCloudServerUrl(BuildConfig.MC_SERVER_URL)
12        .setMid(BuildConfig.MC_MID)
13        .setInboxEnabled(true)
14        .build(this@MainApplication)
15
16    pushFeatureModuleConfig = PushFeatureConfig.builder()
17        .setNotificationCustomizationOptions(/* your notification options */)
18        .setUrlHandler(/* your UrlHandler */)
19        .setShouldShowNotificationListener(/* your ShouldShowNotificationListener */)
20        .build()
21
22    inAppMessagingFeatureModuleConfig = InAppMessagingFeatureConfig.builder()
23        .setUrlHandler(/* your UrlHandler */)
24        .build()
25}) { initStatus ->
26    Log.i("SFMC", "SFMC SDK initialization status: $initStatus")
27}
  1. Update iOS native initialization using module-based configuration.
AppDelegate.swift
1import SFMCSDK
2import PushFeatureSDK
3import InAppMessagingFeatureSDK
4import MarketingCloudSDK
5
6var configBuilder = ConfigBuilder()
7
8if let appEndpoint = URL(string: appEndpointURL) {
9    let engagementConfig = MarketingCloudSdkConfigBuilder(appId: appID)
10        .setAccessToken(accessToken)
11        .setMarketingCloudServerUrl(appEndpoint)
12        .setMid(mid)
13        .setInboxEnabled(true)
14        .setLocationEnabled(true)
15        .setAnalyticsEnabled(true)
16        .build()
17    configBuilder = configBuilder.setEngagement(config: engagementConfig)
18}
19
20let pushConfig = PushFeatureConfigBuilder()
21    .setApplicationControlsBadging(true)
22    .build()
23configBuilder = configBuilder.setPushFeature(config: pushConfig)
24
25let iamConfig = InAppMessagingFeatureConfigBuilder().build()
26configBuilder = configBuilder.setInAppMessagingFeature(config: iamConfig)
27
28SFMCSdk.initializeSdk(configBuilder.build()) { status in
29    // inspect [ModuleInitStatus] per module
30}
  1. Verify mandatory platform configuration requirements.
  • React Native New Architecture is enabled.
  • Android build minimums match the required versions. For example, minSdk and compileSdk.
  • Android 13+ push permission (POST_NOTIFICATIONS) is requested for push flows.
  • iOS deployment target and Xcode minimums match the unified plugin requirements.
  • Keep all existing notification, URL-handling, and delegate forwarding logic when porting to module-based initialization.

For more information, see Prerequisites.

  1. Find native initialization files and verify your final setup.
Find native initialization files
1rg "SFMCSdk|MarketingCloudConfig|ConfigBuilder" android ios

See Also 

Migration Checklist.