<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Arthur Corenzan</title>
    <description>The latest articles on Forem by Arthur Corenzan (@haggen).</description>
    <link>https://forem.com/haggen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F201975%2Fa052c904-f10f-423a-bf06-76b205875cb3.jpeg</url>
      <title>Forem: Arthur Corenzan</title>
      <link>https://forem.com/haggen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/haggen"/>
    <language>en</language>
    <item>
      <title>Versionamento semântico</title>
      <dc:creator>Arthur Corenzan</dc:creator>
      <pubDate>Tue, 26 Dec 2023 14:11:13 +0000</pubDate>
      <link>https://forem.com/haggen/versionamento-semantico-2iik</link>
      <guid>https://forem.com/haggen/versionamento-semantico-2iik</guid>
      <description>&lt;p&gt;Somente para bibliotecas. Não se aplica a produtos. Ver outros &lt;a href="https://en.wikipedia.org/wiki/Software_versioning"&gt;esquemas de versionamento de software&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M9KV_DRw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drg1u53mqk587tbtjhni.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M9KV_DRw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drg1u53mqk587tbtjhni.png" alt="Fluxo de decisão para determinar a nova versão do seu código." width="800" height="924"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Pasting screenshots takes way longer than pasting image files</title>
      <dc:creator>Arthur Corenzan</dc:creator>
      <pubDate>Tue, 22 Feb 2022 14:04:22 +0000</pubDate>
      <link>https://forem.com/haggen/pasting-screenshots-takes-way-longer-than-pasting-image-files-2kb7</link>
      <guid>https://forem.com/haggen/pasting-screenshots-takes-way-longer-than-pasting-image-files-2kb7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;. The demo was previously broken, now it's fixed.&lt;/p&gt;




&lt;p&gt;Let me show you;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Take a screenshot using an utility that dumps the image directly to your clipboard, so you can paste it. Like the &lt;code&gt;PrintScreen&lt;/code&gt; key on Windows/Linux or &lt;code&gt;Cmd+Shift+3&lt;/code&gt; on macOS.&lt;/li&gt;
&lt;li&gt;Open this up &lt;a href="https://eivfjo.csb.app"&gt;https://eivfjo.csb.app&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Paste with &lt;code&gt;Ctrl+V&lt;/code&gt; on Windows/Linux or &lt;code&gt;Cmd+V&lt;/code&gt; on macOS.&lt;/li&gt;
&lt;li&gt;Now copy an existing image from your computer—perhaps a screenshot saved to disk.&lt;/li&gt;
&lt;li&gt;Go back to the page and paste it.&lt;/li&gt;
&lt;li&gt;See any difference?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's how it worked out for me (I'm using Chrome on Windows, by the way);&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first paste, of the screenshot just taken, &lt;strong&gt;took about 500ms&lt;/strong&gt;—I'm on a 4k display, your mileage may vary.&lt;/li&gt;
&lt;li&gt;The second one, of a file from my computer, &lt;strong&gt;took 0ms&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now I'll reveal it to you. We're doing nothing. Okay, it's not technically nothing. But we're not really doing anything useful or that should take too long for that matter.&lt;/p&gt;

&lt;p&gt;So what gives?&lt;/p&gt;

&lt;p&gt;Below there's the whole code you just tested. You can also &lt;a href="https://codesandbox.io/s/paste-file-blocking-handler-eivfjo"&gt;check it over on CodeSandbox&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.addEventListener("paste", (event) =&amp;gt; {
  const now = performance.now();
  void event.clipboardData.files; // This line is the culprit.
  document.body.textContent = `It took ${performance.now() - now}ms`;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're not familiar or need a refresher, &lt;code&gt;void&lt;/code&gt; simply &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void"&gt;evaluates the expression and returns undefined&lt;/a&gt;. That's it. We might as well omit it. I only added it for dramatic purposes. The important bit is you have to access the &lt;code&gt;files&lt;/code&gt; property on the &lt;code&gt;clipboardData&lt;/code&gt; object carried by the event.&lt;/p&gt;

&lt;p&gt;If you're curious why that is it's because the &lt;code&gt;files&lt;/code&gt; array is a shim, its content is gathered in the property accessor &lt;code&gt;get files()&lt;/code&gt; in the &lt;code&gt;DataTransfer&lt;/code&gt; interface. You can &lt;a href="https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-files-dev"&gt;read more on the spec&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The odd part is &lt;strong&gt;why the difference&lt;/strong&gt; between pasting a screenshot and pasting a file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer"&gt;MDN doesn't say anything&lt;/a&gt;. The spec has some curious bits but didn't explain it either.&lt;/p&gt;

&lt;p&gt;My wild guess is that it isn't the browser's fault. Perhaps the underlying implementation on the OS captures the screen as a simple bitmap and then lazily encodes it to more suited format line PNG as it's read? I don't know.&lt;/p&gt;

&lt;p&gt;It's a problem in any case because for one I can't even show the user some feedback that something's going on since event handlers block—the next frame doesn't start until it returns, so any changes to DOM, like adding a &lt;code&gt;loading&lt;/code&gt; class to an element, will have to wait—but it's also freezing up the whole page for that period. Yikes! :( &lt;/p&gt;

&lt;p&gt;Any ideas?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Consentman: a lightweight manager for complying with user consent</title>
      <dc:creator>Arthur Corenzan</dc:creator>
      <pubDate>Sun, 08 Mar 2020 18:27:56 +0000</pubDate>
      <link>https://forem.com/haggen/managing-user-consent-on-your-website-1ecj</link>
      <guid>https://forem.com/haggen/managing-user-consent-on-your-website-1ecj</guid>
      <description>&lt;p&gt;&lt;small&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@charlesdeluvio?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Charles Deluvio&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/handshake?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;.&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://gdpr-info.eu/"&gt;GDPR&lt;/a&gt; and similar legislation in other countries—like the &lt;a href="https://www.lgpdbrasil.com.br/"&gt;LGPD here in Brazil&lt;/a&gt;—picking up I've started to get asked about privacy-focused issues on my clients' websites.&lt;/p&gt;

&lt;p&gt;One such case got me working on a Cookie Consent pop-up. Yea I hate those too but as &lt;a href="https://techcrunch.com/2020/01/10/cookie-consent-tools-are-being-used-to-undermine-eu-privacy-rules-study-suggests/"&gt;others have mentioned&lt;/a&gt; it's mostly because they're being used wrong. &lt;/p&gt;

&lt;p&gt;The first thing I did was to look up what's been done before in this front. But as I did my research I began to realize my options were plugins for WordPress for non-developers, bloated suites that do too much—often overlapping with existing components in my website—or &lt;em&gt;basically adware&lt;/em&gt; that tries to reel me into their paid services. &lt;/p&gt;

&lt;p&gt;Two of the popular ones are &lt;a href="https://www.osano.com/cookieconsent"&gt;Osano's cookieconsent&lt;/a&gt; and &lt;a href="https://www.oiljs.org/"&gt;OIL.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As a fan of small, focused libraries that do one thing and do it well I was left hanging. So I did as any &lt;em&gt;sane&lt;/em&gt; developer would do and set out to create my own.&lt;/p&gt;

&lt;p&gt;My aim was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller scope. Fix the issue at hand and don't touch the rest.&lt;/li&gt;
&lt;li&gt;Simple API that gives full control to the developer.&lt;/li&gt;
&lt;li&gt;Don't touch the user interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The issue at hand, in this case, was to manage user consent for cookies, tracking and some other stuff and get out of the way. I already have the interface done, using my own styles and markup all accessible and whatnot.&lt;/p&gt;

&lt;p&gt;That's how &lt;a href="https://github.com/corenzan/consentman"&gt;Consentman&lt;/a&gt; came to be.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;addConsentSubject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getConsent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;changeConsent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;enforceConsent&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consentman&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;addConsentSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;allowed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Consent has been granted. Installing trackers.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blocked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Consent has been revoked. Removing trackers.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User needs to consent first.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;indeterminate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;getConsent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;consent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;confirm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Would you like to consent?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;changeConsent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;granted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;changeConsent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;revoked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;enforceConsent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the example above, when the user first visit the website the consent named &lt;code&gt;default&lt;/code&gt; will be &lt;code&gt;indeterminate&lt;/code&gt;, so a confirmation will be shown asking the user for consent.&lt;/p&gt;

&lt;p&gt;If the user clicks &lt;code&gt;Yes&lt;/code&gt; consent will be granted and any subjects will have their state changed to &lt;code&gt;allowed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the user clicks &lt;code&gt;No&lt;/code&gt; consent will be revoked and any subjects will have their state changed to &lt;code&gt;skipped&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Subsequent visits by the user will &lt;strong&gt;not&lt;/strong&gt; trigger the confirmation since consent is remembered across visits—via local storage.&lt;/p&gt;

&lt;p&gt;By then, if at any time &lt;code&gt;default&lt;/code&gt; consent is revoked and re-enforced, any subjects will have their state changed to &lt;code&gt;blocked&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Notice that there are two possible states resulting from the consent being revoked. This way you can handle a subject being skipped over and being blocked separately. &lt;/p&gt;

&lt;p&gt;You can also have additional consents with different names, e.g. one for trackers, one for advertising, etc.&lt;/p&gt;

&lt;p&gt;Head over to the &lt;a href="https://github.com/corenzan/consentman"&gt;repository&lt;/a&gt; and checkout the code! Also, don't be a stranger, all feedback is welcome. 😊️&lt;/p&gt;

&lt;p&gt;Thank you for your time and have a good one.&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>consent</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Lazy load embedded YouTube videos</title>
      <dc:creator>Arthur Corenzan</dc:creator>
      <pubDate>Wed, 07 Aug 2019 15:04:06 +0000</pubDate>
      <link>https://forem.com/haggen/lazy-load-embedded-youtube-videos-520g</link>
      <guid>https://forem.com/haggen/lazy-load-embedded-youtube-videos-520g</guid>
      <description>&lt;p&gt;I was working on this simple static website that should have an YouTube video displayed right on the landing page. So I went my merry way, hopped onto YouTube, snatched the embed code, pasted it into my editor and called it a day.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FHWKj35i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FHWKj35i.png" alt="YouTube share dialog"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing is the job was specifically to deliver high performance, accessibility and modern practices, so you can imagine my annoyance when I noticed that just for having this &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; I got this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FIT0tvqp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FIT0tvqp.png" alt="DevTools snapshot showing multiple requests made from YouTube's iframe 🤨️"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plus a few extra requests that my ad blocker handled for me.&lt;/p&gt;

&lt;p&gt;That is over 500KB that my users would have to download on top of the website, regardless if they'll watch the video. Do you have any idea &lt;a href="https://developers.google.com/web/fundamentals/performance/why-performance-matters/" rel="noopener noreferrer"&gt;how heavy this might hit your users&lt;/a&gt;, specially the ones with slow connection or low performing machines? To add insult to injury they'd also be being tracked—Hi Google—for just loading a video they didn't even know was there.&lt;/p&gt;

&lt;p&gt;It being a simple static website I wanted to keep my solution to a minimum, so here's what I came up with.&lt;/p&gt;

&lt;p&gt;The code for embedding an YouTube video, as of August 2019, goes like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; 
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"560"&lt;/span&gt; 
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"315"&lt;/span&gt; 
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.youtube.com/embed/Y8Wp3dafaMQ"&lt;/span&gt; 
  &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; 
  &lt;span class="na"&gt;allow=&lt;/span&gt;&lt;span class="s"&gt;"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"&lt;/span&gt; 
  &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So I thought what if instead of the actual video I showed just its cover linked to the video? It would still kinda look like an embedded video but it would require only a single image upfront. Thankfully YouTube has an &lt;a href="https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api" rel="noopener noreferrer"&gt;URL schema for video thumbnails&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://www.youtube.com/embed/Y8Wp3dafaMQ"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://i3.ytimg.com/vi/Y8Wp3dafaMQ/hqdefault.jpg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool, but I really don't want to have to create a whole new page just for this teeny tiny snippet of code. Well, we're in luck cause &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; has just the perfect thing for us—the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-srcdoc" rel="noopener noreferrer"&gt;srcdoc attribute&lt;/a&gt;. With it you can source the &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; directly in the hosting page. Just beware that it &lt;a href="https://caniuse.com/#search=srcdoc" rel="noopener noreferrer"&gt;won't work on Edge or IE&lt;/a&gt; and that we can't use double quotes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; 
  &lt;span class="err"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;srcdoc=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;a href=https://www.youtube.com/embed/Y8Wp3dafaMQ&amp;gt;&amp;lt;img src=https://i3.ytimg.com/vi/Y8Wp3dafaMQ/hqdefault.jpg&amp;gt;&amp;lt;/a&amp;gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally you'll notice that if we click the image it'll load the video but in a paused state and we would need to click it again to start watching. Fret not, cause the embed video URL supports &lt;a href="https://developers.google.com/youtube/player_parameters?playerVersion=HTML5" rel="noopener noreferrer"&gt;player parameters&lt;/a&gt; and among those there's the &lt;code&gt;autoplay&lt;/code&gt; variable which does exactly what you would expect. Additionally due to browser's default style users on systems with scrollbar—namely not macOS—will see an unnecessary scrollbar, but nothing that a small CSS reset wouldn't fix. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/remy"&gt;Remy Sharp&lt;/a&gt; pointed out we should keep the &lt;code&gt;src&lt;/code&gt; as fallback to browsers that don't support &lt;code&gt;srcdoc&lt;/code&gt;. &lt;a href="https://dev.to/aardrian"&gt;Adrian Roselli&lt;/a&gt; suggested a few tweaks to improve accessibility. Also, while applying these suggestions I fixed the image position so it stays centered both horizontally and vertically without resorting to &lt;code&gt;background-size: cover&lt;/code&gt;. Thank you guys for your feedback! 🤩️&lt;/p&gt;

&lt;p&gt;Here's the &lt;strong&gt;final result&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/qdzu6"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; singled out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt;
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"560"&lt;/span&gt;
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"315"&lt;/span&gt;
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.youtube.com/embed/Y8Wp3dafaMQ"&lt;/span&gt;
  &lt;span class="na"&gt;srcdoc=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;style&amp;gt;*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}&amp;lt;/style&amp;gt;&amp;lt;a href=https://www.youtube.com/embed/Y8Wp3dafaMQ?autoplay=1&amp;gt;&amp;lt;img src=https://img.youtube.com/vi/Y8Wp3dafaMQ/hqdefault.jpg alt='Video The Dark Knight Rises: What Went Wrong? – Wisecrack Edition'&amp;gt;&amp;lt;span&amp;gt;▶&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;"&lt;/span&gt;
  &lt;span class="na"&gt;frameborder=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;
  &lt;span class="na"&gt;allow=&lt;/span&gt;&lt;span class="s"&gt;"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"&lt;/span&gt;
  &lt;span class="na"&gt;allowfullscreen&lt;/span&gt;
  &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"The Dark Knight Rises: What Went Wrong? – Wisecrack Edition"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way all the users will have to download upfront is the cover image, which seems pretty reasonable to me. You can customize it further, e.g. make use of the different thumbnail sizes for different devices, and if you need more control over what the user will load and what features to enable you can always explore the &lt;a href="https://developers.google.com/youtube/iframe_api_reference" rel="noopener noreferrer"&gt;YouTube Player API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you've got any questions, corrections or suggestions feel free to comment below. Thank you for your time. 😊️&lt;/p&gt;

</description>
      <category>html</category>
      <category>youtube</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
