<?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>DEV Community: Jace</title>
    <description>The latest articles on DEV Community by Jace (@scriptjayt).</description>
    <link>https://dev.to/scriptjayt</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%2F930616%2F497978df-a405-496e-9033-40357c6cb003.png</url>
      <title>DEV Community: Jace</title>
      <link>https://dev.to/scriptjayt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/scriptjayt"/>
    <language>en</language>
    <item>
      <title>CSS, The Old</title>
      <dc:creator>Jace</dc:creator>
      <pubDate>Sun, 16 Apr 2023 14:15:51 +0000</pubDate>
      <link>https://dev.to/scriptjayt/css-the-old-6dh</link>
      <guid>https://dev.to/scriptjayt/css-the-old-6dh</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;CSS is more than simply picking a background color&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's take a look at how things were before and how not to do those things today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Float Layouts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Padding Aspect Ratio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pixel Values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Break Out of the Parent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Float Layouts
&lt;/h2&gt;

&lt;p&gt;🔝&lt;/p&gt;

&lt;p&gt;You're probably familiar with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.el&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*left, right*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*left, right, both*/&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 old days this could be used to align two containers next to each other. It was more a hack than an actual way to do it, due to the effects it had on the parent... Except it was the way to do it.&lt;br&gt;
The element got pulled out of the flow (in a way), which meant that the parent would collapse to 0 if there were no other children to give it a height, or it didn't have a height of its own.&lt;br&gt;
The clear-method was a way to tell the parent not to do that; by giving the element after the floated element the &lt;code&gt;clear&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;This way of layout whas rather fragile and with the new layout methods like &lt;code&gt;flex&lt;/code&gt; and &lt;code&gt;grid&lt;/code&gt;; &lt;code&gt;float&lt;/code&gt; quickly became obsolete and outdated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☝ Refactor old code to use &lt;code&gt;flex&lt;/code&gt; or &lt;code&gt;grid&lt;/code&gt; instead of &lt;code&gt;float&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;float&lt;/code&gt; still has its usecases. When you want text to follow the curve of an image, &lt;code&gt;float&lt;/code&gt; is the perfect way to do it.&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"parent"&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;"your_img.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem100&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First of all, you would want the image to be the first element. If it's the last one, it won't work. And give it the &lt;code&gt;float&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c"&gt;/*
    I curve the image by using border radius; 
    using the shape-outside property works as well
    */&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;widht&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;150px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But now we still have the collapsing problem, which is not really noticeable as long as the text is long enough. But why take chances?&lt;br&gt;
To fix this, we could use the clear-method again; but I prefer using the parent. It's a cleaner way to do this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.parent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flow-root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;display: flow-root&lt;/code&gt; changes the parent's context, in this case, it means that it will grow to fit the content, even if the content is floated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☝ Use &lt;code&gt;float&lt;/code&gt; with &lt;code&gt;display: flow-root&lt;/code&gt; to curve text around an image&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Padding Aspect Ratio
&lt;/h2&gt;

&lt;p&gt;🔝&lt;/p&gt;

&lt;p&gt;A short one; before we had the &lt;code&gt;aspect-ratio&lt;/code&gt; property, they would use a different method to achieve this effect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* 1:1 AR */&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! But not responsive, because this would not work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though both values are 100%, they are not the same size. Because percentages for sizes refer to the sizes of the parent element.&lt;/p&gt;

&lt;p&gt;So they found this hack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="c"&gt;/* 1:1 AR: 100% */&lt;/span&gt;
    &lt;span class="c"&gt;/* 16:9 AR: 56.25% */&lt;/span&gt;
    &lt;span class="c"&gt;/* 4: AR: 75% */&lt;/span&gt;
    &lt;span class="c"&gt;/* 3:2 AR: 66.66% */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this did not work if their element had child elements like text. The "aspect ratio" would be added to the height of the elements.&lt;br&gt;
So they did following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.parent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this still is not responsive to the content. The content of the child could still overflow.&lt;/p&gt;

&lt;p&gt;Luckily those days are over.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☝ Use the &lt;code&gt;aspect-ratio&lt;/code&gt; property to keep a constant ratio between with and height that is responsive&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pixels Values
&lt;/h2&gt;

&lt;p&gt;🔝&lt;/p&gt;

&lt;p&gt;A pixel. A small, square speck of which your screen is build out of. But in CSS-land, a pixel is a unit measurement, one of the first, if not the first.&lt;/p&gt;

&lt;p&gt;If you want a square of 50 by 50 pixels, you would use the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.square&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing ground-breaking. But nowadays we have a lot more units that we can use like &lt;code&gt;rem&lt;/code&gt;, &lt;code&gt;em&lt;/code&gt;, &lt;code&gt;ch&lt;/code&gt;, &lt;code&gt;vh&lt;/code&gt;, &lt;code&gt;vw&lt;/code&gt;, &lt;code&gt;dvh&lt;/code&gt;, &lt;code&gt;dvw&lt;/code&gt;...&lt;br&gt;
Each unit has their own use case, their own reference point; and their own perks that should be taken account for.&lt;br&gt;
For this section, I will only take al look at the first three of that list.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Rem&lt;/code&gt;&lt;br&gt;
: A unit that has the roots font-size as reference point; by default 16px. &lt;br&gt;
&lt;small&gt;(You can change this value by changing the roots font-size; but you should NOT do this.)&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Em&lt;/code&gt;&lt;br&gt;
: A unit that has the elements font-size as reference point. So if you change the font-size, the em-value changes as well.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Ch&lt;/code&gt;&lt;br&gt;
: A unit that has the elements 0 character's width of the current font and font-size. So if you change the font-size, the ch-value changes as well.&lt;/p&gt;

&lt;p&gt;When should you use each? And when not?&lt;/p&gt;
&lt;h3&gt;
  
  
  Rem
&lt;/h3&gt;

&lt;p&gt;If you would use pixels, use rem instead. That is a good start in my opinion. So, font-size, width, height...&lt;br&gt;
The &lt;code&gt;rem&lt;/code&gt; unit is more accessible than the pixel unit. Because a browser can easily increase the rem default value when a user wishes to use larger fonts for example. If you use pixels instead, the fonts on site might not be enlarged, which is bad UX.&lt;br&gt;
Yes, it might create some weird values for some regular used pixel-values due to the base 16 our rem unit uses, but I find myself using CSS custom properties in most cases anyway, so it doesn't matter much.&lt;/p&gt;
&lt;h3&gt;
  
  
  Em
&lt;/h3&gt;

&lt;p&gt;If you want a unit that sizes with your font-size for a certain component, use &lt;code&gt;em&lt;/code&gt;. Let's say we have a button with &lt;code&gt;font-size: 0.875rem&lt;/code&gt; and we want a padding on all sizes of 0.4375rem. &lt;br&gt;
Now later you might want the same button but larger, let's say &lt;code&gt;font-size: 1.25rem&lt;/code&gt;; but you want to keep the same ratios, you want to "scale" the button up. In that case, you might want to change the padding value to 0.5em instead. So now the only value you need to update is the font-size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* old */&lt;/span&gt;
&lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.875rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*14px*/&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.4375rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*7px*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.btn&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;large&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*20px*/&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.6125rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*10px*/&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;/* new */&lt;/span&gt;
&lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.875rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.btn&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;large&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It makes the code a lot cleaner; as you can see, using a value like 0.4375rem is a bit cluttering, for sure if you don't know what that value translates to in pixels, it might seem a random value.&lt;br&gt;
But by using the 0.5em, now we simply know: half of the font-size.&lt;br&gt;
And it beautifully scales the button up.&lt;br&gt;
Many use this trick to scale box-shadows as well.&lt;/p&gt;
&lt;h3&gt;
  
  
  Ch
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ch&lt;/code&gt; unit makes it very easy to constrict a paragraph to a certain number of characters, heck, I would not be surprised if that was the exact reason it was introduced.&lt;br&gt;
It works best with monospace fonts in that way, due to all characters being the same width. It does work for other fonts too, but the result is less satisfying in my opinion.&lt;/p&gt;

&lt;p&gt;Similar to the &lt;code&gt;em&lt;/code&gt; unit, &lt;code&gt;ch&lt;/code&gt; is linked to the font-size. They are not the same though, I have noticed that for some fonts 1em and 2ch are similar in size, but not exactly so. This is due to the &lt;code&gt;em&lt;/code&gt; unit being linked to the fonts height, where &lt;code&gt;ch&lt;/code&gt; is character width, I believe. The wording in their descriptions are a bit fuzzy to say for sure.&lt;/p&gt;

&lt;p&gt;According to some UX articles, a length of 45 to 90 characters is the best length for paragraphs to ensure legibility, and yeah, that seems to work. &lt;br&gt;
Personally I shoot for max-widths of 70 to 75ch, which fits neatly in that range. &lt;br&gt;
This unit makes it really easy to implement that theory in our web designs.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Articles I quickly scanned through for that character-range:&lt;/small&gt;&lt;br&gt;
&lt;a href="https://practicaltypography.com/line-length.html"&gt;&lt;small&gt;Practical Typography: Line Length&lt;/small&gt;&lt;/a&gt; &lt;br&gt;
&lt;a href="https://webflow.com/feature/control-width-of-text-elements-by-character-count-using-ch-unit"&gt;&lt;small&gt;Webflow: Ch unit&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Break out of the Parent
&lt;/h2&gt;

&lt;p&gt;🔝&lt;/p&gt;

&lt;p&gt;You might find yourself in this situation:&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;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"full-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where the &lt;code&gt;max-width&lt;/code&gt; constrains the width of its children to, let's pick, 75rem; and the &lt;code&gt;full-width&lt;/code&gt; wants to span the whole site width of, let's say, 100vw.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.max-width&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c"&gt;/*to center the container horizontally*/&lt;/span&gt;
   &lt;span class="py"&gt;margin-inline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.full-width&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, this is not going to work; unless a messy overflow was your goal. So I often see following to fix this:&lt;/p&gt;

&lt;p&gt;&lt;small&gt;(for those thinking: &lt;code&gt;width: 100%&lt;/code&gt;; that would mean the same width as the parent, which is not the desired effect as it would not break out)&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.max-width&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="py"&gt;margin-inline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.full-width&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-50vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/*pull out*/&lt;/span&gt;
   &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* push back in*/&lt;/span&gt;
   &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would fix the overflow issue by removing scrollbars on the &lt;code&gt;main&lt;/code&gt; width &lt;code&gt;overflow: visible&lt;/code&gt; and counteract the overflow-issues on the &lt;code&gt;body&lt;/code&gt; with &lt;code&gt;overflow: hidden&lt;/code&gt;. &lt;br&gt;
&lt;small&gt;(Yes, you're better of specifying &lt;code&gt;overflow-x: hidden&lt;/code&gt; in production)&lt;/small&gt;&lt;br&gt;
Then you would position the article in the center by pulling it back by half the viewport width and pushing it back by half its own length. &lt;/p&gt;

&lt;p&gt;And this would work, were it not for scrollbars.&lt;br&gt;
The scrollbar would push the content further back by, idk, 20 pixels on Chrome, 30px on Safari and 0px on browsers with floating scrollbars. &lt;br&gt;
&lt;small&gt;(No, I did not measure the scrollbar thickness of those browsers, fyi, these values are random)&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;There is no way of counteracting these offsets, due to there being no standards about scrollbars and their width. Not even with JavaScript, or at least not reliably.&lt;br&gt;
This means that for a best case: the content does not line up with the rest; or a worst case: overflow issues that completely muck up your design.&lt;/p&gt;

&lt;p&gt;So, how do you break out? &lt;br&gt;
In my opinion, you don't. I would put the max-width class only on the blocks that actually need it. &lt;br&gt;
But in the case you can't add classes to those elements except the full-width class, you could do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.max-width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.full-width&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="py"&gt;margin-inline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a catch though, and that is when the children of &lt;code&gt;.max-width&lt;/code&gt; are not containers themselves.&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;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- these children --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;lorem5&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!--  --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"full-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's say that I want all &lt;code&gt;p&lt;/code&gt; tags to be a maximum of 60 characters long; the &lt;code&gt;max-width&lt;/code&gt; can be overwritten to be &lt;code&gt;60ch&lt;/code&gt;, that is not the issue; but the text will not be able to align left with the rest of the content, due to the &lt;code&gt;margin-inline: auto&lt;/code&gt;. And removing the &lt;code&gt;margin-inline&lt;/code&gt; of those elements would mean that the &lt;code&gt;p&lt;/code&gt; would stick to the edge of the screen instead. You could try to hard-code the &lt;code&gt;margin-left&lt;/code&gt; so it lines up again, but I don't recommend doing that.&lt;/p&gt;

&lt;p&gt;You will have to ensure the HTML is properly wrapped; by a div, or a proper semantically correct element.&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;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"max-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;lorem5&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"full-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem500&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;lorem200&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something to think about which method you prefer. Use verbose classes on the elements that need it, or only add a class to divergent items.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☝ Don't use &lt;code&gt;width:100vw&lt;/code&gt; to break out of a container parent; rethink how to structure your HTML / how to use your CSS-classes&lt;/strong&gt; &lt;br&gt;
if you can, and curse if you can't.&lt;/p&gt;

&lt;p&gt;In case you only need a background that spans the whole site-width, I recommend this short by Kevin Powell: &lt;a href="https://www.youtube.com/shorts/81pnuZFarRw"&gt;Bleeding Background&lt;/a&gt; as they do a way better job explaining how to than I ever could. 😉&lt;/p&gt;

&lt;p&gt;See you in the next one! 👋&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>tips</category>
      <category>learning</category>
    </item>
    <item>
      <title>Remote with FTP</title>
      <dc:creator>Jace</dc:creator>
      <pubDate>Mon, 03 Apr 2023 12:36:51 +0000</pubDate>
      <link>https://dev.to/scriptjayt/remote-with-ftp-4m72</link>
      <guid>https://dev.to/scriptjayt/remote-with-ftp-4m72</guid>
      <description>&lt;p&gt;I like using FTP for file management on a site. I prefer it over using the file manager GUI of my hosting service. Unless I work with ZIP files, because unzipping a file on the server is faster, for me at least. But back to FTP.&lt;/p&gt;

&lt;p&gt;My current workflow is building a site locally and upload it to the server (via FTP) when it’s done. Check if any functionality is broken due to the environment differences and fix those. So at the moment I don’t need to upload that often.&lt;/p&gt;

&lt;p&gt;But recently I entered a project where I could not really do that without downloading thousands of files, which takes days. So I would have to style a page almost blindly, upload it and see what the result would be. Edit and upload again. That would be many uploads every minute that I would have to do manually. And I am not about doing stuff manually.&lt;/p&gt;

&lt;p&gt;So I asked a colleague what their solution was, and a ftp plugin for your IDE was their answer. &lt;br&gt;
I went looking for a VS-Code extension and found &lt;a href="https://marketplace.visualstudio.com/items?itemName=Natizyskunk.sftp"&gt;(this one)&lt;/a&gt;.&lt;br&gt;
It’s pretty good. Its documentation goes over a lot more than what I use and need at the moment. So I’m summarizing the options here in case I (inevitably) forget how it works. 😅&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Note that I am using the VS Code plugin, there will likely be differences if you use a different instance of this plugin for your own IDE.&lt;/p&gt;

&lt;p&gt;For starters, you need to install the plugin (you can use the link above, or search for SFTP in the Extensions-tab in VS Code), and have a project folder ready.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to your command pallet (&lt;code&gt;ctrl&lt;/code&gt;+&lt;code&gt;shift&lt;/code&gt;+&lt;code&gt;p&lt;/code&gt; on Windows) and type in &lt;code&gt;SFTP: Config&lt;/code&gt;.&lt;br&gt;
This will create and open a &lt;em&gt;sftp.json&lt;/em&gt; file in a new folder in our root.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- root
    - .vscode
        - sftp.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file would look a bit like this:&lt;br&gt;
&lt;small&gt;root/.vscode/sftp.json&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"localhost"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sftp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"remotePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"uploadOnSave"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"useTempFile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"openSsh"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You change the &lt;code&gt;host&lt;/code&gt;, &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;port&lt;/code&gt; to your own login data, provided by your host.&lt;br&gt;
You can add the &lt;code&gt;password&lt;/code&gt; field if you want, otherwise you’d be prompted to fill in your password on connection.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;remotePath&lt;/code&gt; denotes the folder you wish to target, currently it’s set to the root. You could change it to only download a selected folder. Might be a smart idea if you have a site build with a file-happy CMS like Joomla or Wordpress.&lt;br&gt;
Reopen your command pallet and now you could try connecting using the download command down below.&lt;br&gt;
If nothing gets downloaded and you are sure your login data is correct, try changing the &lt;code&gt;"protocol": "sftp"&lt;/code&gt; in the config file to &lt;code&gt;"protocol:" "ftp"&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Download
&lt;/h2&gt;

&lt;p&gt;The following command fetches all the files in the targeted folder. &lt;code&gt;SFTP: Download Project&lt;/code&gt;. They will be downloaded to the root folder. Use this to initiate your folder.&lt;br&gt;
If no files present, nothing will be downloaded, so perhaps make connection using your ftp-application to add a test-file if none are present.&lt;br&gt;
You could also use &lt;code&gt;SFTP: Sync Remote-&amp;gt;Local&lt;/code&gt; to do the same.&lt;/p&gt;
&lt;h2&gt;
  
  
  Upload
&lt;/h2&gt;

&lt;p&gt;The command &lt;code&gt;SFTP: Sync Local-&amp;gt;Remote&lt;/code&gt; will push any files in your root to the designated folder. It is smart enough to only sync the files that changed since the last upload.&lt;/p&gt;
&lt;h2&gt;
  
  
  Boundaries
&lt;/h2&gt;

&lt;p&gt;You might have noticed that the &lt;em&gt;.vscode&lt;/em&gt; folder also got uploaded, with our file with credentials. We don’t want that, so let’s ignore this folder when uploading. (Don’t forget to delete that file from your FTP.)&lt;br&gt;
&lt;small&gt;root/.vscode/sftpconfig.json&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"ignore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;".vscode"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could add any other folders you want to ignore, but in some cases that gets messy. For example, I like using node SASS and this means a lot of folders I don’t want to upload: the node-modules and any folders with SASS-files.&lt;br&gt;
In that case we can constrict any fetch and push action to a single folder.&lt;br&gt;
The rendered files get saved in a &lt;em&gt;public&lt;/em&gt; folder, or &lt;em&gt;live&lt;/em&gt; folder. Or whatever name you or your framework set it up to be.&lt;/p&gt;

&lt;p&gt;By using the &lt;code&gt;context&lt;/code&gt; option, we can border of a folder.&lt;br&gt;
&lt;small&gt;root/.vscode/sftpconfig.json&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"live"&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So only the contents of that folder get synced.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- root
    - live
    - .vscode
        - sftp.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing I noticed, is that renaming files or folders does not play too well with this plugin. Instead of renaming, it creates a new file. So you would have to delete the old files. In that case I would simply delete the target folder with my ftp app, then sync my local environment to the server. This would ensure that no old remnants remain. It's a bit meh 🙄, but whatever. Overall it's still a better experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;small&gt;Copy the next snippet and replace the &amp;lt;login credentials&amp;gt; for a quick setup.&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Project Server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;localhost&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;ftp&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;username&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;password&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"remotePath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"live"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"uploadOnSave"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"useTempFile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"openSsh"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Electron Saga 3️⃣: All beginings have an end.</title>
      <dc:creator>Jace</dc:creator>
      <pubDate>Thu, 23 Mar 2023 19:04:40 +0000</pubDate>
      <link>https://dev.to/scriptjayt/the-electron-saga-3-all-beginings-have-an-end-m65</link>
      <guid>https://dev.to/scriptjayt/the-electron-saga-3-all-beginings-have-an-end-m65</guid>
      <description>&lt;p&gt;And we are back for our latest part of the Electron Sage. As this series is more about the setup I will only go so far, as building the app itself is not really linked to the workings of, and working with Electron.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frameworks?
&lt;/h2&gt;

&lt;p&gt;When I first started with Electron, I did not think about using a JavaScript framework; most of the time I use PHP for my web development, so it did not come to mind that such a framework could be useful.&lt;/p&gt;

&lt;p&gt;The app I wanted to build would be able to do a bit more than just add items to a list I could edit. It needed to be expandable; so I build my first page with a nice sidebar and a main... and came to the realisation that I would need to copy the sidebar each time I would add a new page.&lt;br&gt;
When using PHP, you would build a page &lt;em&gt;index.php&lt;/em&gt;, which would contain the sidebar and an empty main that would be populated with a &lt;code&gt;require&lt;/code&gt;- or an &lt;code&gt;include&lt;/code&gt; function. What file you would include would depend on the current location (the URI).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My Site&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;aside&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;navitem&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;navitem&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;navitem&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;navitem&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/aside&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
        &lt;span class="cp"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="s1"&gt;'path_of_file'&lt;/span&gt;&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But no PHP, so no HTML-include.&lt;br&gt;
I shrugged and instead of looking for a NPM package that could help me, or to look into a framework like Svelte; I decided to try importing with vanilla JavaScript. It worked, kind of.&lt;/p&gt;
&lt;h2&gt;
  
  
  Layout
&lt;/h2&gt;

&lt;p&gt;First of; creating a new folder &lt;em&gt;classes&lt;/em&gt; in &lt;em&gt;/front/logic&lt;/em&gt; and a new file &lt;em&gt;app.js&lt;/em&gt;.&lt;br&gt;
Then linking the &lt;em&gt;app.js&lt;/em&gt; file as a module.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;/front/index.html&lt;/small&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;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Security-Policy"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"script-src 'self' 'unsafe-inline';"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My App&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"styles/reset.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"styles/main.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- right here  --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"logic/app.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, check if the connection is working by logging the values from last time: &lt;/p&gt;

&lt;p&gt;&lt;small&gt;/front/logic/app.js&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&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="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No breakage? Great, let's see, how do we want it to work?&lt;br&gt;
Well, when I click a button in the nav; the content should be switched out.&lt;br&gt;
I would like to be able to include content in a header, main and footer separately as to not break my main layout; so let's build up a nav and include some slots in our body&lt;/p&gt;

&lt;p&gt;&lt;small&gt;/front/index.html&lt;/small&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;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"feature-nav"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"c-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;sheet=&lt;/span&gt;&lt;span class="s"&gt;"home"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;sheet=&lt;/span&gt;&lt;span class="s"&gt;"todo"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Todo&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;sheet=&lt;/span&gt;&lt;span class="s"&gt;"tracker"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;Schema&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app-interface"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;content-slot&amp;gt;&amp;lt;/content-slot&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;content-slot&amp;gt;&amp;lt;/content-slot&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;content-slot&amp;gt;&amp;lt;/content-slot&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see I added an attribute I called &lt;code&gt;sheet&lt;/code&gt; to all buttons. I also created a folder &lt;em&gt;/front/sheets&lt;/em&gt; and added some HTML-files with names that correspond with those attribute values.&lt;/p&gt;

&lt;p&gt;It is certainly possible to add aria-labels like &lt;code&gt;aria-current&lt;/code&gt; and &lt;code&gt;aria-controls&lt;/code&gt; to the buttons; or add a skip-to-content button above the &lt;code&gt;ul&lt;/code&gt;, but those features are a bit out of scope for this checking-out series.&lt;/p&gt;

&lt;p&gt;I want the sheet-files to be plain old HTML-file; I want three containers that I can target with the JS dom-api and just write content as I would normally.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;/front/sheets/home.html&lt;/small&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;header-content&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header-content&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;main-content&amp;gt;&lt;/span&gt;
    my content
&lt;span class="nt"&gt;&amp;lt;/main-content&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;footer-content&amp;gt;&lt;/span&gt;
    my footer
&lt;span class="nt"&gt;&amp;lt;/footer-content&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JS
&lt;/h2&gt;

&lt;p&gt;The class is called &lt;code&gt;page_loader&lt;/code&gt;, and it just gets imported and called. The &lt;code&gt;is_ready&lt;/code&gt; method checks to see if our index.html has all the required elements to work; and the &lt;code&gt;activate()&lt;/code&gt; method enables the button click.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;D$&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;./fn/dev.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;page_loader&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;./classes/loader.js&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="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&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="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//? Load Pager&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;page_loader&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;is_ready&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;D$&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;Page Loader Ready&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;activate&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="nx"&gt;D$&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;warn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Page Loader not Ready&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works by using the fetch-api and a DOMParser object. &lt;br&gt;
When a button is clicked, the class checks which sheet it links to and fetches the file with, well, &lt;code&gt;Fetch&lt;/code&gt;.&lt;br&gt;
A plain text-string is returned; which is passed on to a DOMParser. This JS-object is able to transform our plain string back to HTML.&lt;br&gt;
Then we use the good old DOM-api to query our content-blocks &lt;br&gt;
(&lt;code&gt;&amp;lt;header-content&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;main-content&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;footer-content&amp;gt;&lt;/code&gt;)&lt;br&gt;
At last it's just a matter of removing the old content from our index.html and pasting in the new content to have our final result.&lt;/p&gt;
&lt;h3&gt;
  
  
  Helper functions;
&lt;/h3&gt;

&lt;p&gt;I had made some helper functions and saved them in the files &lt;em&gt;/front/logic/fn/dev.js&lt;/em&gt; and &lt;em&gt;/front/logic/fn/dom.js&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$D()&lt;/code&gt;&lt;br&gt;
: Is a function that fires the passed through function only when the app is in development. It uses the &lt;code&gt;is_dev&lt;/code&gt; variable we bridged over before.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$S()&lt;/code&gt;&lt;br&gt;
: An abbreviation for querySelector&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$SA()&lt;/code&gt;&lt;br&gt;
: An abbreviation for querySelectorAll&lt;/p&gt;
&lt;h3&gt;
  
  
  page_loader class
&lt;/h3&gt;

&lt;p&gt;First; some more helper functions; these do most of the work; they fetch and convert data.&lt;br&gt;
And we import the previously mentioned helpers as well.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;/front/logic/classes/loader.js&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;D$&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;../fn/dev.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;S$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SA$&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;../fn/dom.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @description get the sheet-attribute off of buttons
 * @param {HTMLButtonElement} _btn
 * @returns {string} - Sheet
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;get_sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_btn&lt;/span&gt;&lt;span class="p"&gt;)&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;return&lt;/span&gt; &lt;span class="nx"&gt;_btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sheet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&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="cm"&gt;/**
 * @description fetch sheet and return its data
 * @param {string} _sheet
 * @returns {response} - string
 */&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;find_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_sheet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`./sheets/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;_sheet&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.html`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;F&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// D$(console.log, response);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&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;return&lt;/span&gt; &lt;span class="nx"&gt;data&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;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;D$&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="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&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;return&lt;/span&gt; &lt;span class="nx"&gt;F&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * @description convert string to html of header-main-footer
 * @param {*} _html
 * @returns {array} - object of header_data, main_data, footer_data
 */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data_to_html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_html&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DOMParser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseFromString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;header_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;S$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;header-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;main_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;S$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;footer_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;S$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;footer-content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;header_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;main_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;footer_data&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the main class; it does little more than querying all nav-buttons with the &lt;code&gt;sheets&lt;/code&gt; attribute and the &lt;code&gt;&amp;lt;content-slot&amp;gt;&lt;/code&gt; tags and attaches a click-event to those nav-buttons.&lt;br&gt;
There are more functions you could add to the class; for example, automatically load the home.html sheet on startup. Or the sheet last used.&lt;br&gt;
And some navigation functionality like showing what the current sheet is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;page_loader&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;header_slot&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;main_slot&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;footer_slot&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;all_nav_btns&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;get_targets&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;get_nav&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// query native elements&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;get_targets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;header_slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;S$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#app-header content-slot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;main_slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;S$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#app-content content-slot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;footer_slot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;S$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#app-footer content-slot&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="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;get_nav&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;all_nav_btns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SA$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#feature-nav [sheet]&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="cm"&gt;/**
     * Fetch given sheet and render the data in the app
     * @param {string} _sheet - sheet of data to fetch
     * @param {HTMLButtonElement} _btn - button to turn on in the nav
     * @returns {void}
     */&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_sheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;_btn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;find_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_sheet&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;header_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;main_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;footer_data&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data_to_html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;header_slot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;header_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;main_slot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;main_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;footer_slot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;footer_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * @description checks to see if the loader has succesfully retrieved all nav btns and the content slots
     * @returns {boolean}
     */&lt;/span&gt;
    &lt;span class="nx"&gt;is_ready&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;all_nav_btns&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;header_slot&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;main_slot&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;footer_slot&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * @description function to activate click events on nav-btns
     */&lt;/span&gt;
    &lt;span class="nx"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;all_nav_btns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;get_sheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;btn&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  It works but...
&lt;/h2&gt;

&lt;p&gt;What I noticed when using this class is, that when I write JavaScript in a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags in a sheet.html; it does not get triggered in the index.html; which does not mean it is safe to allow any scripts to infiltrate those files though. My guess is that the script gets run when the fetch-request reads through the file and not when the content gets 'pasted' into our index.html.&lt;/p&gt;

&lt;p&gt;But what if you want to import some JS anyway? Well; I noticed that custom-elements get rendered properly, (if they are defined in our app.js file); so you could use a custom-element to autoload JS code.&lt;/p&gt;

&lt;p&gt;Notice: I can't really speak about the security of this method; I would say not too bad, but if those HTML files got corrupted anyhow, the class would have no way of knowing, never mind handeling.&lt;/p&gt;

&lt;p&gt;Conclusion: use a framework 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Series Conclusion
&lt;/h2&gt;

&lt;p&gt;In these 4 articles, I set to lay out my first steps into starting with Electron and desktop-app making. I must say I was surprised how little extra setup it is compared to web development, for this example at least. I assume that if I where to dive deeper into this world, it would require some more setup. &lt;br&gt;
I found that it is certainly possible to work with Electron without a framework (I fully build my app before realizing I could have used one); but it would have improved my dev-experience a bit.&lt;br&gt;
I like how close it is to web-development I'm used to, and working with it feels quite nice, but I can't really compare how it holds up against other app-dev frameworks.&lt;br&gt;
However, the unsolvable errors at the start of my journey should be mentioned &lt;a href="https://dev.to/scriptjayt/the-electron-saga-0-my-first-app-45jg"&gt;(The Electron Saga 0)&lt;/a&gt;. They did cause a bit of confusion and worry.&lt;/p&gt;

&lt;p&gt;Overall, it was fun mocking around this new environment, away from the projects lurking over my shoulder.&lt;br&gt;
Speaking of which, I should return to those. I hope you got something out of this series.&lt;br&gt;
See ya! 👋&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>writing</category>
      <category>electron</category>
    </item>
    <item>
      <title>The Electron Saga 2️⃣: Bridge building</title>
      <dc:creator>Jace</dc:creator>
      <pubDate>Fri, 30 Dec 2022 14:29:00 +0000</pubDate>
      <link>https://dev.to/scriptjayt/the-electron-saga-2-bridge-building-2nhj</link>
      <guid>https://dev.to/scriptjayt/the-electron-saga-2-bridge-building-2nhj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hi there; a short message before we jump into the code:&lt;/p&gt;

&lt;p&gt;With this being the third article of this journey, I thought: why not open a &lt;a href="https://github.com/ScriptJayT/Checks-out-Electron" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt; for this project? So here you go.&lt;br&gt;
For those who would like access to the source code. The latest version of this project can be downloaded/pulled from this repo.&lt;br&gt;
Note that some of the older commit-messages may be a bit wonky. I am terrible at naming things sometimes.&lt;/p&gt;

&lt;p&gt;Now let's jump back into the project.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last time we build the backbone and the start of a body. Now, these two can't communicate with each other yet; and sometimes we sort of do need that.&lt;br&gt;
For now we will transfer a couple of variables.&lt;/p&gt;

&lt;p&gt;If you remember, last time we had a variable which could tell us if the app was in production or not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;is_dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, wouldn't it be usefull to have this constant in our body as well? I would think so, so let's take a look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the bridge
&lt;/h2&gt;

&lt;p&gt;Remembering back; we told electron to preload a &lt;em&gt;preload.js&lt;/em&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;/main.js&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;create_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;my_window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My Lab&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;webPreferences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;contextIsolation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;nodeIntegration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="c1"&gt;// We are telling that here!&lt;/span&gt;
            &lt;span class="na"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preload.js&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;my_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`./front/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.html`&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;is_dev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;my_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setDevToolsWebContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;my_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openDevTools&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;detach&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;So if you didn't create an empty &lt;em&gt;preload.js&lt;/em&gt; file in the root folder and ran into some trouble last time... Now you know why. 😉&lt;/small&gt;&lt;/p&gt;

&lt;p&gt;This &lt;em&gt;preload.js&lt;/em&gt; acts like a bridge between our backbone and our body.&lt;/p&gt;

&lt;p&gt;Let's build some containers to bridge over.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;/preload.js&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;contextBridge&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;contextBridge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exposeInMainWorld&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;E_system&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="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;contextBridge.exposeInMainWorld&lt;/code&gt; function takes in two params, the first on is the object-name you wish to use. The second is the object with key-value pairs of the actual data.&lt;/p&gt;

&lt;p&gt;In this case we save the users system (mac, linux, windows) in the &lt;code&gt;E_system.platform&lt;/code&gt; variable; and the production mode, (live, in production) in the &lt;code&gt;E_system.mode&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;Important to note is that these variables are read-only.&lt;/p&gt;

&lt;p&gt;Great, now we have access to backbone-data. Let's see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cross the bridge
&lt;/h2&gt;

&lt;p&gt;&lt;small&gt;/front/index.html&lt;/small&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;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt; &lt;span class="na"&gt;spellcheck=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Security-Policy"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"script-src 'self' 'unsafe-inline';"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My Lab&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's fire up Electron &lt;code&gt;npm start&lt;/code&gt; and check the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Program Files\nodejs\node.exe

win32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ha, 🤔&lt;br&gt;
The platform variable logs something we expect, the &lt;code&gt;win32&lt;/code&gt; is indeed the machine I'm currently working on...&lt;br&gt;
But the mode does not say anything about dev-mode or production.&lt;/p&gt;

&lt;p&gt;Well, take a look at the &lt;code&gt;is_dev&lt;/code&gt; variable declaration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;is_dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we check &lt;code&gt;is_dev&lt;/code&gt; variable against our &lt;code&gt;E_system.mode&lt;/code&gt;, we would get true. &lt;code&gt;C:\Program Files\nodejs\node.exe&lt;/code&gt; is not equal to &lt;code&gt;production&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So let's change the code a bit so we get a variable we could use without getting a weird string.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;/preload.js&lt;/small&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;contextBridge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exposeInMainWorld&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;E_system&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="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;is_dev_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;small&gt;/front/index.html&lt;/small&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;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;is_dev_mode&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;E_system&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's refresh the Electron app. (The shortcut &lt;code&gt;ctrl+r&lt;/code&gt; is set up in our app-menu to reload the frontend of our app).&lt;/p&gt;

&lt;p&gt;We get the values we expected logged out.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;true

win32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! We build a bridge and successfully crossed it.&lt;br&gt;
Let's stop here for now.&lt;br&gt;
Will see you in the next one! 👋&lt;/p&gt;

</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>The Electron Saga 1️⃣: Setup</title>
      <dc:creator>Jace</dc:creator>
      <pubDate>Sat, 10 Dec 2022 13:49:14 +0000</pubDate>
      <link>https://dev.to/scriptjayt/the-electron-saga-1-setup-53ld</link>
      <guid>https://dev.to/scriptjayt/the-electron-saga-1-setup-53ld</guid>
      <description>&lt;p&gt;It's been a while, hasn't it? But let's not dwell and dive back into the project.&lt;/p&gt;

&lt;p&gt;The goal for this chapter is to try give a bit of a clearer image of what is going on. Rather than tell you about mishaps I encountered, I'll try and show you how it works. &lt;/p&gt;

&lt;h2&gt;
  
  
  Folder Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; - root
    - front
    - node_modules
    - .gitignore
    - main.js
    - package.json
    - package-lock.json
    - preload.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  First: background noice (mostly)
&lt;/h3&gt;

&lt;p&gt;.gitignore&lt;br&gt;
: if you are familiar with Git you know what this one does. &lt;br&gt;
It allows us to exclude files and folders from the git repo. In our case it removes the &lt;em&gt;node_modules&lt;/em&gt; folder and the &lt;em&gt;package-lock.json&lt;/em&gt;. You don't need it if you don't use Git.&lt;/p&gt;

&lt;p&gt;package.json&lt;br&gt;
: this file is generated when we setup everything we need, including Electron; and contains some functions to symplify workflow. We will take a look at this one a bit down below.&lt;/p&gt;

&lt;p&gt;package-lock.json&lt;br&gt;
: magic happens here. It is a file that is generated after a Node project is initialized.&lt;/p&gt;
&lt;h3&gt;
  
  
  Next up: Electron
&lt;/h3&gt;

&lt;p&gt;main.js&lt;br&gt;
: this is the core of our project. It contains the code which allows us to 'communicate' with Electron.&lt;br&gt;
You could say it is the backbone of our project and it also acts like a key to the user system.&lt;/p&gt;

&lt;p&gt;preload.js&lt;br&gt;
: this file is the bridge between our backbone and our future front-end. Any user-system data we want access to in our front-end will be copied here and passed on.&lt;/p&gt;
&lt;h3&gt;
  
  
  Front-end
&lt;/h3&gt;

&lt;p&gt;The folder &lt;em&gt;front&lt;/em&gt; contains any code, styles, markup the actual project consists out of.&lt;br&gt;
I devided this folder further like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- front
    - logic
    - media
    - sheets
    - styles
    - index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you could rename any folder in here to your liking.&lt;br&gt;
The &lt;em&gt;logic&lt;/em&gt; folder contains any javascript; &lt;em&gt;media&lt;/em&gt; contains any images and svg-icons; &lt;em&gt;styles&lt;/em&gt; contains css-files; and &lt;em&gt;sheets&lt;/em&gt;... html-files. What for is not for now.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup Node
&lt;/h2&gt;

&lt;p&gt;To setup Node you need it installed on your system. Then open a terminal in the root folder of the project.&lt;br&gt;
First of, initialize Node with following command: &lt;code&gt;npm init&lt;/code&gt;&lt;br&gt;
Second, open the generated &lt;em&gt;package.json&lt;/em&gt; and add/edit the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main.js"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"electron"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^21.1.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to install some more packages here like Sass or Typescript, that is possible ofcourse.&lt;br&gt;
With this set up, let's install Electron: &lt;code&gt;npm install&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If that succeeded we could start with the next setup, but first I like to add a script to the package to simplify the workflow a bit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"electron ."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the command &lt;code&gt;npm start&lt;/code&gt; would launch Electron. But before this works, we need a body, meaning a backbone and a front.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup main.js
&lt;/h2&gt;

&lt;p&gt;As said before, the main.js is like the core of the project. Without, no Electron.&lt;br&gt;
Let's get it set up.&lt;/p&gt;
&lt;h3&gt;
  
  
  Variables
&lt;/h3&gt;

&lt;p&gt;Firstly the &lt;em&gt;app&lt;/em&gt;, &lt;em&gt;BrowserWindow&lt;/em&gt; and &lt;em&gt;Menu&lt;/em&gt; from &lt;em&gt;electron&lt;/em&gt;. These give us the objects necessary to create the app itself.&lt;br&gt;
The &lt;em&gt;path&lt;/em&gt; gives us access to the user's directory folders.&lt;br&gt;
Lastly is the &lt;em&gt;process&lt;/em&gt;. This object gives us access to the user's system info. And the &lt;em&gt;env&lt;/em&gt; object can be used to check if we are in develop-mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Menu&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;electron&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;is_mac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;darwin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;is_windows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;win32&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;is_linux&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;linux&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;is_dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's create an object containing the menu of our app. There are some default functions we can use, to use those, use the &lt;em&gt;role&lt;/em&gt; key. &lt;br&gt;
The &lt;em&gt;accelerator&lt;/em&gt; key indicates a keyboard shortcut.&lt;br&gt;
Here we install a &lt;code&gt;reload&lt;/code&gt; functionality, to quickly reload to see new changes in the front-end; and a &lt;code&gt;quit-app&lt;/code&gt; functionality, well to fully close the app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;my_main_menu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;submenu&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Quit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;quit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;accelerator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;is_mac&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cmd+W&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;Ctrl+W&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;forceReload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;accelerator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;is_mac&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cmd+R&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;Ctrl+R&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="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Functions:
&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;create_window&lt;/em&gt; function sets up an app window. It takes the name of the file to render there.&lt;br&gt;
As you can see it creates a window with given width and height and title. It is also preloading the &lt;em&gt;preload.js&lt;/em&gt; here.&lt;br&gt;
It also checks whether or not we are in develop-mode and opens a chrome devtools if so. The way we create the devtools here is a fix, as we saw in &lt;a href="https://dev.to/scriptjayt/the-electron-saga-0-my-first-app-45jg"&gt;Electron Saga 0&lt;/a&gt;".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;create_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;my_window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My Lab&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;webPreferences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;contextIsolation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;nodeIntegration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preload.js&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;my_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loadFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`./front/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.html`&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;is_dev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;my_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setDevToolsWebContents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;my_window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webContents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openDevTools&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;detach&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;set_menu&lt;/em&gt; function takes an object and creates a menu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;set_menu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_menu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buildFromTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_menu&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;Menu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setApplicationMenu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;M&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Events:
&lt;/h3&gt;

&lt;p&gt;These events trigger when opening the app and closing the app.&lt;br&gt;
For a deepdive, I suggest looking at the documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ready&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;create_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;set_menu&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;my_main_menu&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;activate&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="o"&gt;=&amp;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;BrowserWindow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAllWindows&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;create_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window-all-closed&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="o"&gt;=&amp;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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;is_mac&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quit&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  First Load
&lt;/h2&gt;

&lt;p&gt;Lets edit the &lt;em&gt;index.html&lt;/em&gt; in our &lt;em&gt;front&lt;/em&gt; folder to see something; some may notice a new meta-tag; the "http-equiv" is needed for applications.&lt;/p&gt;

&lt;p&gt;And to prevent red squibly lines when the chrome-engine doesn't recognize a word, the &lt;em&gt;spellcheck="false"&lt;/em&gt; on the &lt;em&gt;&lt;/em&gt; tag does wonders.&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="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt; &lt;span class="na"&gt;spellcheck=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"Content-Security-Policy"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"script-src 'self' 'unsafe-inline';"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

   &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My Lab&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we run the command &lt;code&gt;npm start&lt;/code&gt; and a new window should open and it should greet us with the Hello World message we set.&lt;/p&gt;

&lt;p&gt;Finaly, caught up.&lt;br&gt;
There still is some stuff like the preload.js we need to take a look at, and even further down the line what the &lt;em&gt;sheets&lt;/em&gt; folder is for.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>electron</category>
      <category>writing</category>
      <category>showdev</category>
    </item>
    <item>
      <title>The Electron Saga 0️⃣: My First App</title>
      <dc:creator>Jace</dc:creator>
      <pubDate>Mon, 10 Oct 2022 16:00:42 +0000</pubDate>
      <link>https://dev.to/scriptjayt/the-electron-saga-0-my-first-app-45jg</link>
      <guid>https://dev.to/scriptjayt/the-electron-saga-0-my-first-app-45jg</guid>
      <description>&lt;p&gt;I've always wanted to make a desktop app. ✨&lt;br&gt;
Ever since I started my webdev journey.&lt;br&gt;
But I currently have other projects to finish, and a responsible dev would not start one project before all others are done, right?&lt;br&gt;
Right.&lt;/p&gt;

&lt;p&gt;But I am not a responsible dev, so I am building a desktop app now.&lt;/p&gt;
&lt;h2&gt;
  
  
  ~Let's Start: What to make?
&lt;/h2&gt;

&lt;p&gt;Something small, (my other projects are giving me the stink eye already 👀). But not too small, it still has to be usefull.&lt;br&gt;
An app I could use every day, for work; I thought. &lt;br&gt;
But what functions does it need to have? Let's start simple, A todo-list. I have written a webcomponent for todo-lists in Typescript before, should make things a bit easier.&lt;br&gt;
So that is our goal, an app with a todo-function.&lt;/p&gt;
&lt;h3&gt;
  
  
  What to use?
&lt;/h3&gt;

&lt;p&gt;My knowledge on app-developing is limited to non-existent. I have only worked with web-technologies before, like HTML, CSS, Javascript... So learning a complete new language is not ideal. At least not for a quick sideproject like this, I should say. So I was looking for frameworks that use web-technologies for app-developing; and I found two: &lt;strong&gt;&lt;em&gt;Electron&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Tauri&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Electron&lt;/em&gt;&lt;/strong&gt; is bigger, slower, but more consistent on different devices, since it carries its own machine to run on (chromium, I believe).&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Tauri&lt;/em&gt;&lt;/strong&gt; on the other hand is said to be smaller and faster, because it doesn't carry its own machine and uses one present on the OS. This however has the drawback of it not beeing as consistent.&lt;/p&gt;

&lt;p&gt;In the end I did choose Electron, since it has more documentation to work off. Given this is my first project, it's the safer choice. But after this I'll most certainly give Tauri a chance.&lt;/p&gt;

&lt;p&gt;So I went in search of a tutorial to start off of and familiarize myself with the framework. I found this one, it's pretty great.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ML743nrkMHw"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;small&gt;Video by Traversy Media&lt;/small&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  ~Setup
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A dev is set up to encounter errors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I cloned the quick-start directory from Electron's &lt;a href="https://github.com/electron/electron-quick-start"&gt;github&lt;/a&gt; and spun up my node-js.&lt;br&gt;
No problems there. 🦾&lt;/p&gt;

&lt;p&gt;I followed the tutorial to set up the Main frame of the app and everything worked as expected; but after a while this error message appeared in my terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[9532:1010/142156.863:ERROR:gpu_init.cc(521)] Passthrough is not supported, GL is disabled, ANGLE is
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Odd, never seen this one. 🧐&lt;br&gt;
When the interwebs didn't return more than a void function would, even after an hour of searching, I gave up. It didn't seem to impact my workflow, so... ¯_(ツ)_/¯.&lt;br&gt;
I did find some other people who got the same error message, all using a different setup and even a different OS; so no fix there. &lt;br&gt;
If anyone knows what might cause this error and how to mend it, by all means, leave a comment.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Main Frame
&lt;/h3&gt;

&lt;p&gt;I got back to assembling the main frame and got it running without any issue. I could open the app, close the app... But I could not yet inspect the innards of the app.&lt;/p&gt;

&lt;p&gt;Since Electron is web-based it is possible to use devtools like you would on a website, which is great for debugging. So I implemented the function to automaticly open the devtools when launching the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my_window.webContents.openDevTools();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it worked... until it didn't.🙀 Once I closed the app and reopened it, the devtools would not show again.&lt;/p&gt;

&lt;p&gt;I got stuck. I could not figure out what was going on. From one moment to the next the tools stopped working. &lt;br&gt;
Traversy Media did not seem to get the same issue. So, just me?&lt;br&gt;
"Perhaps Electronmon is acting up, so try disabling that."&lt;br&gt;
"No that isn't it. It doesn't even work just running Electron."&lt;br&gt;
I deleted and restarted the whole project three times, only to get the same issue again and again. The first devtools launch worked, every following failed.&lt;/p&gt;
&lt;h2&gt;
  
  
  ~Got there in the end. 😸
&lt;/h2&gt;

&lt;p&gt;So, sleep helps. After taking a break for the weekend I came back to this function and went straight to the github issues of Electron and found that it was a recurring problem.&lt;br&gt;
This time the interwebs did return something! A workaround:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dev = new BrowserWindow();
my_window.webContents.setDevToolsWebContents(dev.webContents);
my_window.webContents.openDevTools({ mode: "detach" });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can't really explain why this works while the other one didn't but it is working now, so let's not touch it.&lt;br&gt;
It's time to set up the front-end of our app...&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>showdev</category>
      <category>writing</category>
    </item>
    <item>
      <title>JS Errors in the Console, with a twist</title>
      <dc:creator>Jace</dc:creator>
      <pubDate>Sat, 01 Oct 2022 12:04:38 +0000</pubDate>
      <link>https://dev.to/scriptjayt/js-errors-in-the-console-with-a-twist-25mb</link>
      <guid>https://dev.to/scriptjayt/js-errors-in-the-console-with-a-twist-25mb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Oh no! My site, it's broken!&lt;br&gt;
What ever shall I do? Better open the console to see what's wrong...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  It happens
&lt;/h2&gt;

&lt;p&gt;Errors happen, so we have to handdle them. And since javascript has the console-object, most if not all js-developers use it. &lt;br&gt;
Yet having console errors littered around on your site is not great, (I could be wrong but) it might even influence your SEO score in search engines, so some delegating is in order.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better not flood the user's console
&lt;/h2&gt;

&lt;p&gt;Flooding the console of a regular user with errors and exceptions is rather inefficient and unnecessary. They don't know how to open the developer tools, never mind navigate to the console.&lt;br&gt;
The only thing website-users need to know is whether or not all interactive functions on the site work, that's it. And that can be done by showing just a &lt;em&gt;"Something has gone wrong"&lt;/em&gt; message in a nice and well designed pop-up.&lt;/p&gt;

&lt;h2&gt;
  
  
  But a flood for them is a sip for me.
&lt;/h2&gt;

&lt;p&gt;Yes, developers do use and need the console for first line debugging, users do not. &lt;br&gt;
So let's hide all messages from the console unless a developer visits the site. A dumbed-down developer-mode if you wish.&lt;/p&gt;

&lt;p&gt;First, convert all loud errors into silent ones. Use the try-catch block to exit the function early when something goes wrong and show a simple error message to the user. That's better than crashing the whole thread, wouldn't you say?&lt;/p&gt;

&lt;p&gt;Great! But now the developer can't assess any errors though. To remedy, let's create our own console function:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const dev_log = ()=&amp;gt;{}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This function is going to pass a message to the console if and only if a condition is met. Otherwise it will exit the function early with &lt;code&gt;return&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const dev_log = (_error) =&amp;gt; {&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;if(!*condition*) return;&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;console.log(_error);&lt;/code&gt;&lt;br&gt;
&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But what condition? You could use any: login, ip-address, local host... Or whatever floats your boat.&lt;br&gt;
I like checking the hash in the url, you know: &lt;code&gt;yoursite.com#hash&lt;/code&gt;.&lt;br&gt;
It's the easiest to set up and has no real implications for the website, since the hash is mostly used to highlight articles, or navigate one-pagers.&lt;br&gt;
So let's do that. You can access that hash from the location-object.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const dev_log = (_error) =&amp;gt; {&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;const is_debugging = location.hash == "dev";&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;if(!is_debugging) return;&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;console.log(_error);&lt;/code&gt;&lt;br&gt;
&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And that's it. Now the only thing left is to call this function every time we try and catch errors;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;try {&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;foo();&lt;/code&gt;&lt;br&gt;
&lt;code&gt;}&lt;/code&gt;&lt;br&gt;
&lt;code&gt;catch(error){&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;show_error_to_user();&lt;/code&gt;&lt;br&gt;
  &lt;code&gt;dev_log(error);&lt;/code&gt;&lt;br&gt;
&lt;code&gt;}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ofcourse you could expand the function to support multiple types of console functions like &lt;code&gt;console.error&lt;/code&gt;, &lt;code&gt;console.group&lt;/code&gt; or &lt;code&gt;console.time&lt;/code&gt; even, make it fit your needs.&lt;/p&gt;

&lt;p&gt;So now only visitors using &lt;code&gt;yoursite.com#dev&lt;/code&gt; will be able to inspect any errors you logged to the console.&lt;br&gt;
What do you think?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
