[Bug]: Ios Youtube embed player issue - Blocked a frame with origin "ionic://localhost" from accessing a frame with origin "https://www.youtube.com". Protocols must match.
Capacitor Version
Capacitor Version : 6.2.1 Ionic version : 8
Other API Details
Ionic(Angular) capacitor ios
Platforms Affected
- [x] iOS
- [ ] Android
- [ ] Web
Current Behavior
Youtube video player is not playing . I have updated the Youtube IFrame Api implementation too. But Still getting this cors error. Blocked a frame with origin "ionic://localhost" from accessing a frame with origin "https://www.youtube.com". Protocols must match. It happens only on IOS Devices only. In Android Devices , youtube video is playing well.
Expected Behavior
Youtube player should be played without cors error
Project Reproduction
you can check in the latest version of the capacitor
Additional Information
No response
Capacitor 7 is also affected. I'm reproducing this on iOS 18.6.2.
YouTube’s embedding system requires a valid HTTP Referer header to verify the origin of the embed request. In a Capacitor/iOS WebView, no valid Referer is sent with the iframe request, not even "capacitor://localhost"
Error 153: playability error code embedder identity missing referrer
Looks like it's a known bug since July 2020 : #3210
I'm also running into the same issue. Anyone find a workaround?
I was also facing this issue, and the workaround I found was to create a proxy through my website. On the site, I added a route specifically to embed the YouTube video, and then I embed that route from my website within the Capacitor app. This way, the video loads over HTTPS instead of the capacitor:// protocol, which bypasses the YouTube restriction on iOS.
Workaround steps
- Create a route on your website (e.g.
/videoor/embed). - Make that route accept a
?id=parameter for the YouTube video ID. - In that route, generate the YouTube embed iframe using the received ID.
- Allow your Capacitor app domain in the site's CORS or iframe settings.
- In your Capacitor app, embed your site’s route instead of the direct YouTube URL.
I’ve been facing the same issue for the past four days. Does anyone have a workaround or fix for it?
We have the same issue in our app, but we use Cordova instead of Capacitor. I opened an issue in the cordova-plugin-ionic-webview repository: https://github.com/ionic-team/cordova-plugin-ionic-webview/issues/701
I tried modifying the iOS source code to force sending a Referer on each request. Before executing the WebView's loadRequest, I tried to add the Referer to the request as suggested by the Youtube documentation:
[request addValue:@"https://my.test.app" forHTTPHeaderField:@"Referer"];
But inspecting the WebView requests I see that the Referer is still not being sent and Youtube videos don't work.
However, if I force the WebView to load an online URL (the Youtube one) when the app starts instead of a local URL (my app's index.html), then I see that the requests contain the Referer https://my.test.app. So It seems WKWebView is not sending the Referer when using a custom scheme or local file, as it was already mentioned in this issue:
https://github.com/ionic-team/cordova-plugin-ionic-webview/issues/365
I guess this issue should be fixed by Apple, so I also sent a report to Apple using the Feedback Assistant.
In our app we'll probably end up using a proxy as a workaround, similar to what IgorSamer explained in a comment above.
This issue needs more information before it can be addressed. In particular, the reporter needs to provide a minimal sample app that demonstrates the issue. If no sample app is provided within 15 days, the issue will be closed. Please see the Contributing Guide for how to create a Sample App. Thanks! Ionitron 💙
Here is a reproduction - https://github.com/wsamoht/capacitor-youtube-video-error-ios-8205
Reproducing
Run the following:
npm install
ionic cap build ios
Then run in an iOS Simulator and try to play the YT video.
Running with Live Reload works (YouTube doesn't give an error) because the HTTP scheme is http vs. capacitor. This is why I believe Android works too.
Resources
- https://developers.google.com/youtube/terms/required-minimum-functionality
- Mentions how to handle WebViews
- https://developers.google.com/youtube/iframe_api_reference
I am also having the same issue. Is this a bug or is this something that will never be allowed?
This issue is affecting us as well.
Here is another reproduction - https://github.com/madams-cutco/youtube-issue-example
When running on iOS try and play the video and you will see the issue. We are seeing this issued in all of our environments all the way to production.
Hi Folks!... I've followed the same approach suggested by @IgorSamer above to resolve this issue. I used AI to generate the below explanations and example code for better understanding.
I've also encountered this issue when attempting to render a third party web URL as an iframe on iOS devices. This problem arises due to WebView security limitations in iOS platform.
Root Cause: iOS uses a secure WebView that prevents external iframe content from loading Third-party iframe providers will implement domain whitelisting to allow their domains to third-party websites/ apps. These providers check the referrer/origin domain to allow iframe rendering Since iOS WebView doesn't expose the app's domain properly, iframe providers reject the request Result: Blank iframe or loading failures on iOS while working fine on web/Android
Solution: Cordova InAppBrowser Fallback for iOS.
I've used the below solution to render the iframe on iOS without blank screens/ errors.
Installation:
cordova plugin add cordova-plugin-inappbrowser
Component Code:
import React, { useEffect, useState } from 'react';
import { Capacitor } from '@capacitor/core';
const IframeComponent = ({ src }) => {
const [loading, setLoading] = useState(true);
const isIOS = Capacitor.getPlatform() === 'ios';
const openInBrowser = () => {
try {
// Cordova InAppBrowser usage
window.cordova.InAppBrowser.open(
src,
'_blank',
'location=no,toolbar=yes,closebuttoncaption=Done'
);
} catch (error) {
console.error('Failed to open browser:', error);
}
};
// Auto-open for iOS
useEffect(() => {
if (isIOS && src && window.cordova && window.cordova.InAppBrowser) {
openInBrowser();
setLoading(false);
}
}, [isIOS, src]);
// Regular iframe for web/Android
if (!isIOS) {
return (
<iframe
src={src}
onLoad={() => setLoading(false)}
style={{ width: '100%', height: '400px', border: 'none' }}
/>
);
}
// iOS fallback UI
return (
<div style={{ textAlign: 'center', padding: '20px' }}>
<p>Content will open in browser</p>
<button onClick={openInBrowser}>
Open Content
</button>
</div>
);
};
export default IframeComponent
This code checks the platform using Capacitor. If it's iOS, it opens the URL in InAppBrowser instead of rendering an iframe. For web and Android, it uses a standard iframe
Any update on this?