This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Tutorial: Create a native view
Edit page
A tutorial on creating a native view that renders a WebView with Expo Modules API.
In this tutorial, you'll build an example module with a native view that renders a WebView. For Android, you'll use the WebView component, and for iOS, WKWebView. Web support can be implemented using an iframe and is left as an exercise for you.
1
2
Set up workspace
Clean up the default module to start with a clean slate by deleting the following files:
Locate the following files and replace them with the provided minimal boilerplate:
3
4
Add the system WebView as a subview
Add the system WebView with a hardcoded URL as a subview of ExpoWebView. The ExpoWebView class extends ExpoView, which extends RCTView from React Native, and eventually extends View on Android and UIView on iOS.
Ensure that the WebView subview uses the same layout as ExpoWebView, whose layout is calculated by React Native's layout engine.
Android view
On Android, use LayoutParams to set the WebView's layout to match the ExpoWebView layout. You can do this when you instantiate the WebView.
iOS view
On iOS, set clipsToBounds to true and ensure the WebView's frame matches the bounds of ExpoWebView in layoutSubviews. The init method is called when the view is created, and layoutSubviews is called when the layout changes.
Example app
No changes are required. Rebuild and run the app using the following commands:
After that, you'll see the Expo Modules API overview page rendered. If the changes aren't reflected, try reinstalling the app.
5
Add a prop to set the URL
To set a prop on the view, define the prop name and setter inside ExpoWebViewModule. In this case, you can access the webView property directly for convenience. However, in real-world scenarios, keep the logic inside the ExpoWebView class to minimize how much ExpoWebViewModule knows about its internals.
Use the Prop definition component to define the prop. In the prop setter block, you can access both the view and the prop. Specify that the URL is of type URL — the Expo modules API will convert strings to the native URL type.
Android module
iOS module
TypeScript module
Next, add the url prop to the Props type.
Example app
Finally, pass a URL to your WebView component in the example app.
Rebuild the example app:
After that, you'll see the Expo homepage in the WebView.
6
Add an event to notify when the page has loaded
View callbacks allow developers to listen for events on components. They are typically registered through props on the component, for example: <Image onLoad={...} />. Use the Events definition component to define an event for your WebView. Call it onLoad.
Android view and module
On Android, override the onPageFinished function. Then, call the onLoad event handler that you defined in the module.
Indicate in ExpoWebViewModule that the View has an onLoad event.
iOS view and module
On iOS, implement webView(_:didFinish:) and make ExpoWebView extend WKNavigationDelegate. Then, call onLoad from that delegate method.
Indicate in ExpoWebViewModule that the View has an onLoad event.
TypeScript module
Event payloads are included within the nativeEvent property of the event. To access the url from the onLoad event, read event.nativeEvent.url.
Example app
Update the example app to show an alert when the page has loaded. Copy the following code, then rebuild and run your app, and you'll see the alert!
7
Congratulations! You've created your first Expo module with a native view for Android and iOS.
Next steps
Create native modules using Kotlin and Swift.
A tutorial on creating a native module that persists settings with Expo Modules API.