Skip to main content

Using Portals in React Native

Once you obtain an API key and install Ionic Portals, you can start creating Portals for your application.

Registering with your Portals Key

import { register } from '@ionic/portals-react-native';

register('YOUR_PORTAL_KEY_HERE');

Creating a Portal and Rendering It

Create a Portal and add it to the portal registry:

import { addPortal } from '@ionic/portals-react-native';
const helloPortal = {
// A unique name to reference later
name: 'hello',
// This is the location of your web bundle relative to the asset directory in Android and Bundle.main in iOS
// This will default to the name of the portal
startDir: 'portals/hello',
// Any initial state to be provided to a Portal if needed
initialContext: {
greeting: 'Hello, world!'
}
};

addPortal(helloPortal);

Create a PortalView in your view hierarchy:

import { PortalView } from '@ionic/portals-react-native';

<PortalView
portal={{
// The name of the portal to be used in the view
name: 'hello',
// Set any initial context you may want to override.
initialContext: {
greeting: 'Goodbye!',
},
}}
name='hello'

// Setting a size is required
style={{ flex: 1, height: 300 }}
/>

iOS Specific Configuration

AppDelegate

Both Capacitor and React Native have classes named AppDelegate. To prevent a clash that can prevent your React Native application from launching, you will need to rename AppDelegate to something else:

// AppDelegate.h
@interface RNAppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
// AppDelegate.m
@implementation RNAppDelegate
@end
// main.m
#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([RNAppDelegate class]));
}
}

Podfile

There are two methods you may use to ensure Portals can integrate into your React Native application: a custom pre_install hook or adding use_frameworks! to your Podfile. Only one of these approaches is needed to ensure that Capacitor is compiled as a dynamic framework.

pre_install

Using the pre_install hook allows you to keep all the other React Native dependencies as static frameworks:

# These frameworks are required to be dynamic. 
dynamic_frameworks = ['Capacitor', 'CapacitorCordova']

pre_install do |installer|
installer.pod_targets.each do |pod|
if dynamic_frameworks.include?(pod.name)
def pod.static_framework?
false
end
def pod.build_type
Pod::BuildType.dynamic_framework
end
end
end
end

use_frameworks

Alternative to the pre_install hook, you can add use_frameworks! to your Podfile application target. This forces all dependencies to be dynamic frameworks. Using this approach requires removing use_flipper!() from the Podfile.

Communicating between React Native and Web

One of the key features of Ionic Portals for React Native is facilitating communication between the web and React Native layers of your application. Publishing a message to the web:

import { publish } from '@ionic/portals-react-native';

publish('topic', { number: 1 })

Subscribe to messages from the web:

import { subscribe } from '@ionic/portals-react-native';

let subscriptionReference = await subscribe('topic', message => {
// Here you have access to:
// message.data - Any data sent from the web
// message.subscriptionRef - The subscription reference used to manage the lifecycle of the subscription
// message.topic - The topic the message was published on
})

When you no longer need to receive events, unsubscribe:

import { unsubscribe } from '@ionic/portals-react-native';

unsubscribe('channel:topic', subscriptionReference)

To see an example of Portals Pub/Sub in action that manages the lifecycle of a subscription with the lifecycle of a React Native component, refer to the PubSubLabel implementation in the example project of the @ionic/portals-react-native source repo.

Using Capacitor Plugins

If you need to use any Capacitor plugins, the classpath of the Android plugins will have to be provided to the Portal androidPlugins property.

const helloPortal = {
name: 'hello',
startDir: 'portals/hello',
androidPlugins: ['com.capacitorjs.plugins.camera.CameraPlugin'],
initialContext: {
greeting: 'Hello, world!'
}
};

No configuration for iOS is needed since plugins are automatically registered when the Capacitor bridge initializes on iOS.

Bundling Your Web Apps

Currently there is no tooling for bundling your web apps directly as part of @ionic/portals-react-native. Please follow the native guides to manage this as part of the native build process.