iframes with data-src attribute don't load video content
Steps to Reproduce
iframes that use the data-src attribute instead of src (common lazy loading implementation) don't render or play video content correctly in the widget.
HTML
<iframe
width="560"
height="315"
data-src="https://www.youtube-nocookie.com/embed/8rvRE0YGZC0?si=FSGjHOuepA_66fIv"
title="YouTube video player"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEAOw=="
class="lazyload"
data-load-mode="1">
</iframe>
`HtmlWidget` configuration
HtmlWidget(
post.content?.rendered ?? '',
textStyle: TextStyle(
fontSize: 18,
color: context.textColor(),
))
Tesing environment
[✓] Flutter (Channel stable, 3.35.2, on macOS 15.5 24F74 darwin-arm64, locale es-ES) [1.368ms]
• Flutter version 3.35.2 on channel stable at /Users/fabianperez/fvm/versions/3.35.2
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 05db968908 (12 hours ago), 2025-08-25 10:21:35 -0700
• Engine revision a8bfdfc394
• Dart version 3.9.0
• DevTools version 2.48.0
• Feature flags: enable-web, enable-linux-desktop, enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-lldb-debugging
[!] Android toolchain - develop for Android devices (Android SDK version 35.0.1) [1.810ms]
• Android SDK at /Users/fabianperez/Library/Android/sdk
• Emulator version 35.3.11.0 (build_id 12836668) (CL:N/A)
• Platform android-36, build-tools 35.0.1
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
This is the JDK bundled with the latest Android Studio installation on this machine.
To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
• Java version OpenJDK Runtime Environment (build 21.0.6+-13391695-b895.109)
! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
[✓] Xcode - develop for iOS and macOS (Xcode 16.2) [1.680ms]
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 16C5032a
• CocoaPods version 1.16.2
[✓] Chrome - develop for the web [6ms]
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2025.1) [6ms]
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 21.0.6+-13391695-b895.109)
[✓] VS Code (version 1.101.0) [5ms]
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (3 available) [6,5s]
• iPhone 16 (mobile) • 47079FEA-73C2-4273-8DE0-2629D32F6A02 • ios • com.apple.CoreSimulator.SimRuntime.iOS-18-2 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 15.5 24F74 darwin-arm64
• Chrome (web) • chrome • web-javascript • Google Chrome 139.0.7258.139
[✓] Network resources [1.185ms]
• All expected network resources are available.
Expected results
iframes with data-src should load and display YouTube video content normally, recognizing the data-src attribute as a valid source for the iframe.
Actual results
iframes with data-src don't load video content, showing an empty or blank iframe. The library appears to not recognize or process the data-src attribute, which is commonly used in CMS systems like WordPress to implement automatic lazy loading.
flutter_widget_from_html v0.17.1 has been released with support for this. Please try upgrading and see whether it works for you.
Hi, with the new update it doesn't work for me. Could you please try with this code?
`
I'm getting this when using youtube embed with iframe
<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>
The exact html used to work properly but now I'm getting this behaviour
Any solutions ?
Note: i tried to add the
refererpolicy=“cross-origin-with-strict-origin”
but it doesn't work
I'm getting this when using youtube embed with iframe
<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>The exact html used to work properly but now I'm getting this behaviour
Any solutions ?
Note: i tried to add the
refererpolicy=“cross-origin-with-strict-origin”but it doesn't work
me too. flutter 3.35.1
I'm getting this when using youtube embed with iframe
<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>The exact html used to work properly but now I'm getting this behaviour
Any solutions ?
Note: i tried to add the
refererpolicy=“cross-origin-with-strict-origin”but it doesn't workme too. flutter 3.35.1
Same problem since flutter 3.29
Same thing with flutter 3.35.7 I don't think the issue is with the flutter version
The error 153 that they are reporting is not the same as what I explained in this issue; according to my research, it is happening to different libraries due to a change in YouTube's policies and cookies.
The error 153 that they are reporting is not the same as what I explained in this issue; according to my research, it is happening to different libraries due to a change in YouTube's policies and cookies.
I have tried changing youtube.com to youtube-nocookie.com and adding referrerpolicy="strict-origin-when-cross-origin", but it still doesn’t work.
This was working perfectly as expected
<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>
But since YouTube changed their policies it stopped
Any suggestions ?
This was working perfectly as expected
<iframe src="//www.youtube.com/embed/aEGxfFx9FgM" width="640" height="360" class="note-video-clip"></iframe>But since YouTube changed their policies it stopped
Any suggestions ?
My temporary solution to this problem is to use youtube_player_iframe. Here’s an example code: if (element.localName == 'iframe' && element.attributes.containsKey('src')) { final src = element.attributes['src']!;
final videoId = YoutubePlayerController.convertUrlToId(src);
if (videoId != null) {
final controller = YoutubePlayerController.fromVideoId(
videoId: videoId,
autoPlay: true,
params: const YoutubePlayerParams(
showControls: true,
showFullscreenButton: false,
origin: 'https://www.youtube-nocookie.com',
),
);
return Container(
padding: const EdgeInsets.symmetric(vertical:16),
width: double.infinity,
child: YoutubePlayer(
controller: controller,
aspectRatio: 16 / 9,
),
);
}
}
Same problem,
<iframe src="https://www.youtube.com/embed/g-r8nFhsxnU" width="560" height="314" allowfullscreen="allowfullscreen"></iframe>
I think it's a youtube bug they should Fix it
Same issue here. It's also not working when replacing the youtube.com with youtube-nocookie.com in the url.
Did you find any solution?
Did you find any solution?
The temporary solution I found is to use customWidgetBuilder together with the youtube_player_iframe package.
With this approach, you can detect <iframe> elements whose src attribute contains "youtube" and then render them using the Youtube player widget instead of a raw HTML iframe:
HtmlWidget(
post.videoEmbed ?? '',
customWidgetBuilder: (e) {
if (e.localName == 'iframe') {
final src = e.attributes['src'] ?? '';
if (src.contains('youtube')) {
final videoId = YoutubePlayerController.convertUrlToId(src);
if (videoId != null) {
final controller = YoutubePlayerController.fromVideoId(
videoId: videoId,
autoPlay: false,
params: const YoutubePlayerParams(
showControls: true,
showFullscreenButton: false,
origin: 'https://www.youtube-nocookie.com',
),
);
return Container(
padding: const EdgeInsets.symmetric(vertical: 16),
width: double.infinity,
child: YoutubePlayer(
controller: controller,
aspectRatio: 16 / 9,
),
);
}
}
}
return null;
},
)
This workaround lets you properly display embedded YouTube videos, until a more permanent solution is available.
Unfortunately even with the YoutubePlayer and your example factory the error still remains for us. Not sure what to do here.
Unfortunately even with the YoutubePlayer and your example factory the error still remains for us. Not sure what to do here.
I did the same thing with youtube player Same error black screen no video playing 😐
It seems that only some videos are working with this workaround. Other videos just show a black screen.
This is btw our working factory for YouTube with the package youtube_player_iframe and some adjustments. It's working for all videos since there is a bug within the package.
Cue the video instead of loading it was the solution, as it would be auto-played then. Do not initialize the controller via "YoutubePlayerController.fromVideoId" as this cannot correctly handle videos with ids that contain a "-".
Issue: https://github.com/sarbagyastha/youtube_player_flutter/issues/1060
mixin TMXYoutubeFactory on WidgetFactory {
@override
void parse(BuildTree meta) {
if (meta.element.localName == 'iframe') {
final src = meta.element.attributes['src'];
if (src != null && src.contains('youtube')) {
final videoId = YoutubePlayerController.convertUrlToId(src);
if (videoId != null) {
meta.register(
BuildOp(
priority: 9999,
onRenderBlock: (_, _) => YoutubePlayerFromHtml(
videoId: videoId,
),
),
);
}
}
}
return super.parse(meta);
}
}
/// A widget that renders a YouTube player from an HTML iframe element via video id.
class YoutubePlayerFromHtml extends StatefulWidget {
const YoutubePlayerFromHtml({required this.videoId, super.key});
/// The YouTube video ID to play.
final String videoId;
@override
State<YoutubePlayerFromHtml> createState() => _YoutubePlayerFromHtmlState();
}
class _YoutubePlayerFromHtmlState extends State<YoutubePlayerFromHtml> {
late final controller = YoutubePlayerController(
params: const YoutubePlayerParams(
showFullscreenButton: true,
enableCaption: false,
interfaceLanguage: 'de',
origin: 'https://www.youtube-nocookie.com',
),
);
@override
void initState() {
controller.cueVideoById(videoId: widget.videoId);
super.initState();
}
@override
Widget build(BuildContext context) {
return YoutubePlayer(controller: controller);
}
@override
void dispose() {
controller.close();
super.dispose();
}
}