Skip to content

Instantly share code, notes, and snippets.

@o-az
Created October 23, 2025 11:00
Show Gist options
  • Save o-az/6fdb23a1bf68d24c59f6d3b40829f732 to your computer and use it in GitHub Desktop.
Save o-az/6fdb23a1bf68d24c59f6d3b40829f732 to your computer and use it in GitHub Desktop.
import * as React from 'react'
import { Porto, Mode } from 'porto'
import { WebView } from 'react-native-webview'
const porto = Porto.create({
mode: Mode.reactNative(),
})
const injected = /* javascript */ `
(function () {
const pending = new Map();
let rid = 0;
window.PortoBridge = {
request(method, params) {
return new Promise((resolve, reject) => {
const id = ++rid;
pending.set(id, { resolve, reject });
window.ReactNativeWebView.postMessage(JSON.stringify({ __porto: true, id, method, params }))
})
}
}
document.addEventListener('message', (event) => {
try {
const message = JSON.parse(event.data)
if (!message?.['__porto'] || !message.__porto) return
const promise = pending.get(message.id)
if (!promise) return
pending.delete(message.id)
message?.error ? promise.reject(new Error(message.error)) : promise.resolve(message.result)
} catch {
// handle error
}
})
})()
`
export default function App() {
const ref = React.useRef<WebView>(null)
return (
<WebView
ref={ref}
source={{ uri: 'https://news.kiwistand.com' }}
injectedJavaScriptBeforeContentLoaded={injected}
onMessage={async (event) => {
let message
try {
message = JSON.parse(event.nativeEvent.data)
} catch {
return
}
if (!message?.__porto) return
const { id, method, params } = message
try {
const result = await porto.provider.request({ method, params }) // calls native -> Mode.reactNative
ref.current?.injectJavaScript(
`window.postMessage(${JSON.stringify(JSON.stringify({ __porto: true, id, result }))})`,
)
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
ref.current?.injectJavaScript(
`window.postMessage(${JSON.stringify(JSON.stringify({ __porto: true, error: errorMessage, id }))})`,
)
}
}}
/>
)
}
// wherever you’d normally call Porto provider:
const provider = {
request(method: string, params: any) {
// if true it means we’re inside the RN WebView app -> forward to native
if (window.PortoBridge) {
return window.PortoBridge.request(method, params)
}
// fallback for normal browsers (Porto defined in your site code)
porto.provider.request({ method, params })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment