Ionic Portals is a supercharged native Web View component for iOS and Android that lets you add web-based experiences to React Native mobile apps. It enables React Native and web teams to better collaborate and bring new and existing web experiences to mobile in a safe, controlled way.
Getting Started
Installation
npm install @ionic/portals-react-native
or
yarn add @ionic/portals-react-native
Usage
Register Portals with your product key:
import { register } from '@ionic/portals-react-native';
register('YOUR_PORTAL_KEY_HERE');
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
// 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!' }}
// 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. 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.
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.
Registration
Ionic Portals for React Native requires a key to use. Once you have integrated Portals into your project, login to your ionic account to get a key. See our doc on how to register for free and get your Portals license key and refer to the usage section on how to add your key to your React Native application.
FAQ
What is the pricing for Portals use?
Portals is free to use in non-production environments. Businesses with more than USD $1 million in annual revenue are required to purchase a license from Ionic before using Portals in production.
Is Portals Open Source?
See our license.
How is Portals Related to Capacitor and Ionic?
Ionic Portals is a solution that lets you add web-based experiences to your native mobile apps. Portals uses Capacitor as a bridge between the native code and the web code to allow for cross-communication between the two layers. Because Portals uses Capacitor under the hood, you are able to use any existing Capacitor Plugins and even most Cordova Plugins while continuing to use your existing native workflow. Portals for React Native brings these capabilities to React Native applications.
Ionic Framework is the open-source mobile app development framework that makes it easy to build top quality native and progressive web apps with web technologies. Your web experiences can be developed with Ionic, but it is not necessary to use Portals.