Flutter web and iframe
Tags: flutter, productivity, webdev, dart
Published: 2020-03-22 12:14:13

This article combines the power of Flutter web and iframe together...

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:heading {"level":4} -->
<h4>Pre-Requisite…</h4>
<!-- /wp:heading -->

{% youtube L4iLMRHVmZ8 %}


<!-- wp:paragraph -->
<p>As of 1.12, Flutter has early support for running web applications, but you need to be running the <code>beta</code> channel of Flutter…</p>
<!-- /wp:paragraph -->

####Article here: https://flatteredwithflutter.com/flutter-web-and-iframe/


<!-- wp:paragraph -->
<p>Upgrade to Flutter <code>beta</code> channel as&nbsp;:</p>
<!-- /wp:paragraph -->


<!-- wp:code -->
<pre class="wp-block-code"><code>flutter channel beta
flutter upgrade
flutter config --enable-web</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Once web is enabled, run the <code>flutter devices</code> command…you should see something like this&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>flutter devices
2 connected device:
Chrome     • chrome     • web-javascript • Google Chrome 78.0.3904.108
Web Server • web-server • web-javascript • Flutter Tools</code></pre>
<!-- /wp:code -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>Run your app as <code>localhost</code> in Chrome, by the following</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>flutter run -d chrome</code></pre>
<!-- /wp:code -->

<!-- wp:heading {"level":4} -->
<h4>Begin…</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Lets see first, what’s an <strong>iframe</strong></p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>An inline frame is used to embed another document within the current HTML document.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>All the iframe properties in modern web, <a href="https://www.w3schools.com/tags/tag_iframe.asp" rel="noreferrer noopener" target="_blank">here</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>To include an iframe in web, we use the below syntax</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">&lt;iframe src="https://www.google.com"&gt;&lt;/iframe&gt;</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p><strong>Steps&nbsp;:&nbsp;</strong></p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Tip&nbsp;:<strong>(Create a Stateful widget and do all these steps inside initState)</strong></p></blockquote>
<!-- /wp:quote -->

<!-- wp:list {"ordered":true} -->
<ol><li>We initialize our widget as&nbsp;</li></ol>
<!-- /wp:list -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">final IFrameElement _iframeElement = IFrameElement();</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>2. Next we use the properties as exposed by this <code>_iframeElement</code>&nbsp;.&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">_iframeElement.height = '500';
_iframeElement.width = '500';
_iframeElement.src = 'https://www.youtube.com/embed/RQzhAQlg2JQ';
_iframeElement.style.border = 'none';</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p><strong>height</strong> and <strong>width</strong> are self-explanatory. This <code>src</code> paramater states the document which we want to embed and <code>style</code> parameter is for applying css to the iframe window…</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note&nbsp;: Properties for exploring: allow, allowFullScreen, contentWindow, csp, srcdoc etc..</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>3. Including <code>_iframeElement</code> as Flutter Widget</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>This <code>_iframeElement</code> is not a widget, hence we require something to register this.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We take the help of <strong>dart:ui</strong></p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">import 'dart:ui' as ui;
ui.platformViewRegistry.registerViewFactory();</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>As of now, if you copy paste the second line, you will probably get an error. This is a known issue, check <a href="https://github.com/flutter/flutter/issues/41563" rel="noreferrer noopener" target="_blank"><strong>here</strong></a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Workaround&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">// ignore: undefined_prefixed_name<br>ui.platformViewRegistry.registerViewFactory();</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>Finally, we register our <code>_iframeElement</code> like this&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">// ignore: undefined_prefixed_name<br>ui.platformViewRegistry.registerViewFactory(<br>   'iframeElement',<br> (int viewId) =&gt; _iframeElement,<br>);</pre>
<!-- /wp:preformatted -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note&nbsp;: Parameter ‘<strong>iframeElement</strong>’ is important, we will see below…</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>4. Showing the <code>_iframeElement</code>&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We will use a widget called <a href="https://api.flutter.dev/flutter/widgets/HtmlElementView-class.html" rel="noreferrer noopener" target="_blank"><strong>HtmlElementView</strong></a><strong>. </strong>As per the docs&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Embeds an HTML element in the Widget hierarchy in Flutter Web. The platform view’s lifetime is the same as the lifetime of the <a href="https://api.flutter.dev/flutter/widgets/State-class.html" rel="noreferrer noopener" target="_blank">State</a> object for this widget. When the <a href="https://api.flutter.dev/flutter/widgets/State-class.html" rel="noreferrer noopener" target="_blank">State</a> is disposed the platform view (and auxiliary resources) are lazily released.</p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>This widget has a required property named <code>viewType</code>&nbsp;. We will set its value to the one in <strong>Step3 i.e (</strong>iframeElement<strong>)</strong></p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">Widget _iframeWidget;
_iframeWidget = HtmlElementView(
   key: UniqueKey(),
   viewType: 'iframeElement',
);</pre>
<!-- /wp:preformatted -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Note: the param <code>viewType</code> has the same name as the one in Step3</p></blockquote>
<!-- /wp:quote -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:paragraph -->
<p>WE can use this _iframeWidget now inside our build method&nbsp;</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">SizedBox(<br>    height: _height,<br>    width: _width,<br>    child: _iframeWidget,<br>)</pre>
<!-- /wp:preformatted -->

<!-- wp:heading {"level":4} -->
<h4>YouTube Video in&nbsp;IFrame…</h4>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>To show the youtube video in iframe, we need to follow some rules.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Steps&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:list {"ordered":true} -->
<ol><li>Don’t directly copy paste the link and assign as <code><em>src</em></code> to iframe.</li></ol>
<!-- /wp:list -->

<!-- wp:paragraph -->
<p><strong>Reason&nbsp;:&nbsp;</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If we copy paste any youtube link, we see an endpoint (<code><em>/watch</em></code>) like this&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">https://www.youtube.com/watch?v=RQzhAQlg2JQ</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p>This <code>/watch</code> endpoint does not allow outside requests, and you may get an error like&nbsp;: <strong>X-Frame-Options</strong> to <strong>SAMEORIGIN…</strong></p>
<!-- /wp:paragraph -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><a href="https://stackoverflow.com/questions/25661182/embed-youtube-video-refused-to-display-in-a-frame-because-it-set-x-frame-opti" rel="noreferrer noopener" target="_blank">See SO here.</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:paragraph -->
<p>2. Right click on any YouTube video and click <strong>‘Copy Embed Code’….</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>You will get something like this&nbsp;:</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>&lt;iframe width="424" height="238" src="https://www.youtube.com/embed/RQzhAQlg2JQ" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Extract out the <code><em>src</em></code> param value and paste into your iframe <code><em>src</em></code></p>
<!-- /wp:paragraph -->

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">https://www.youtube.com/embed/RQzhAQlg2JQ</pre>
<!-- /wp:preformatted -->

<!-- wp:paragraph -->
<p><code>/embed</code> endpoint allows outside requests…..</p>
<!-- /wp:paragraph -->

*In case it helped :)*
<a href="https://www.buymeacoffee.com/aseemwangoo" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Pass Me A Coffee!!" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p>Hosted URL&nbsp;: <a href="https://fir-signin-4477d.firebaseapp.com/#/" rel="noreferrer noopener" target="_blank">https://fir-signin-4477d.firebaseapp.com/#/</a></p></blockquote>
<!-- /wp:quote -->

<!-- wp:quote -->
<blockquote class="wp-block-quote"><p><a href="https://github.com/AseemWangoo/experiments_with_web" rel="noreferrer noopener" target="_blank">Source code for Flutter Web App..</a></p></blockquote>
<!-- /wp:quote -->

{% youtube L4iLMRHVmZ8 %}