Skip to content

Commit 9ba4156

Browse files
authored
fix: resolve 101/150 errors by aligning WebView baseUrl and IFrame origin in inline mode (#74)
- Set baseUrl to the default `https://localhost/` for inline WebView - Default playerVars.origin to `https://localhost` in inline WebView - Wrap certain dev logs with DEV so they only run in development - Add TSDoc for playerVars.origin and webViewUrl props
1 parent 56d8d68 commit 9ba4156

File tree

7 files changed

+36
-11
lines changed

7 files changed

+36
-11
lines changed

.changeset/cool-pets-do.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"react-native-youtube-bridge": patch
3+
"@react-native-youtube-bridge/core": patch
4+
---
5+
6+
fix: resolve 101/150 errors by aligning WebView baseUrl and IFrame origin in inline mode
7+
8+
- Set baseUrl to the default `https://localhost/` for inline WebView
9+
- Default playerVars.origin to `https://localhost` in inline WebView
10+
- Wrap certain dev logs with DEV so they only run in development
11+
- Add TSDoc for playerVars.origin and webViewUrl props

example/src/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,10 @@ function App() {
293293
</TouchableOpacity>
294294

295295
<TouchableOpacity
296-
style={[styles.videoButton, videoId === 'fJ9rUzIMcZQ' && styles.activeVideoButton]}
297-
onPress={() => setVideoId('fJ9rUzIMcZQ')}
296+
style={[styles.videoButton, videoId === 'dvgZkm1xWPE' && styles.activeVideoButton]}
297+
onPress={() => setVideoId('dvgZkm1xWPE')}
298298
>
299-
<Text style={styles.videoButtonText}>Bohemian Rhapsody</Text>
299+
<Text style={styles.videoButtonText}>Viva la Vida</Text>
300300
</TouchableOpacity>
301301

302302
<TouchableOpacity

packages/core/src/types/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ export type YoutubePlayerVars = {
166166
rel?: boolean;
167167
/**
168168
* This parameter provides an extra security measure for the IFrame API and is only supported for IFrame embeds.
169+
*
170+
* @remark
171+
* - When `useInlineHtml` is `true` (iOS/Android inline WebView), if not provided, the library defaults this to `https://localhost` and sets the WebView `baseUrl` accordingly so that the document origin and this value match.
172+
* - When `useInlineHtml` is `false` (remote WebView), if not provided, the external page URL defaults to `https://react-native-youtube-bridge.pages.dev` and this value follows that URL. If you pass a custom `webViewUrl` (base URL), `origin` should follow that same origin.
173+
* - In all cases, this value MUST exactly match the document's origin that hosts the iframe for the YouTube IFrame API to function correctly.
169174
*/
170175
origin?: string;
171176
};

packages/react-native-youtube-bridge/src/YoutubeView.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ function YoutubeView({
4040
// biome-ignore lint/correctness/useExhaustiveDependencies: webViewProps.source is intentionally excluded to prevent unnecessary re-renders
4141
const webViewSource = useMemo(() => {
4242
if (useInlineHtml) {
43-
return { html: createPlayerHTML(), ...(webViewBaseUrl ? { baseUrl: webViewBaseUrl } : {}) };
43+
return {
44+
html: createPlayerHTML(),
45+
baseUrl: webViewBaseUrl ?? 'https://localhost/',
46+
};
4447
}
4548

4649
if (webViewUrl) {
@@ -107,7 +110,9 @@ function YoutubeView({
107110
return;
108111
}
109112
} catch (error) {
110-
console.error('Error parsing WebView message:', error);
113+
if (__DEV__) {
114+
console.error('Error parsing WebView message:', error);
115+
}
111116
player.emit('error', { code: 1000, message: 'FAILED_TO_PARSE_WEBVIEW_MESSAGE' });
112117
}
113118
},
@@ -159,12 +164,9 @@ function YoutubeView({
159164
mediaPlaybackRequiresUserAction={false}
160165
originWhitelist={['*']}
161166
style={[styles.webView, webViewStyle]}
162-
// iOS specific props
163167
allowsLinkPreview={false}
164168
dataDetectorTypes={dataDetectorTypes}
165-
// Android specific props
166169
mixedContentMode="compatibility"
167-
thirdPartyCookiesEnabled={false}
168170
webviewDebuggingEnabled={__DEV__}
169171
onShouldStartLoadWithRequest={handleShouldStartLoadWithRequest}
170172
{...webViewProps}
@@ -173,7 +175,9 @@ function YoutubeView({
173175
source={webViewSource}
174176
onMessage={handleMessage}
175177
onError={(error) => {
176-
console.error('WebView error:', error);
178+
if (__DEV__) {
179+
console.error('WebView error:', error);
180+
}
177181
player.emit('error', { code: 1001, message: 'WEBVIEW_LOADING_ERROR' });
178182
}}
179183
/>

packages/react-native-youtube-bridge/src/hooks/useCreateLocalPlayerHtml.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const useCreateLocalPlayerHtml = ({
2525
return '<html><body><div style="width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; color: #fff;">Invalid YouTube ID</div></body></html>';
2626
}
2727

28-
const safeOrigin = escapeHtml(origin);
28+
const safeOrigin = escapeHtml(origin) ?? 'https://localhost';
2929
const safeStartTime = safeNumber(startTime);
3030
const safeEndTime = endTime ? safeNumber(endTime) : undefined;
3131

packages/react-native-youtube-bridge/src/hooks/useYouTubePlayer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ const useYouTubePlayer = (source: YoutubeSource, config?: YoutubePlayerVars): Yo
4040
const isFastRefresh = useRef(false);
4141

4242
const onError = useCallback((error: YoutubeError) => {
43-
console.error('Invalid YouTube source: ', error);
43+
if (__DEV__) {
44+
console.error('Invalid YouTube source: ', error);
45+
}
4446
playerRef.current?.emit('error', error);
4547
}, []);
4648

packages/react-native-youtube-bridge/src/types/youtube.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ export type YoutubeViewProps = {
5454
* The URL for the WebView source.
5555
* @remark
5656
* When `useInlineHtml` is `true`, this value is set as the `baseUrl` for HTML content.
57+
* In this case, the origin of `webViewUrl` MUST match the YouTube IFrame API `origin`
58+
* (e.g. baseUrl `https://localhost/` ⇄ origin `https://localhost`).
59+
*
5760
* When `useInlineHtml` is `false`, this value overrides the default URI for the WebView source (https://react-native-youtube-bridge.pages.dev).
5861
* @platform ios, android
5962
*/

0 commit comments

Comments
 (0)