npm.io
2.1.0 • Published 11h ago

@aspectly/react-native-web

Licence
MIT
Version
2.1.0
Deps
3
Size
36 kB
Vulns
0
Weekly
0

@aspectly/react-native-web

npm version npm downloads

Cross-platform Aspectly bridge integration for React Native Web, Expo, and universal React Native apps.

Installation

# npm
npm install @aspectly/react-native-web

# pnpm
pnpm add @aspectly/react-native-web

# yarn
yarn add @aspectly/react-native-web

For native platforms, you'll also need:

npm install react-native-webview
cd ios && pod install

Overview

@aspectly/react-native-web provides a unified API for embedding web content in universal React Native apps:

  • Web Platform: Uses iframes for embedding
  • iOS/Android: Uses react-native-webview (via @aspectly/react-native)

This package allows you to write one codebase that works seamlessly across all platforms.

Other hosts

The embedded web content (@aspectly/core) speaks the same protocol against every Aspectly host beyond Web/iOS/Android — .NET (CefSharp/WebView2), macOS/visionOS (WebKit), Flutter, and Linux/WebKitGTK — with the transport auto-detected by @aspectly/transports. See the main README for the full host matrix.

Quick Start

import React, { useEffect } from 'react';
import { View, Text, Button, Platform } from 'react-native';
import { useAspectlyWebView } from '@aspectly/react-native-web';

function App() {
  const [bridge, loaded, WebView] = useAspectlyWebView({
    url: 'https://example.com/widget'
  });

  useEffect(() => {
    if (loaded) {
      bridge.init({
        getPlatform: async () => ({
          os: Platform.OS,
          isWeb: Platform.OS === 'web'
        }),
        showMessage: async (params: { text: string }) => {
          alert(params.text);
          return { shown: true };
        }
      });
    }
  }, [loaded, bridge]);

  const handlePress = async () => {
    const result = await bridge.send('greet', { name: 'Universal App' });
    console.log(result);
  };

  return (
    <View style={{ flex: 1 }}>
      <Text>Platform: {Platform.OS}</Text>
      <WebView style={{ flex: 1 }} />
      <Button
        title="Send Message"
        onPress={handlePress}
        disabled={!loaded}
      />
    </View>
  );
}

API Reference

useAspectlyWebView
const [bridge, loaded, WebViewComponent] = useAspectlyWebView(options);
Options
Property Type Required Description
url string Yes URL to load
timeout number No Handler execution timeout in ms (default: 100000)
Returns
Index Type Description
0 BridgeBase Bridge instance for communication
1 boolean Whether the content has loaded
2 FunctionComponent Platform-appropriate component
WebViewComponent Props (Web Platform)
Prop Type Description
style CSSProperties Custom styles
className string CSS class name
title string Accessibility title (default: "Embedded content")
sandbox string iframe sandbox attribute
allow string iframe allow attribute
onError (error: unknown) => void Error handler
WebViewComponent Props (Native Platform)

Accepts all react-native-webview props except source, onMessage, onLoad, and ref.

Platform-Specific Code

The package uses React Native's platform-specific file extensions:

  • index.ts / useAspectlyWebView.tsx - Web platform (iframe)
  • index.native.ts / useAspectlyWebView.native.tsx - iOS/Android (WebView)

This is handled automatically by Metro bundler (React Native) and most web bundlers.

Cross-Platform Patterns

Detecting Platform
import { Platform } from 'react-native';

bridge.init({
  getPlatformInfo: async () => ({
    platform: Platform.OS, // 'web', 'ios', 'android'
    isWeb: Platform.OS === 'web',
    isNative: Platform.OS !== 'web',
  })
});
Conditional Features
bridge.init({
  takePhoto: async () => {
    if (Platform.OS === 'web') {
      // Use file input on web
      return { error: 'Use file picker on web' };
    }
    // Use native camera on iOS/Android
    const result = await ImagePicker.launchCamera();
    return { uri: result.assets[0].uri };
  }
});
Styling Differences
// The component handles platform differences internally
<WebView
  style={{
    flex: 1,
    // These work on both platforms
    width: '100%',
    height: 400,
  }}
/>

Expo Support

This package works great with Expo:

# Install in an Expo project
npx expo install @aspectly/react-native-web react-native-webview

Works automatically with:

  • Expo Go (web only)
  • Expo Dev Client (all platforms)
  • EAS Build (all platforms)

Metro Configuration

For the native platform resolution to work correctly, ensure your metro.config.js supports platform extensions:

// metro.config.js (usually automatic)
const { getDefaultConfig } = require('expo/metro-config');

const config = getDefaultConfig(__dirname);

config.resolver.sourceExts = ['native.tsx', 'native.ts', ...config.resolver.sourceExts];

module.exports = config;

Webpack Configuration (Web)

For web builds, ensure the resolver handles the extensions correctly:

// webpack.config.js
module.exports = {
  resolve: {
    extensions: ['.web.tsx', '.web.ts', '.tsx', '.ts', '.js'],
    alias: {
      'react-native$': 'react-native-web'
    }
  }
};

When to Use Which Package

Package Use Case
@aspectly/react-native-web Universal apps (Expo/RN Web)
@aspectly/react-native Native-only apps
@aspectly/web Web-only apps
@aspectly/core Inside WebViews/iframes

License

MIT

Keywords