<?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: Saurabh Daware 🌻</title>
    <description>The latest articles on DEV Community by Saurabh Daware 🌻 (@saurabhdaware).</description>
    <link>https://dev.to/saurabhdaware</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%2F174161%2Fe04efa48-2ea8-42ba-82a0-824e81857d50.png</url>
      <title>DEV Community: Saurabh Daware 🌻</title>
      <link>https://dev.to/saurabhdaware</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saurabhdaware"/>
    <language>en</language>
    <item>
      <title>I made a Profile Card Widget for Bluesky 🦋</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Sun, 24 Nov 2024 15:45:56 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/i-made-a-profile-card-widget-for-bluesky-268e</link>
      <guid>https://dev.to/saurabhdaware/i-made-a-profile-card-widget-for-bluesky-268e</guid>
      <description>&lt;p&gt;Hey there! 👋 It’s been a while since my last post here—four years, to be exact. But I’m back, excited to share something cool I built: a Profile Card Widget for Bluesky!&lt;/p&gt;

&lt;p&gt;Lets get to the topic! I recently joined Bluesky and I was exploring their APIs and I realised, what if we could render our bluesky's profile into our websites. &lt;/p&gt;

&lt;p&gt;This is something that I had done in the past by creating dev.to widget for this platform.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/saurabhdaware" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F174161%2Fe04efa48-2ea8-42ba-82a0-824e81857d50.png" alt="saurabhdaware"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/saurabhdaware/i-made-dev-to-widget-for-websites-blogs-40p2" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;I made DEV.to widget for websites/blogs&lt;/h2&gt;
      &lt;h3&gt;Saurabh Daware 🌻 ・ Oct 20 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#showdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Just like dev.to widget, I want bsky-widget to work in all frameworks and setups without me having to write libraries for each and every one of them so I went with the same approach as dev.to widget, web components!!&lt;/p&gt;

&lt;p&gt;I'll probably write a different article on web components if you all are interested. Until then, here's how you can use bsky-widget&lt;/p&gt;

&lt;h2&gt;
  
  
  Here's how it looks like
&lt;/h2&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/bsky-widget-vanilla-project?embed=1&amp;amp;file=index.html" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use &lt;code&gt;bsky-widget&lt;/code&gt;?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  In Vanilla Projects
&lt;/h3&gt;

&lt;p&gt;You just need 2 lines of code to use &lt;code&gt;bsky-widget&lt;/code&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="c"&gt;&amp;lt;!-- Use your bluesky profile handle --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;bsky-widget&lt;/span&gt; &lt;span class="na"&gt;handle=&lt;/span&gt;&lt;span class="s"&gt;"srbh.dev"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/bsky-widget&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Paste before end of body --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script 
  &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/bsky-widget@~0.1/dist/index.js"&lt;/span&gt; 
  &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  In Frameworks
&lt;/h3&gt;

&lt;p&gt;In frameworks, you can skip adding &lt;code&gt;&amp;lt;script src=""&amp;gt;&lt;/code&gt; and instead follow this-&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; bsky-widget@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// along with other imports of framework&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bsky-widget&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="c1"&gt;// Wherever you want to render the card&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;bsky&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;widget&lt;/span&gt; &lt;span class="nx"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;srbh.dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/bsky-widget&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  React Example
&lt;/h4&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/bsky-widget-react-example?ctl=1&amp;amp;embed=1&amp;amp;file=src%2FApp.tsx" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;
&lt;h2&gt;
  
  
  Customization
&lt;/h2&gt;

&lt;p&gt;Checkout &lt;a href="https://github.com/saurabhdaware/bsky-widget?tab=readme-ov-file#override-styles" rel="noopener noreferrer"&gt;Override Styles Documentation&lt;/a&gt; to know which CSS variables and styles can be overriden&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-N41svdVew4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Thanks for reading! Let me know if you all are interested in an article on web components and how I used it for bsky-widget.&lt;/p&gt;

&lt;p&gt;Do ⭐️ the repo or build your own card using the link below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/saurabhdaware/bsky-widget" rel="noopener noreferrer"&gt;https://github.com/saurabhdaware/bsky-widget&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Card Generator: &lt;a href="https://bsky-widget.srbh.dev/" rel="noopener noreferrer"&gt;https://bsky-widget.srbh.dev/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;
        saurabhdaware
      &lt;/a&gt; / &lt;a href="https://github.com/saurabhdaware/bsky-widget" rel="noopener noreferrer"&gt;
        bsky-widget
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Unofficial Bluesky widget to render cute profile cards in your websites ^_^
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Bluesky Widget&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Unofficial Bluesky Profile Cards for Bluesky Friends 🦋&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Card Generator UI: &lt;a href="https://bsky-widget.srbh.dev/" rel="nofollow noopener noreferrer"&gt;https://bsky-widget.srbh.dev/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
  &lt;th&gt;Code&lt;/th&gt;
&lt;br&gt;
  &lt;th&gt;Preview&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;

&lt;div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&amp;lt;!-- Paste in your CSS to avoid layout shift --&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;style&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;
  bsky-widget {
    min-height: 387px;
    width: 350px;
  }
&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;style&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="pl-c"&gt;&amp;lt;!-- Paste wherever you want to render the card --&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;bsky-widget&lt;/span&gt; &lt;span class="pl-c1"&gt;handle&lt;/span&gt;="&lt;span class="pl-s"&gt;patak.dev&lt;/span&gt;"&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;bsky-widget&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="pl-c"&gt;&amp;lt;!-- Paste before end of body --&amp;gt;&lt;/span&gt;
&lt;span class="pl-kos"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt;
  &lt;span class="pl-c1"&gt;src&lt;/span&gt;="&lt;span class="pl-s"&gt;https://unpkg.com/bsky-widget@~0.1/dist/index.js&lt;/span&gt;"
  &lt;span class="pl-c1"&gt;type&lt;/span&gt;="&lt;span class="pl-s"&gt;module&lt;/span&gt;"
&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;script&lt;/span&gt;&lt;span class="pl-kos"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/saurabhdaware/bsky-widget/.github/repo-assets/card-preview.png"&gt;&lt;img alt="Patak's Bluesky Profile Widget" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fsaurabhdaware%2Fbsky-widget%2F.github%2Frepo-assets%2Fcard-preview.png" width="300px"&gt;&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage as NPM module&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Install&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install bsky-widget@latest --save&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Import and Use&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s"&gt;"bsky-widget"&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;

&lt;span class="pl-c1"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-ent"&gt;bsky-widget&lt;/span&gt; &lt;span class="pl-c1"&gt;handle&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"srbh.dev"&lt;/span&gt;&lt;span class="pl-c1"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-c1"&gt;&amp;lt;&lt;/span&gt;&lt;span class="pl-c1"&gt;/&lt;/span&gt;&lt;span class="pl-ent"&gt;bsky-widget&lt;/span&gt;&lt;span class="pl-c1"&gt;&amp;gt;&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Props&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Prop&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Example value&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;handle&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;handle of your bluesky account&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;"srbh.dev"&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;show-description&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;hide / show your description / bio from profile&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;"true" (default) or "false"&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;show-banner&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;hide / show your banner (only applicable if you have a banner)&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;"true" (default) or "false"&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/saurabhdaware/bsky-widget" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;&lt;a href="https://bsky-widget.srbh.dev/" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Generate your own Bluesky profile card&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>webcomponents</category>
    </item>
    <item>
      <title>The Evolution of FrontEnd Development🌻: What is WebPack, Babel, and Build-steps in Frameworks.</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Sun, 15 Nov 2020 13:28:42 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/the-evolution-of-frontend-development-what-is-webpack-babel-and-build-steps-in-frameworks-3gj2</link>
      <guid>https://dev.to/saurabhdaware/the-evolution-of-frontend-development-what-is-webpack-babel-and-build-steps-in-frameworks-3gj2</guid>
      <description>&lt;p&gt;There have been several advances in the web in recent years and in this post, I will talk about the tools that I feel have made a significant impact on how we build websites today.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Do note that this post is not intended to teach or help you set up these tools. This is an introduction and a top-level view of what they do and why they do. For detailed information, you can check out their respective documentations.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lets talk about the basic web!
&lt;/h2&gt;

&lt;p&gt;This is how we build small websites right? this is something that our browsers understand without any need for external tools.&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&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;p&amp;gt;&lt;/span&gt;Hello!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./index.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;/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;This was working great for a long time! so what went wrong? &lt;/p&gt;

&lt;p&gt;The websites became larger and more dynamic so the responsibility of JavaScript increased. &lt;/p&gt;

&lt;h2&gt;
  
  
  Problem with Maintainability
&lt;/h2&gt;

&lt;p&gt;Now imagine a code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&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;input&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"name-input"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./jquery.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;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./helpers.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;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./main.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;/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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isInputURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input.name-input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;val&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;isInputURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wai-wai-waittt where did &lt;code&gt;isURL&lt;/code&gt; function come from? What is even &lt;code&gt;$&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Imagine having multiple scripts like these and you find out one function is wrong. How do you find and debug that function?&lt;/p&gt;

&lt;p&gt;This can eventually lead to a huge mess so we needed a more scalable solution.&lt;/p&gt;

&lt;p&gt;Let's look into this code instead:&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="c"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&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;input&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"name-input"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- ... --&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./main.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;/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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jquery&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;isURL&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="s1"&gt;./helpers.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isInputURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input.name-input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;val&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;isInputURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code becomes a lot more readable and maintainable.&lt;/p&gt;

&lt;p&gt;However, the browser did not understand this code so we needed a way where we can write this code, and eventually output the code that browsers understand. &lt;/p&gt;

&lt;p&gt;This is what Webpack does! &lt;/p&gt;

&lt;p&gt;Now we do have &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules" rel="noopener noreferrer"&gt;native modules in JavaScript&lt;/a&gt;. However, webpack provides additional things like bundling the scripts into a single file, importing CSS and other types of files from modules, and a lot of other things.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://webpack.js.org/guides/getting-started/" rel="noopener noreferrer"&gt;Getting Started Guide of Webpack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! so webpack provided us with a way to write modulated code that is easier to maintain.&lt;/p&gt;

&lt;p&gt;Next problem we had was browser compatibility. &lt;/p&gt;

&lt;h2&gt;
  
  
  Problem with Browser Compatibility
&lt;/h2&gt;

&lt;p&gt;Different browsers use different engines for JavaScript. They all have different behaviours and old browser engines do not have the ability to understand the newly released syntax.&lt;/p&gt;

&lt;p&gt;In 2015, a new version of &lt;a href="https://www.freecodecamp.org/news/write-less-do-more-with-javascript-es6-5fd4a8e50ee2/" rel="noopener noreferrer"&gt;JavaScript (ES6)&lt;/a&gt; was released which came with a number of features that were absolutely needed in language. However, these features did not work in old browsers. &lt;/p&gt;

&lt;p&gt;From &lt;a href="https://babeljs.io/docs/en/" rel="noopener noreferrer"&gt;Babel's documentation&lt;/a&gt;-&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards-compatible version of JavaScript in current and older browsers or environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So this code from ES2020 version-&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Becomes this-&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JavaScript Frameworks/Libraries
&lt;/h2&gt;

&lt;p&gt;As mentioned earlier, today's web is more dynamic and thus the JavaScript has more responsibilities. &lt;/p&gt;

&lt;p&gt;We can use jQuery by just including it with script, right?&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&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://code.jquery.com/jquery-3.5.1.min.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;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then why we don't do it with React, Vue, and other frameworks? &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fun Fact!&lt;/strong&gt; We actually can use them with CDN. &lt;br&gt;
For example, we can use React with CDN using-&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&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;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/babel-standalone@6/babel.min.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;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/react@16/umd/react.development.js"&lt;/span&gt; &lt;span class="na"&gt;crossorigin&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;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/react-dom@16/umd/react-dom.development.js"&lt;/span&gt; &lt;span class="na"&gt;crossorigin&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;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/babel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;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;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#root&lt;/span&gt;&lt;span class="dl"&gt;'&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;Okayyyy but then why we don't use it like this?&lt;/p&gt;

&lt;p&gt;Frameworks today recommend an additional build step that lets them do the optimizations and provides better control.&lt;/p&gt;

&lt;p&gt;Most of the JavaScript frameworks, in one way or the other, use webpack, Babel or their equivalents in development and build process.&lt;/p&gt;

&lt;p&gt;Apart from just bundling, Frameworks provide additional functionality by making use of webpack and babel plugins.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vue&lt;/strong&gt; for example, uses a webpack plugin called &lt;a href="https://www.npmjs.com/package/vue-loader" rel="noopener noreferrer"&gt;vue-loader&lt;/a&gt; for &lt;a href="https://github.com/vuejs/vue-loader/blob/HEAD/docs/spec.md" rel="noopener noreferrer"&gt;Single File Components&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Babel, Apart from just converting code to backwards-compatible version, can also transpile different syntaxes. For &lt;strong&gt;React&lt;/strong&gt;, babel converts &lt;code&gt;JSX&lt;/code&gt; to &lt;code&gt;React.createElement&lt;/code&gt; calls.&lt;/p&gt;

&lt;p&gt;So, this-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;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;becomes-&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;App&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;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello&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;In the earlier example of React on CDN, this step was happening on frontend whereas here, this happens on &lt;code&gt;npm run build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://babeljs.io/docs/en/plugins/" rel="noopener noreferrer"&gt;List of Babel Plugins&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Thank you for reading the article 🌻&lt;/p&gt;

&lt;p&gt;Also, In the article, I only mentioned webpack since it is popular but there are also other alternatives like &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt;, &lt;a href="https://rollupjs.org/guide/en/" rel="noopener noreferrer"&gt;Rollup&lt;/a&gt;, and many more tools which perform similar operations.&lt;/p&gt;

&lt;p&gt;Finally, Our needs are changing and so does the tools and the language and it's super exciting to be in this time and experience these tools and libraries making our lives easier. &lt;/p&gt;

&lt;p&gt;Big thanks to all the people maintaining and contributing to these amazing projects &amp;lt;3&lt;/p&gt;

&lt;p&gt;Do you know any other tool that you think has changed the web? drop them in the comments 👇&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A Guide for Contributing to Any Open Source JavaScript Project Ever 💛</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Sat, 04 Jul 2020 17:01:53 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/a-guide-for-contributing-to-any-open-source-javascript-project-ever-hi</link>
      <guid>https://dev.to/saurabhdaware/a-guide-for-contributing-to-any-open-source-javascript-project-ever-hi</guid>
      <description>&lt;p&gt;Lately, I had people asking how can they contribute to open-source projects when the codebase is large, or issues are taken, or good first issues seem difficult. &lt;/p&gt;

&lt;p&gt;Initially, I've faced these questions as well and In this article, I will talk about how we can explore repositories, find the right issues to work on, and I will also try to answer some of the questions I just mentioned. 🐨🌻&lt;/p&gt;

&lt;p&gt;Let's goooo 🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Table of Content&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finding the Right Repository&lt;/li&gt;
&lt;li&gt;
Finding the Right Issue

&lt;ul&gt;
&lt;li&gt;Q. Every issue is taken, how do we find one?&lt;/li&gt;
&lt;li&gt;Q. Did find an issue but it seems difficult&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Exploring Code

&lt;ul&gt;
&lt;li&gt;Q. CODEBASES ARE HUGEE! How can we understand the whole codebase?&lt;/li&gt;
&lt;li&gt;Finding the right files in the code&lt;/li&gt;
&lt;li&gt;Projects that require additional knowledge&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Some Useful Links&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Finding the Right Repository 🕵
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Contribute to something you use or find something that excites you and play around it before trying to contribute.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I will highly suggest using the tool/library/website, before contributing to it. This will give you a nice overview of what it does and how it works.&lt;/p&gt;

&lt;p&gt;If you're uncomfortable with the process of making PR, you can first contribute to &lt;a href="https://github.com/firstcontributions/first-contributions" rel="noopener noreferrer"&gt;First Contributions Repository&lt;/a&gt;. You have to add your name to the list and send a PR! They have a nice guide to explain the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Finding the Right Issue 📚
&lt;/h2&gt;

&lt;p&gt;In the issues section, you will find issues that have &lt;code&gt;good first issue&lt;/code&gt; tag. Though it is not necessary, it is usually a sign from maintainers that 'hey these issues are relatively easy to tackle'. If you find any other issue that excites you more, go for it!&lt;/p&gt;

&lt;p&gt;I will suggest trying to find issues related to documentation since they will be easier to get started but if you couldn't find such issues, that's ok as well you can pick whichever you like. As you get comfortable with the repository, you can go on picking more challenging issues.&lt;/p&gt;

&lt;p&gt;And before we move forward, I know you might've heard this a lot and I am probably the 1000th person saying this but&lt;/p&gt;

&lt;p&gt;🎉 &lt;strong&gt;EVERY. CONTRIBUTION. MATTERS&lt;/strong&gt; 🎉&lt;/p&gt;

&lt;p&gt;Even a spelling fix in documentation is a huge help to maintainers and you should totally be proud of such contributions!&lt;/p&gt;

&lt;p&gt;Here's something I am proud of:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foaqu0t3fo8odcuu65h32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foaqu0t3fo8odcuu65h32.png" alt="A screenshot of GitHub diff in my Pull Request that shows I only removed an additional bracket from the documentation" width="696" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There was an extra bracket in the editor guide of DEV.to and I removed it :D&lt;/p&gt;

&lt;p&gt;PR: &lt;a href="https://github.com/thepracticaldev/dev.to/pull/4500"&gt;https://github.com/thepracticaldev/dev.to/pull/4500&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Q. Every issue is taken, how do we find one?
&lt;/h3&gt;

&lt;p&gt;A lot of times in popular open-source projects, you will find that most of the good first issues are taken and someone is already working on them. In this case, you can join their chat channels. Projects use Slack, Discord, Spectrum, GitHub Discussions, or other chat channels where you can ask for help. In those chat channels, you can drop a message asking for help in finding issues. Maintainers will then help you in finding an issue for you.&lt;/p&gt;
&lt;h3&gt;
  
  
  Q. Did find an issue but it seems difficult...
&lt;/h3&gt;

&lt;p&gt;This is very normal and even if you are experienced in contributing, you will likely find issues difficult in the first look when you're trying to contribute to a new organization.&lt;/p&gt;

&lt;p&gt;You can always ask for help in comments of issues. Maintainers will then help you debug the problem and can point you to the right files that need changes but try exploring it yourself before asking for help.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Exploring Code 🤠
&lt;/h2&gt;

&lt;p&gt;Before you start exploring the code, always read CONTRIBUTING.md file in the repository (If a repository does not have CONTRIBUTING.md, whoop whoop 🎉 That's your chance to send a Pull Request that adds CONTRIBUTING.md). It usually has a local setup guide and other information that you may need for contributing. You can either set it up locally and then explore, or explore on the GitHub itself and then do a local setup to make changes.&lt;/p&gt;

&lt;p&gt;I prefer exploring locally since you get to play around and execute the code.&lt;/p&gt;

&lt;p&gt;Awesome so now you've,&lt;br&gt;
🗸 Decided the issue that you want to work on&lt;br&gt;
🗸 Read the CONTRIBUTING.md&lt;/p&gt;

&lt;p&gt;Now we exploreeeee yayyyyy!!! oh.. but wait..&lt;/p&gt;
&lt;h3&gt;
  
  
  Q. CODEBASES ARE HUGEE! How can we understand the whole codebase?
&lt;/h3&gt;

&lt;p&gt;Fun fact, &lt;strong&gt;You don't have to understand the whole code 🎉&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You will only have to care about the code that is related to the issue you've chosen.&lt;/p&gt;
&lt;h3&gt;
  
  
  3a. Finding the right files in the code.
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Tip: In VSCode, you can CTRL + SHIFT + F to find something in a complete project or On GitHub, you can use the search bar to find the related code.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  In websites/frontend repositories
&lt;/h4&gt;

&lt;p&gt;If the project you're contributing to is a website, you can search for the words you see on the interface. E.g. If you want to contribute to the navigation bar of DEV, you can search for "Write a Post" button.&lt;/p&gt;

&lt;p&gt;If it is not a website you can start finding the related functions by following the imports starting with an entry file.&lt;/p&gt;
&lt;h4&gt;
  
  
  In libraries, NPM Packages, and CLIs
&lt;/h4&gt;

&lt;p&gt;In NPM packages, you would find package.json that has &lt;code&gt;main&lt;/code&gt; attribute, the value of the &lt;code&gt;main&lt;/code&gt; is the file that gets imported when you import/require that NPM package. &lt;/p&gt;

&lt;p&gt;If you're contributing to a CLI, you would find &lt;code&gt;bin&lt;/code&gt; in package.json that points to the file which is executed when you run a CLI command.&lt;/p&gt;
&lt;h4&gt;
  
  
  Mono-repos
&lt;/h4&gt;

&lt;p&gt;Some projects like React, Gatsby, Next follow a mono repo. They have all the related projects in the same repository. In such projects, you would most probably find a folder called &lt;code&gt;packages&lt;/code&gt; on root level and inside the &lt;code&gt;packages&lt;/code&gt; you would find a folder with the name of the npm library (e.g &lt;code&gt;packages/react&lt;/code&gt;, &lt;code&gt;packages/next&lt;/code&gt;, &lt;code&gt;packages/gatsby&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;If you see the package.json file inside these packages, you would find the &lt;code&gt;main&lt;/code&gt; key that points to the file which exports the functions that we usually import from these libraries.&lt;/p&gt;
&lt;h5&gt;
  
  
  Example
&lt;/h5&gt;

&lt;p&gt;If you've used React, we usually import &lt;code&gt;useEffect&lt;/code&gt; and other hooks like this, right?&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;useEffect&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="s1"&gt;react&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;Which means the package react must be exporting the &lt;code&gt;useEffect&lt;/code&gt; function 🤔&lt;/p&gt;

&lt;p&gt;Let's find out!&lt;/p&gt;

&lt;p&gt;As I've mentioned earlier, the mono-repos usually have a &lt;code&gt;packages&lt;/code&gt; folder and inside that there is a package with the name of the NPM library ('react' in this case). So let's go inside &lt;code&gt;packages/react/&lt;/code&gt; 🚀&lt;/p&gt;

&lt;p&gt;Now we want to find the entry file so we will look into &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/facebook/react/blob/master/packages/react/package.json" rel="noopener noreferrer"&gt;Package.json of React&lt;/a&gt; has &lt;code&gt;{'main': 'index.js'}&lt;/code&gt; which means everything that we import from &lt;code&gt;react&lt;/code&gt; package, has to be exported from &lt;code&gt;index.js&lt;/code&gt;. Let's see if it has &lt;code&gt;useEffect&lt;/code&gt; function!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flp6kau9cp9bp9mn1nhh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flp6kau9cp9bp9mn1nhh6.png" alt="A screenshot of index.js file that shows it actually has useEffect function in exports" width="324" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whoop whoop 🎉 Yes it does!&lt;/p&gt;

&lt;p&gt;Now you can follow the imports to that function to find a file that handles useEffect logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  3b. Projects that require additional knowledge
&lt;/h3&gt;

&lt;p&gt;If you've been building websites and webapps and then see the source code of React, the code will look different. Some repositories require knowledge of few additional topics which you may not come across otherwise. &lt;/p&gt;

&lt;p&gt;Some projects are built on top of &lt;a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="noopener noreferrer"&gt;Abstract Syntax Trees&lt;/a&gt; whereas some repositories use a different language/libraries. &lt;/p&gt;

&lt;p&gt;It is likely that you will find this code difficult in first look but more than difficult, it is different. It is different from what we JavaScript developers usually come across.&lt;/p&gt;

&lt;p&gt;You can spend some time playing around the codebase and if you get stuck, you can always ask questions to the maintainers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Useful Links
&lt;/h2&gt;

&lt;h3&gt;
  
  
  GitHub Repositories for Initial Contributions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/firstcontributions/first-contributions" rel="noopener noreferrer"&gt;First Contributions GitHub Repository&lt;/a&gt; - This is great to actually practice sending Pull Request (Fun Fact: I too started here :D)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/knaxus" rel="noopener noreferrer"&gt;Knaxus GitHub Organization&lt;/a&gt; - The aim is similar to first contributions but they will let you contribute to actual coding projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resources to learn git and GitHub
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;YouTube Video, "Contributing to Open Source on GitHub for Beginners" by &lt;a href="https://twitter.com/kentcdodds" rel="noopener noreferrer"&gt;Kent C. Dodds&lt;/a&gt;
&lt;a href="https://youtu.be/k6KcaMffxac" rel="noopener noreferrer"&gt;https://youtu.be/k6KcaMffxac&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;YouTube Video, "git_basics - The basics that you need for Git &amp;amp; GitHub!" by &lt;a href="https://twitter.com/harshgkapadia" rel="noopener noreferrer"&gt;Harsh Kapadia&lt;/a&gt;
&lt;a href="https://youtu.be/HF12-91iazM" rel="noopener noreferrer"&gt;https://youtu.be/HF12-91iazM&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Resources to learn git by GitHub
&lt;a href="https://try.github.io/" rel="noopener noreferrer"&gt;https://try.github.io/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thank you for reading this 🎉 If you have any questions about git, GitHub, or contributing, you can ask them in comments or reach out to me on my &lt;a href="https://twitter.com/saurabhcodes" rel="noopener noreferrer"&gt;Twitter DMs @saurabhcodes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;🌻🌻🌻🌻&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Hey you, talk about your side-projects!</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Fri, 29 May 2020 08:19:01 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/hey-you-talk-about-your-side-projects-7eh</link>
      <guid>https://dev.to/saurabhdaware/hey-you-talk-about-your-side-projects-7eh</guid>
      <description>&lt;p&gt;Around 3 years ago, I started using GitHub. Though I've been working on some super cool projects, for 2 years all of these projects went unnoticed. The highest stars on my GitHub repository were 9 (8 classmates + me).&lt;/p&gt;

&lt;p&gt;Why? Apart from sharing it with a few other classmates, I never really talked about these projects anywhere.&lt;/p&gt;

&lt;p&gt;In this article, I am going to talk about how you can share your project so that it will reach a larger audience. Before that, here are some stats to convince you how it has helped me✨&lt;/p&gt;

&lt;p&gt;Last year in August, I joined DEV and shared my side-project "PWAinit" here, and guess what? I got 10+ stars in a week!! Since then, I started talking about every project I build through articles, tweets, videos and it gave a huge boost to my GitHub babies.&lt;/p&gt;

&lt;p&gt;My recent project &lt;a href="https://github.com/saurabhdaware/text-to-handwriting" rel="noopener noreferrer"&gt;text-to-handwriting&lt;/a&gt; got 100+ stars when I shared it on Twitter! After writing an article here, the number just kept growing and it has 600+ stars today 🥺🌻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fad68sm2o0s7m7s3i9rgd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fad68sm2o0s7m7s3i9rgd.png" alt="Graph of the GitHub stars to time that shows an exponential growth after writing an article on DEV.to and tweeting about it on Twitter" width="800" height="482"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(The Graph is from &lt;a href="https://github.com/timqian/star-history" rel="noopener noreferrer"&gt;https://github.com/timqian/star-history&lt;/a&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The chances of your project being discovered from Google Search are very less unless the project is famous already. You have to talk about your project if you want people to use your project. &lt;/p&gt;

&lt;p&gt;Do you know what the coolest part is? Even if it doesn't work, you lose nothing! The best-case scenario is, people will start using your project and it will be everywhere on the internet, and The worst-case scenario is, not many people will use it but even in this case, your project will definitely be more popular than it was when you did not talk about it. win-win 🎉&lt;/p&gt;

&lt;p&gt;Awesome! so let's see what all options we have, &lt;/p&gt;

&lt;h1&gt;
  
  
  Share it with Friends, Parents, or Anyone you know. 🤗
&lt;/h1&gt;

&lt;p&gt;Talking about GitHub, to get stars on your repository, you need stars on your repository... People trust projects that are being used and already have at least some amount of stars. You can get these initial stars by sharing your project with classmates, friends, and parents.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm1fwfjios0ab3t99413g.png" class="article-body-image-wrapper"&gt;&lt;img alt="Cute tiny duck with a knife meme that says 'Hey fren, star my GitHub'" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm1fwfjios0ab3t99413g.png" width="749" height="807"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Tweet it out 🐦
&lt;/h1&gt;

&lt;p&gt;Twitter is a great platform to share your projects! There are a lot of people on Twitter who would love to see what you're working on and would appreciate it.&lt;/p&gt;

&lt;p&gt;If you have a cool project, then even having a few hundred or fewer followers can do wonders✨. A few months back, one of my projects got 80 retweets and 300 likes, and back then I only had around 150 followers on Twitter! Thanks to all the amazing people on Twitter🥺🌻&lt;/p&gt;

&lt;h1&gt;
  
  
  Write an Article 📖
&lt;/h1&gt;

&lt;p&gt;DEV.to is super cool to quickly start writing. DEV.to helps your project reach the relevant people. You can use appropriate tags depending on the project (#python, #javascript, #machinelearning) and your project will reach the correct people. &lt;/p&gt;

&lt;p&gt;After writing an article on DEV.to, make sure you go to the "manage" option on the right side of "edit" and Suggest a Tweet. This will help the DEV team discover your article and they may later post it on the Official Twitter handle &lt;a href="http://twitter.com/thepracticaldev" rel="noopener noreferrer"&gt;@ThePracticalDev&lt;/a&gt; and other social media accounts.&lt;/p&gt;

&lt;h1&gt;
  
  
  Talk about your project in Meetups/Conferences 🎤
&lt;/h1&gt;

&lt;p&gt;There are developer meetups that happen around the world where all the developers come together and talk about what they are working on and what they do. Some developers present what they've learned or built, in these meetups. You can apply to speak in one of these meetups and give a talk about your side project!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx6nmfh38mib8jq9ezour.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fx6nmfh38mib8jq9ezour.png" alt="Spiderman giving presentation meme that says 'Introducing Potato Maker v1.0.0-beta'" width="680" height="907"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to find a list of meetups that are happening in your city, you can check out &lt;a href="https://meetup.com" rel="noopener noreferrer"&gt;Meetup.com&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Currently, due to pandemic, most of these meetups are happening online which is even better since you can talk at a meetup happening across the globe!&lt;/p&gt;

&lt;h1&gt;
  
  
  Other ways to talk about your project
&lt;/h1&gt;

&lt;p&gt;Apart from the ones mentioned above, other ways to share your projects would be,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating 'How to' videos about your project on YouTube&lt;/li&gt;
&lt;li&gt;Reddit&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.producthunt.com/" rel="noopener noreferrer"&gt;ProductHunt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sharing it on Facebook, LinkedIn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you know any other ways to share a project, let me know in the comments!&lt;/p&gt;




&lt;p&gt;Although it's not necessary to do everything mentioned in the article, definitely do the ones that you're fine doing. &lt;/p&gt;

&lt;p&gt;Thank you and if you have any questions, you can drop me a DM on &lt;a href="https://twitter.com/saurabhcodes" rel="noopener noreferrer"&gt;my Twitter @saurabhcodes&lt;/a&gt; 🐨🎉&lt;/p&gt;

&lt;p&gt;Stay safe! and let me know your thoughts in comments 🌻&lt;/p&gt;

</description>
      <category>career</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>I made a Text-to-handwriting tool to write my college assignments for me 🤓</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Sun, 19 Apr 2020 18:50:29 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/i-made-a-text-to-handwriting-tool-to-write-my-college-assignments-for-me-4ko</link>
      <guid>https://dev.to/saurabhdaware/i-made-a-text-to-handwriting-tool-to-write-my-college-assignments-for-me-4ko</guid>
      <description>&lt;p&gt;Hi everyone, I hope you all are safe and doing fine! &lt;/p&gt;

&lt;p&gt;I prefer typing over writing and college told us to write some assignments and I was bored.&lt;/p&gt;

&lt;p&gt;So instead of spending 1 hour to write assignments, I spent 3 hours to build a tool that writes assignments for me 🎉. It is called &lt;a href="https://github.com/saurabhdaware/text-to-handwriting" rel="noopener noreferrer"&gt;Text-to-handwriting&lt;/a&gt; (see... I'm really good at naming my projects)&lt;/p&gt;

&lt;p&gt;Text to Handwriting converts text content to an image that looks like handwriting. So this is what the output looks like:&lt;/p&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fikkj6js77uyo7m0rd1ud.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fikkj6js77uyo7m0rd1ud.jpeg" alt="A picture of output from text-to-handwriting that looks very close to the picture taken of handwritten paper" width="550" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Draw diagrams&lt;/li&gt;
&lt;li&gt;Change font-size, ink color, spacing, etc.&lt;/li&gt;
&lt;li&gt;Upload font button for custom handwritings (so you can create a font of your handwriting from other online tools and upload the font file)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  URLs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tool
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://saurabhdaware.github.io/text-to-handwriting" rel="noopener noreferrer"&gt;https://saurabhdaware.github.io/text-to-handwriting&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub
&lt;/h3&gt;

&lt;p&gt;Do ⭐ the repository &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;
        saurabhdaware
      &lt;/a&gt; / &lt;a href="https://github.com/saurabhdaware/text-to-handwriting" rel="noopener noreferrer"&gt;
        text-to-handwriting
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      So your teacher asked you to upload written assignments? Hate writing assigments? This tool will help you convert your text to handwriting xD
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/67069f80bd5749a7d1977513a325baeb43e39d2dc3f832beaf39f2e59d3d78b8/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f736175726162686461776172652f696d6167652f75706c6f61642f775f3430302f76313538363031353039342f73617572616268323031392f746578742d746f2d68616e6477726974696e672d7469746c652e706e67"&gt;&lt;img alt="Text-to-handwriting title image" src="https://camo.githubusercontent.com/67069f80bd5749a7d1977513a325baeb43e39d2dc3f832beaf39f2e59d3d78b8/68747470733a2f2f7265732e636c6f7564696e6172792e636f6d2f736175726162686461776172652f696d6167652f75706c6f61642f775f3430302f76313538363031353039342f73617572616268323031392f746578742d746f2d68616e6477726974696e672d7469746c652e706e67"&gt;&lt;/a&gt; 
&lt;br&gt;&lt;b&gt;&lt;a href="https://saurabhdaware.github.io/text-to-handwriting/" rel="nofollow noopener noreferrer"&gt;https://saurabhdaware.github.io/text-to-handwriting/&lt;/a&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/4b53bac5992f6b70eb4b52443588daa861a35018cb6c590e21ee5c750b583a6b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7061636b6167652d6a736f6e2f762f736175726162686461776172652f746578742d746f2d68616e6477726974696e673f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d626c61636b266c6f676f3d6e706d26636f6c6f723d6461726b726564"&gt;&lt;img alt="NPM Version" src="https://camo.githubusercontent.com/4b53bac5992f6b70eb4b52443588daa861a35018cb6c590e21ee5c750b583a6b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f7061636b6167652d6a736f6e2f762f736175726162686461776172652f746578742d746f2d68616e6477726974696e673f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d626c61636b266c6f676f3d6e706d26636f6c6f723d6461726b726564"&gt;&lt;/a&gt; &lt;a href="https://github.com/saurabhdaware/text-to-handwriting#contributing" rel="noopener noreferrer"&gt;&lt;img alt="Contributions Welcome" src="https://camo.githubusercontent.com/d993925111a6d5b58122b4543606a1aa7a99e9748d39589964d4a33eef9dc46a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6e747269627574696f6e732d77656c636f6d652d627269676874677265656e3f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d626c61636b266c6f676f3d676974687562"&gt;&lt;/a&gt; &lt;br&gt;&lt;a href="https://github.com/saurabhdaware/text-to-handwriting/blob/master/LICENSE" rel="noopener noreferrer"&gt; &lt;img alt="GitHub License MIT" src="https://camo.githubusercontent.com/56a3220bff4e10bb8da4b8227f5b2b7678721cc9aeb61de93eb3097ba1fe36c7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f736175726162686461776172652f746578742d746f2d68616e6477726974696e673f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d626c61636b266c6f676f3d676974687562"&gt; &lt;/a&gt;&lt;a href="https://twitter.com/saurabhcodes" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Twitter Follow" src="https://camo.githubusercontent.com/15e5487e071dbc6cbebce5bc903b783651d3fc3dc29fbe81165bc5ce320699b3/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f666f6c6c6f772f73617572616268636f6465733f7374796c653d666f722d7468652d626164676526636f6c6f723d303966266c6162656c436f6c6f723d626c61636b266c6f676f3d74776974746572266c6162656c3d4073617572616268636f646573"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt; I hate writing assignments so I made this tool that converts text to an image that looks like handwriting😛
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This project is now archived. Read the announcement at &lt;a class="issue-link js-issue-link" href="https://github.com/saurabhdaware/text-to-handwriting/issues/138" rel="noopener noreferrer"&gt;#138&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🌠 Output&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/saurabhdaware/text-to-handwritingsample.jpeg"&gt;&lt;img width="400" alt="Sample image of output" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fsaurabhdaware%2Ftext-to-handwritingsample.jpeg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤗 Contributing&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Checkout &lt;a href="https://github.com/saurabhdaware/text-to-handwritingCONTRIBUTING.md" rel="noopener noreferrer"&gt;Contribution Guide&lt;/a&gt; for local setup and contribution guide.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📚 Libraries used&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/niklasvh/html2canvas" rel="noopener noreferrer"&gt;html2canvas&lt;/a&gt; - Turns DOM into Canvas.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/MrRio/jsPDF" rel="noopener noreferrer"&gt;jsPDF&lt;/a&gt; - To generate PDF from images.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/cypress-io/cypress" rel="noopener noreferrer"&gt;cypress&lt;/a&gt; - Testing Library&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zeit/serve" rel="noopener noreferrer"&gt;serve&lt;/a&gt; - Start local server&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;a href="https://www.patreon.com/bePatron?u=31891872" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Buy me a Coffee Button" width="200" src="https://camo.githubusercontent.com/044a949826a3db38839983c98265b4c40fbe92c8953926639e9149d729a9dc1e/68747470733a2f2f63352e70617472656f6e2e636f6d2f65787465726e616c2f6c6f676f2f6265636f6d655f615f706174726f6e5f627574746f6e2e706e67"&gt;&lt;/a&gt;   &lt;a href="https://www.buymeacoffee.com/saurabhdaware" rel="nofollow noopener noreferrer"&gt;&lt;img alt="Buy me a Coffee Button" width="200" src="https://camo.githubusercontent.com/874ea9179562e6d914f8a96ab0e560f680e2a388b1f05b2a5024d410f30cc9ee/68747470733a2f2f63646e2e6275796d6561636f666665652e636f6d2f627574746f6e732f64656661756c742d79656c6c6f772e706e67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bye!
Have fun 🦄&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/saurabhdaware/text-to-handwriting" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Twitter
&lt;/h3&gt;

&lt;p&gt;Do share it with your twitter fam 🕺🏻&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1242426542510067712-385" src="https://platform.twitter.com/embed/Tweet.html?id=1242426542510067712"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1242426542510067712-385');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1242426542510067712&amp;amp;theme=dark"
  }



&lt;/p&gt;




&lt;p&gt;Thank you for reading 🐨🎉 Let me know your thoughts comments. &lt;/p&gt;

&lt;p&gt;You can follow me on &lt;a href="https://twitter.com/saurabhcodes" rel="noopener noreferrer"&gt;Twitter @saurabhcodes&lt;/a&gt; and on &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;GitHub @saurabhdaware&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bye! stay safe and remember we are going get through this 🌻&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>html</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Overcoming the anxiety of creating your first open-source contribution 🦄</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Sat, 21 Mar 2020 09:23:06 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/overcoming-the-anxiety-of-creating-your-first-open-source-contribution-3bf0</link>
      <guid>https://dev.to/saurabhdaware/overcoming-the-anxiety-of-creating-your-first-open-source-contribution-3bf0</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This article is for the people who already know how to create Pull Requests but are too scared to create one or don't know how to exactly find an issue or a repository to work on. If you need help with the process of creating PR, you can check out &lt;a href="https://www.atlassian.com/git"&gt;Git and GitHub Guide on Atlassian&lt;/a&gt; or &lt;a href="https://github.com/HarshKapadia2/git_basics"&gt;Harsh's Git Basic Guide&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open-source can be overwhelming and contributing to someone else's project can seem difficult at first. &lt;/p&gt;

&lt;p&gt;"What if I mess everything up?", "What if I do something dumb with the code?", "I am ready... but these codebases are so huge... how do I find and fix bugs in this", "I can't understand the codebase... it's so huge".&lt;/p&gt;

&lt;p&gt;... these are some of the questions I had after learning git and GitHub. Even though I knew how to create a Pull Request, it was either too scary to actually send a Pull Request to someone or I simply didn't understand their codebase.&lt;/p&gt;

&lt;p&gt;This article will hopefully help you through this phase and will help you create your first Pull Request.&lt;/p&gt;

&lt;p&gt;Let's see how you can find the right repository and an issue.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exploring and finding the right repository and issue
&lt;/h1&gt;

&lt;p&gt;For the initial pull request, the first-contributions repository is quite cool to get started. You have to add your name to &lt;code&gt;CONTRIBUTORS.md&lt;/code&gt; and send a Pull Request.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/firstcontributions"&gt;
        firstcontributions
      &lt;/a&gt; / &lt;a href="https://github.com/firstcontributions/first-contributions"&gt;
        first-contributions
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🚀✨ Help beginners to contribute to open source projects
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://github.com/firstcontributions/open-source-badges"&gt;&lt;img src="https://camo.githubusercontent.com/244b53cd769b762eb980b653d6d79ffbccb3e317/68747470733a2f2f6669727374636f6e747269627574696f6e732e6769746875622e696f2f6f70656e2d736f757263652d6261646765732f6261646765732f6f70656e2d736f757263652d76312f6f70656e2d736f757263652e737667" alt="Open Source Love"&gt;&lt;/a&gt;
&lt;a href="https://join.slack.com/t/firstcontributors/shared_invite/enQtNjkxNzQwNzA2MTMwLTVhMWJjNjg2ODRlNWZhNjIzYjgwNDIyZWYwZjhjYTQ4OTBjMWM0MmFhZDUxNzBiYzczMGNiYzcxNjkzZDZlMDM" rel="nofollow"&gt;&lt;img width="150" src="https://res.cloudinary.com/practicaldev/image/fetch/s--TbBmcid5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/firstcontributions/first-contributions/master/assets/join-slack-team.png"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/76f0e887c183ccc31c1cb63c33d2dbf48cb2df51/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://www.codetriage.com/roshanjossey/first-contributions" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/8e53aecabdd0316ce198fe932798bb0f8754b30f/68747470733a2f2f7777772e636f64657472696167652e636f6d2f726f7368616e6a6f737365792f66697273742d636f6e747269627574696f6e732f6261646765732f75736572732e737667" alt="Open Source Helpers"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
First Contributions&lt;/h1&gt;
&lt;p&gt;It's hard. It's always hard the first time you do something. Especially when you are collaborating, making mistakes isn't a comfortable thing. We wanted to simplify the way new open-source contributors learn &amp;amp; contribute for the first time.&lt;/p&gt;
&lt;p&gt;Reading articles &amp;amp; watching tutorials can help, but what's better than actually doing the stuff in a practice environment? This project aims at providing guidance &amp;amp; simplifying the way beginners make their first contribution. If you are looking to make your first contribution, follow the steps below.&lt;/p&gt;
&lt;h4&gt;
&lt;em&gt;If you're not comfortable with command line, &lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/#tutorials-using-other-tools"&gt;here are tutorials using GUI tools.&lt;/a&gt;&lt;/em&gt;
&lt;/h4&gt;
&lt;h4&gt;
&lt;em&gt;Read this in &lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/Translations.md"&gt;other languages&lt;/a&gt;.&lt;/em&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.bn.md"&gt;🇧🇩&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.bg.md"&gt;🇧🇬&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.pt_br.md"&gt;🇧🇷&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ca.md"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bLbrVq0p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/firstcontributions/first-contributions/master/assets/catalan1.png" width="22"&gt;&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.chs.md"&gt;🇨🇳&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.cs.md"&gt;🇨🇿&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.de.md"&gt;🇩🇪&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.da.md"&gt;🇩🇰&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.eg.md"&gt;🇪🇬&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.es.md"&gt;🇪🇸&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.fr.md"&gt;🇫🇷&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.gl.md"&gt;🏴&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.gr.md"&gt;🇬🇷&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ge.md"&gt;🇬🇪&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.hu.md"&gt;🇭🇺&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.id.md"&gt;🇮🇩&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.hb.md"&gt;🇮🇱&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/Translations.md"&gt;🇮🇳&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.fa.md"&gt;🇮🇷&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.fa.en.md"&gt;🇮🇷&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.it.md"&gt;🇮🇹&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ja.md"&gt;🇯🇵&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.kws.md"&gt;🇰🇪&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ko.md"&gt;🇰🇷 🇰🇵&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.lt.md"&gt;🇱🇹&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ro.md"&gt;🇲🇩 🇷🇴&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.mm_unicode.md"&gt;🇲🇲&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.mk.md"&gt;🇲🇰&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.mx.md"&gt;🇲🇽&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.my.md"&gt;🇲🇾&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.nl.md"&gt;🇳🇱&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.igb.md"&gt;🇳🇬&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.no.md"&gt;🇳🇴&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.np.md"&gt;🇳🇵&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.tl.md"&gt;🇵🇭&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.en-pirate.md"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gzCMasIC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/firstcontributions/first-contributions/master/assets/pirate.png" width="22"&gt;&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ur.md"&gt;🇵🇰&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.pl.md"&gt;🇵🇱&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.pt-pt.md"&gt;🇵🇹&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ru.md"&gt;🇷🇺&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.ar.md"&gt;🇸🇦&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.se.md"&gt;🇸🇪&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.slk.md"&gt;🇸🇰&lt;/a&gt;
&lt;a href="https://raw.githubusercontent.com/firstcontributions/first-contributions/master/translations/README.sl.md"&gt;🇸🇮&lt;/a&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/firstcontributions/first-contributions"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This is super helpful as an initial practice.&lt;/p&gt;

&lt;p&gt;or you can contribute to any of your friend's repository.&lt;/p&gt;

&lt;p&gt;Even after contributing to the first-contributions repository, sending a pull request to an actual project and finding an issue in the repository can still seem a difficult thing to do.&lt;/p&gt;

&lt;p&gt;You can start by&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
Contributing to something you use
&lt;em&gt;or&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Contributing to something that looks cool&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  - Contributing to something you use.
&lt;/h2&gt;

&lt;p&gt;One option you have is to contribute to a project that you currently use. You can make a list of the projects that you are using. NPM packages or Python packages, VSCode Extensions, Frameworks, Libraries, list everything you use! &lt;/p&gt;

&lt;p&gt;While using these projects you might have discovered this one particular feature that you feel is missing or documentation for particular function needs to be better or maybe a bug that you found while using it or even a spelling mistake!&lt;/p&gt;

&lt;p&gt;Search for the GitHub repository of that project and create an issue mentioning the changes you want to make. If your change is fixing a typo or obvious bug that does not require you to waste too much of your time and effort, then you can create a pull request directly. For feature requests, always create an issue before you start working on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example?
&lt;/h3&gt;

&lt;p&gt;Recently I was reading DEV.to's editor guide and found that there's an extra &lt;code&gt;%&lt;/code&gt; in the guide so I quickly made a PR that removed the extra &lt;code&gt;%&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Here's my PR&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/thepracticaldev/dev.to/pull/4500"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg"&gt;
      &lt;span class="issue-title"&gt;
        removed extra bracket from liquid tags in editor guide
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#4500&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/saurabhdaware"&gt;
        &lt;img class="github-liquid-tag-img" src="https://res.cloudinary.com/practicaldev/image/fetch/s--imwddvXz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars1.githubusercontent.com/u/30949385%3Fv%3D4" alt="saurabhdaware avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/saurabhdaware"&gt;saurabhdaware&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/thepracticaldev/dev.to/pull/4500"&gt;&lt;time&gt;Oct 19, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      

&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;What type of PR is this? (check all applicable)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Refactor&lt;/li&gt;
&lt;li&gt;[ ] Feature&lt;/li&gt;
&lt;li&gt;[x] Bug Fix&lt;/li&gt;
&lt;li&gt;[ ] Documentation Update&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Description&lt;/h2&gt;
&lt;p&gt;Found that there was an extra curly bracket in liquid tag guide so I just removed it&lt;/p&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Added to documentation?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[ ] docs.dev.to&lt;/li&gt;
&lt;li&gt;[ ] readme&lt;/li&gt;
&lt;li&gt;[x] no documentation needed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;[optional] What gif best describes this PR or how it makes you feel?&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://camo.githubusercontent.com/5c57f964d91913f09e0bc5381be59ed024c239e1/68747470733a2f2f7468756d62732e6766796361742e636f6d2f53706963795265737065637466756c4974616c69616e67726579686f756e642d73697a655f726573747269637465642e676966" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/5c57f964d91913f09e0bc5381be59ed024c239e1/68747470733a2f2f7468756d62732e6766796361742e636f6d2f53706963795265737065637466756c4974616c69616e67726579686f756e642d73697a655f726573747269637465642e676966" alt="Fix it Felix fixing unfixed window"&gt;&lt;/a&gt;&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/thepracticaldev/dev.to/pull/4500"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;P.S. I am super proud of this Pull Request 🐨🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  - Contributing to something that looks cool.
&lt;/h2&gt;

&lt;p&gt;Contributing to something you use is not always an option. It can be difficult to find issues after one point so you can simply go to repositories that you find interesting and check out issues in that repository.&lt;/p&gt;

&lt;p&gt;Some repositories have issues with labels like "Good First Issue", "Difficulty: Easy" or something equivalent. You can find these issues and comment with something like "Hey this seems cool! can I work on this?". If you need any help or extra information you can comment on this issue and ask for help.&lt;/p&gt;

&lt;p&gt;Also, it's not necessary to only go through "Good First Issues" sometimes other issues can seem easier to you. So do go through other issues as well and choose the one that looks interesting!&lt;/p&gt;

&lt;h3&gt;
  
  
  Example?
&lt;/h3&gt;

&lt;p&gt;During &lt;a href="http://hacktoberfest.digitalocean.com/"&gt;Hacktoberfest&lt;/a&gt; I was randomly searching for issues to work on and came across this issue on DEV.to about bad coloring in the profile theme. Do check out the conversation here:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/thepracticaldev/dev.to/issues/4106"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg"&gt;
      &lt;span class="issue-title"&gt;
        Bad coloring on follow button
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#4106&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/sierisimo"&gt;
        &lt;img class="github-liquid-tag-img" src="https://res.cloudinary.com/practicaldev/image/fetch/s--qzihkD9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://avatars3.githubusercontent.com/u/1699877%3Fv%3D4" alt="sierisimo avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/sierisimo"&gt;sierisimo&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/thepracticaldev/dev.to/issues/4106"&gt;&lt;time&gt;Sep 25, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      

&lt;p&gt;&lt;strong&gt;Describe the bug&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When reading an article, sometimes the button is not clear on what it says given the colors.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;To Reproduce&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I found it on this article: &lt;a href="https://dev.to/jmfayard/how-kotlin-makes-editing-your-gradle-build-less-frustrating-232l" rel="nofollow"&gt;https://dev.to/jmfayard/how-kotlin-makes-editing-your-gradle-build-less-frustrating-232l&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just going there, without dark mode or anything, I'm not sure if I'm following or not this particular user.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Expected behavior&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Text with the follow status for this user should be visible or selectable&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Screenshots&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://user-images.githubusercontent.com/1699877/65620722-f4135f00-df87-11e9-935d-cfc1694bdc20.png" rel="nofollow"&gt;&lt;img width="282" alt="image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--3pZtjxOt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/1699877/65620722-f4135f00-df87-11e9-935d-cfc1694bdc20.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Desktop (please complete the following information):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS: MacOS&lt;/li&gt;
&lt;li&gt;Browser: Firefox&lt;/li&gt;
&lt;li&gt;Version: 69.0.1&lt;/li&gt;
&lt;/ul&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/thepracticaldev/dev.to/issues/4106"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Awesome🎉 Now you have an issue to work on! Let's code!!&lt;/p&gt;

&lt;h1&gt;
  
  
  Writing code and sending a Pull Request
&lt;/h1&gt;

&lt;p&gt;Here's a thing about large codebases, NOBODY KNOWS HOW THE WHOLE CODEBASE WORKS NOT EVEN THE MAINTAINER! so you don't really have to go through every single file trying to understand how every single function works.&lt;/p&gt;

&lt;p&gt;You only have to search for the file where you want to make changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  - Searching for the right file
&lt;/h2&gt;

&lt;p&gt;I usually search using the text that is visible on the screen so If I want to make a change in DEV's navigation bar, I would search for "WRITE A POST" (visible in the desktop navigation bar)&lt;/p&gt;

&lt;p&gt;Here are the search results:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L8RRO-Av--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/any3cffm4vwochqyscmf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L8RRO-Av--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/any3cffm4vwochqyscmf.png" alt="Screenshot of search results after searching write a post which display result from a file named _nav_menu_html.erb at the top"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  - Local setup
&lt;/h2&gt;

&lt;p&gt;Repositories have a local setup guide in README or CONTRIBUTINGmd. Usually, this includes cloning a repository and installing the required dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  - Writing the code
&lt;/h2&gt;

&lt;p&gt;Do go through the contribution guidelines of the repository to see if there are any instructions about writing the code. Even if you miss something that is fine maintainer will let you know after you make the PR. Going through contribution guidelines will just save your time of making changes later.&lt;/p&gt;

&lt;h2&gt;
  
  
  - Sending Pull Request
&lt;/h2&gt;

&lt;p&gt;HIT THAT "CREATE PULL REQUEST" BUTTON!!! &lt;br&gt;
and it's totally ok if you miss something or change the wrong function or a wrong file (trust me I've done that a lot). Maintainers will later request you changes if required. You can always commit to the branch and changes will reflect in the PR.&lt;/p&gt;

&lt;p&gt;Finally, even small contributions play a major role in an open-source project so don't feel awkward while sending PR for fixing a typo. It is a fair contribution and as a maintainer, these contributions are super useful for me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EVERY. CONTRIBUTION. IS. IMPORATNT.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Thank you for reading the article. If you have any questions or any help regarding open-source and GitHub, you can drop them in the comments or DM me on my &lt;a href="https://twitter.com/saurabhcodes"&gt;Twitter @saurabhcodes&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can also follow me on &lt;a href="https://github.com/saurabhdaware"&gt;GitHub @saurabhdaware&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay Home, Stay Safe. 🌻&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>DEV.to Widget v1.2.0🎉: GUI to create widget, new theme, data-sortby attribute and more!</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Sun, 23 Feb 2020 18:56:18 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/dev-to-widget-v1-2-0-gui-to-create-widget-new-theme-data-sortby-attribute-and-more-22bo</link>
      <guid>https://dev.to/saurabhdaware/dev-to-widget-v1-2-0-gui-to-create-widget-new-theme-data-sortby-attribute-and-more-22bo</guid>
      <description>&lt;p&gt;Hello people! I just published the new version of DEV.to widget(v1.2.0). &lt;/p&gt;

&lt;p&gt;Now you can create your widget from GUI🎉!! &lt;/p&gt;

&lt;p&gt;Visit &lt;a href="https://dev-widget.netlify.com/create" rel="noopener noreferrer"&gt;dev-widget.netlify.com/create&lt;/a&gt; and change the values!&lt;br&gt;
&lt;a href="https://dev-widget.netlify.com/create" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmtozkkdt5eke2s99iamp.png" alt="Screenshot of GUI" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Changelog&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GUI!! &lt;a href="https://dev-widget.netlify.com/create" rel="noopener noreferrer"&gt;dev-widget.netlify.com/create&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-sortby&lt;/code&gt; attribute with &lt;code&gt;"reactions"&lt;/code&gt; and &lt;code&gt;"date"&lt;/code&gt; values.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data-contentheight="200px"&lt;/code&gt; to change the height of the articles container.&lt;/li&gt;
&lt;li&gt;Bug fixes (Shoutout to @Pika1998 for finding and fixing a bug!)&lt;/li&gt;
&lt;li&gt;andd a new theme!! &lt;code&gt;data-theme="cobalt2"&lt;/code&gt; (by @b3u, Thank you🌻)
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw6sww4h0v4c1xu6t2qm1.png" alt="Preview of Cobalt2 Theme" width="383" height="498"&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;strong&gt;Checkout dev-widget on GitHub&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;
        saurabhdaware
      &lt;/a&gt; / &lt;a href="https://github.com/saurabhdaware/DEV-widget" rel="noopener noreferrer"&gt;
        DEV-widget
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Unofficial Widget/profile card for https://dev.to/
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;p&gt;Thank you for reading!&lt;/p&gt;

&lt;p&gt;Byeee 🐨🎉&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>HTML parsing and rendering🌻: Here's what happens when you type URL and press enter...</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Wed, 19 Feb 2020 13:54:46 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/html-parsing-and-rendering-here-s-what-happens-when-you-type-url-and-press-enter-3b2o</link>
      <guid>https://dev.to/saurabhdaware/html-parsing-and-rendering-here-s-what-happens-when-you-type-url-and-press-enter-3b2o</guid>
      <description>&lt;p&gt;Hi there! I am writing a series of articles called "Web Performance Hacks" and this will be the first article from the series. &lt;/p&gt;

&lt;p&gt;This article aims to show how browsers parse and render HTML and CSS which will eventually help us in understanding how we can trick the browser's parser to improve web performance.&lt;/p&gt;

&lt;h1&gt;
  
  
  TLDR;
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Parsing and Rendering turn the HTML content into a web page with colors and backgrounds and pictures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTML Parsing:&lt;/strong&gt; HTML Text -&amp;gt; Tokenization -&amp;gt; DOM Tree&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Parsing:&lt;/strong&gt; CSS Text -&amp;gt; Tokenization -&amp;gt; CSSOM Tree&lt;/li&gt;
&lt;li&gt;DOM and CSSOM are merged to form a Render Tree&lt;/li&gt;
&lt;li&gt;Render Tree has all the information required to mark and paint the screen.&lt;/li&gt;
&lt;li&gt;Render Tree -&amp;gt; Layout -&amp;gt; Paint&lt;/li&gt;
&lt;li&gt;The layout does the maths for placing the elements&lt;/li&gt;
&lt;li&gt;Paint paints the elements with colors, backgrounds, shadows, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SO LETS GOOO!!!! &lt;/p&gt;

&lt;p&gt;First, let's see what happens when you type a URL and hit enter&lt;/p&gt;

&lt;h1&gt;
  
  
  How browsers work
&lt;/h1&gt;

&lt;p&gt;We type a URL and press the enter and the server responds with index.html. However, an HTML content is not what we see when we visit a website... we see a web page with colors and backgrounds and animations and pictures. So there's a process that turns the HTML content to a pretty webpage, and that is parsing and rendering!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxpx8zzyg2rcguv7kfpp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvxpx8zzyg2rcguv7kfpp.gif" alt="A gif displaying a server is hit when you type URL and returns HTML content, then HTML content goes through parsing and rendering to get the webpage" width="600" height="338"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Note: This is a zoomed-out view and there are other things like DNS resolving and other networking side of things that I've ignored to simplify the article&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  HTML Parsing
&lt;/h1&gt;

&lt;p&gt;So we have HTML content at the beginning which goes through a process called tokenization, tokenization is a common process in almost every programming language where code is split into several tokens which are easier to understand while parsing. This is where the HTML's parser understands which is the start and which is the end of the tag, which tag it is and what is inside the tag.&lt;/p&gt;

&lt;p&gt;Now we know, html tag starts at the top and then the head tag starts before the html ends so we can figure out that the head is inside html and create a tree out of it. Thus we then get something called a parse tree which eventually becomes a DOM tree as shown in the image below:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo91r8lupx8elero5djh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo91r8lupx8elero5djh3.png" alt="An image showing how HTML Parsing works with HTML content at the top then tokenization and a DOM tree" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DOM tree is what we access when we do &lt;code&gt;document.getElementById&lt;/code&gt; or &lt;code&gt;document.querySelector&lt;/code&gt; in JavaScript.&lt;/p&gt;

&lt;p&gt;Just like HTML, CSS goes through a similar process where we have the CSS text and then the tokenization of CSS to eventually create something called a CSSOM or CSS Object Model. &lt;/p&gt;

&lt;p&gt;This is what a CSS Object Model looks like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvg9595umg17jzkcdvm7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvg9595umg17jzkcdvm7f.png" alt="a diagram of CSSOM tree displaying body with its CSS properties in its one node and div on the other node, div has its CSS properties as well" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! now we have DOM and CSSOM so we got every information that is required to get our screens painted!&lt;/p&gt;

&lt;h1&gt;
  
  
  Rendering of Web Page
&lt;/h1&gt;

&lt;p&gt;For rendering, a DOM and CSSOM are merged to form something called a Render Tree. Render Tree has the information required to mark and paint elements on the screen.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0av60eim9egeoihfdfo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0av60eim9egeoihfdfo1.png" alt="A diagram showing DOM tree and CSSOM tree being merged to form Render Tree, Few things to note are render-tree does not include head, link, script, and elements with display none" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also while forming a Render Tree, elements like &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, and elements with 'display: none' in CSS are ignored since they are not rendered on the screen.&lt;/p&gt;

&lt;p&gt;Note that the elements with 'opacity:0' or 'visibility: none' are included in the render tree, even though they are not painted on the screen they do take their positions and render as an empty space and thus are required for calculations.&lt;/p&gt;

&lt;p&gt;Huushh! you've come a long way! drink a glass of water maybe? &lt;/p&gt;

&lt;p&gt;So now we have a render tree with all the information that is needed to create a visual page. Now, the renderer will use this information to create a Layout and then a Paint, we will talk about Layout and Paint in next point before that here's what the overall process looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs0cj1gr1srugpkc34985.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs0cj1gr1srugpkc34985.png" alt="A diagram displaying that DOM and CSSOM come together to form Render Tree and then the Layout happens and then at the end the Paint happens" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Layout
&lt;/h2&gt;

&lt;p&gt;The layout is where the elements are marked on the screen. The layout includes all the calculations and mathematics behind an element's position so it takes all the properties related to the position (height, width, position, top left right bottom, etc) from The Render Tree and places the elements on the screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paint
&lt;/h2&gt;

&lt;p&gt;After Layout, a Paint happens. Paint takes properties like color, background-color, border-color, box-shadow, etc. to paint the screen with colors. &lt;/p&gt;

&lt;p&gt;After the paint, we see the content on the screen and the first time we see something other than a white screen is called 'First Paint'. The term First Paint is used in performance reports to show how long your website took to show something on the screen.&lt;/p&gt;

&lt;h1&gt;
  
  
  Gotchas!
&lt;/h1&gt;

&lt;p&gt;Now, there are few important points to note in the whole process of parsing and rendering such as,&lt;/p&gt;

&lt;h3&gt;
  
  
  - Parsing halts when it comes across &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag.
&lt;/h3&gt;

&lt;p&gt;So if I have &lt;code&gt;&amp;lt;script src="path/to/script"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt; in the middle of the HTML, The parser will halt there, will fetch the script, wait for the response, execute it and then it will continue the parsing. This is why we put &lt;code&gt;&amp;lt;scipt&amp;gt;&lt;/code&gt; at the end of the body so that we can complete the parsing first. &lt;/p&gt;

&lt;p&gt;A similar thing happens when we put &lt;code&gt;&amp;lt;link rel="stylesheet" href="path/to/css" /&amp;gt;&lt;/code&gt;. The parser fetches the CSS and makes sure that the CSSOM is ready before putting content on the screen. This is why we don't see a flash of CSSless content before the page load instead we see the content with its CSS loaded and applied.&lt;/p&gt;

&lt;p&gt;Even though I said that the parsing halts when it comes across &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, there are ways to avoid that using &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;defer&lt;/code&gt; on the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag and &lt;code&gt;rel="preload"&lt;/code&gt; on &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; We'll see that in details in the next part of this series.&lt;/p&gt;

&lt;p&gt;Anddd... we're done! Thank you for reading the article!! &lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>webperf</category>
    </item>
    <item>
      <title>Make websites work offline - Offline Storage. Making IndexedDB the Hero!</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Wed, 12 Feb 2020 09:33:35 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/make-websites-work-offline-offline-storage-making-indexeddb-the-hero-1oee</link>
      <guid>https://dev.to/saurabhdaware/make-websites-work-offline-offline-storage-making-indexeddb-the-hero-1oee</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: This article does not expect you to know anything from Part 1.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Traditionally cookies were used for storing local data. But with HTML5 APIs, we got new options like &lt;code&gt;localStorage&lt;/code&gt;, &lt;code&gt;sessionStorage&lt;/code&gt;, &lt;code&gt;WebSQL&lt;/code&gt;, and &lt;code&gt;IndexedDB&lt;/code&gt;. In this article, we will specifically talk about IndexedDB.&lt;/p&gt;

&lt;p&gt;Let's say you got Service Workers setup done and now your website loads offline. But... what if you want to store and retrieve a particular data? you cannot just &lt;code&gt;fetch()&lt;/code&gt; from your API since the user is offline.&lt;/p&gt;

&lt;p&gt;In this case, you can store data in IndexedDB!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Indexed Database API is a JavaScript application programming interface provided by web browsers for managing a NoSQL database of JSON objects. It is a standard maintained by the World Wide Web Consortium.&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;~ &lt;a href="https://en.wikipedia.org/wiki/Indexed_Database_API" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt; &lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;IndexedDB is provided by the browser and thus does not need internet for performing CRUD (Create Read Update Delete) operations. It is something like SQLite in Android (minus the SQL).&lt;/p&gt;

&lt;h1&gt;
  
  
  Implementation
&lt;/h1&gt;

&lt;p&gt;If you prefer learning yourself from codesandbox, you can checkout IndexedDB Example.&lt;/p&gt;

&lt;p&gt;For the browsers that use prefix, we can start with something like&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mozIndexedDB&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webkitIndexedDB&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;msIndexedDB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IDBTransaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IDBTransaction&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webkitIDBTransaction&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;msIDBTransaction&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;READ_WRITE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;readwrite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IDBKeyRange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IDBKeyRange&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webkitIDBKeyRange&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;msIDBKeyRange&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="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&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="nf"&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;Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.&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;Before we go to the next code, let me warn you about something: IndexedDB is not &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" rel="noopener noreferrer"&gt;promisified&lt;/a&gt; and thus is largely dependent on &lt;code&gt;onsuccess&lt;/code&gt; and &lt;code&gt;onerror&lt;/code&gt; callbacks. There are libraries like &lt;a href="https://www.npmjs.com/package/idb" rel="noopener noreferrer"&gt;idb&lt;/a&gt; that provide promisified version of IndexedDB but for this article I will stick to the vanilla IndexedDB code. &lt;/p&gt;

&lt;h2&gt;
  
  
  Open/Create Database
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Opening a database automatically creates new database if it doesn't exist&lt;/em&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;let&lt;/span&gt; &lt;span class="nx"&gt;db&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;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyTestDatabase&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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;
  
  
  &amp;gt; Defining schema/values
&lt;/h3&gt;

&lt;p&gt;When you create a new database, the &lt;code&gt;onupgradeneeded&lt;/code&gt; event will be triggered. We can create objectStores here,&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;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onupgradeneeded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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;userObjectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&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;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;userObjectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;name&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;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;userObjectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&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;email&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;unique&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus, the complete code to create/open a database would look something like:&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;openDatabase&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MyTestDatabase&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onupgradeneeded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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;userObjectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&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;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="nx"&gt;userObjectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;name&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;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="nx"&gt;userObjectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&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;email&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;unique&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="p"&gt;}&lt;/span&gt;       
    &lt;span class="p"&gt;})&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;openDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&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;// db instance accessible here&lt;/span&gt;

    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add data
&lt;/h2&gt;

&lt;p&gt;Now we have &lt;code&gt;db&lt;/code&gt; object accessible in &lt;code&gt;openDatabase()&lt;/code&gt; promise. We can use this object to add/read/delete the data from IndexedDB.&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="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&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;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;openDatabase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Add&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userReadWriteTransaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&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;readwrite&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;newObjectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userReadWriteTransaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;newObjectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;userid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;josn@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;userReadWriteTransaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Data Added&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Remove data
&lt;/h2&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;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&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;readwrite&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="nf"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&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;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&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="nf"&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;Deleted!&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;h2&gt;
  
  
  Read and Update Data
&lt;/h2&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;readTransaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&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;objectStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;customers&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;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User is &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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="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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&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="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&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;updateRequest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;objectStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put&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="nx"&gt;updateRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onsuccess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&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="nf"&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;Data Updated!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/indexeddb-example-trv2f"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Usecase?
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you have an API that always (or most of the times) returns same values, you can call API, store the response in IndexedDB and when next time user calls the API, you can return it from IndexedDB right there and maybe later call API and store the updated value. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I use IndexedDB in my application &lt;a href="https://pocketbook.cc" rel="noopener noreferrer"&gt;PocketBook&lt;/a&gt; which is a Google Keep alternative where you can store your todos, goals, etc. PocketBook uses IndexedDB by default to store notebook's information. Thus you can use pocketbook even when you are offline!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;&lt;em&gt;MDN Docs:&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;codesandbox example:&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://codesandbox.io/s/indexeddb-example-trv2f" rel="noopener noreferrer"&gt;https://codesandbox.io/s/indexeddb-example-trv2f&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;&lt;em&gt;PocketBook:&lt;/em&gt;&lt;/strong&gt; &lt;a href="https://pocketbook.cc" rel="noopener noreferrer"&gt;https://pocketbook.cc&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Thank you for reading! If you have any interesting project where you're using IndexedDB, do drop the link below! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>database</category>
      <category>html</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Make websites work offline - What are Service Workers and How to get a custom App Install button on the website.</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Tue, 07 Jan 2020 14:03:58 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/make-websites-work-offline-part-1-what-are-service-workers-and-how-to-get-a-custom-app-install-button-on-the-website-4a8</link>
      <guid>https://dev.to/saurabhdaware/make-websites-work-offline-part-1-what-are-service-workers-and-how-to-get-a-custom-app-install-button-on-the-website-4a8</guid>
      <description>&lt;p&gt;Hey everyone, &lt;/p&gt;

&lt;p&gt;This is a little different from my usual posts (finally a post without #showdev tag 😂). In this post, I will be explaining what are Service Workers, How to implement them with Vanilla JavaScript, and finally How to get the custom "Add to Homescreen" banner on the website.&lt;/p&gt;

&lt;h1&gt;
  
  
  Table of Content
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Why do we need Service Worker?&lt;/li&gt;
&lt;li&gt;
How Service Worker works?

&lt;ul&gt;
&lt;li&gt;Service Worker Lifecycle&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

How to implement Service Worker

&lt;ul&gt;
&lt;li&gt;1. Service Worker Registration&lt;/li&gt;
&lt;li&gt;
2. Handling Requests with Service Worker

&lt;ul&gt;
&lt;li&gt;2a. Storing URLs to Cache&lt;/li&gt;
&lt;li&gt;2b. Loading file from the Cache&lt;/li&gt;
&lt;li&gt;2c. Handling new Cache version&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

3. Complete example for implementing Service Worker (If your deadline to implement service worker is tomorrow, just jump here.)

&lt;ul&gt;
&lt;li&gt;3a. Code for loading index.html and index.js offline&lt;/li&gt;
&lt;li&gt;3b. Code for loading offline.html when you are offline&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Custom "Add to Homescreen" banner (If you are only here for how to get custom App Install button on website, you can jump here)&lt;/li&gt;

&lt;li&gt;Helpful Links&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Why do we need Service Worker?
&lt;/h1&gt;

&lt;p&gt;Do you use Instagram (The Native App)? on the Home Screen, it shows pictures right? what if you turn off the internet? Does it crashes or show dinosaur game like chrome? well nope...&lt;/p&gt;

&lt;p&gt;Instead, Instagram shows older posts that were already loaded. Though you cannot refresh the feed or like a picture it is still pretty cool to be able to see the older posts right? &lt;/p&gt;

&lt;p&gt;Service Workers let you implement something similar on the web. You can avoid the chrome's dinosaur and show a custom offline page instead! or you can show a part of your website (or a whole website considering it is small) while the user is browsing offline.&lt;/p&gt;

&lt;p&gt;Here's what twitter shows when you go offline:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0f47ida8wqujfbd6zc4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0f47ida8wqujfbd6zc4w.png" alt="Image of Twitter's offline page" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In fact, DEV.to has one of the coolest offline pages ever! They have a coloring canvas as an offline page! super cool right? Here's how it looks:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqi8zz92sdre1htp41yna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqi8zz92sdre1htp41yna.png" alt="Image of DEV.to's offline page" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's a humblebrag: &lt;br&gt;
Last year I made a game called &lt;a href="https://eotm.ml" rel="noopener noreferrer"&gt;Edge of The Matrix&lt;/a&gt; that works offline! since the game is not that large I was able to cache most of the parts of the website and make the entire game work offline.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ny7kp5fkwtm8i6p0png.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ny7kp5fkwtm8i6p0png.png" alt="Offline and Online comparison of eotm.ml" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the Left image is when you are online and right when you are offline. When you are offline the game looks the same (minus the font). &lt;/p&gt;

&lt;p&gt;How do they work? hah.. saurabh.. obviously magic.&lt;/p&gt;

&lt;p&gt;Well, They use Service Workers🎉 With the three examples above I wanted to give an idea of how websites can use Service Workers in various ways.&lt;/p&gt;

&lt;p&gt;So are you all excited to learn how they work and how to implement them!!? Lezgooo!!!&lt;/p&gt;
&lt;h1&gt;
  
  
  How Service Worker works?
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Note: This is a very surface-level explanation of how service worker works, After reading the article if you are interested in knowing more about them, I have linked some references at the end of the article&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Service Worker has access to cache, requests coming out from your applications, and the Internet.&lt;/p&gt;

&lt;p&gt;Since you have access to these three things, you can write code and handle the requests the way you want.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0q87ei29e46xkto1w0t3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0q87ei29e46xkto1w0t3.png" alt="Diagram that explains how service worker takes the request from the application and can redirect the request to cache or internet depending on the requirement" width="531" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Service Worker can listen to the requests from the user,&lt;/p&gt;

&lt;p&gt;Here's how we usually prefer our requests to load with the service worker registered:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User hits your website's URL (and thus requests for your &lt;code&gt;/index.html&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Service Workers have a fetch event listener that listens to this event.&lt;/li&gt;
&lt;li&gt;Now since the service worker has access to &lt;code&gt;caches&lt;/code&gt; object which controls the cache. It can check if the &lt;code&gt;/index.html&lt;/code&gt; exists in the cache.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If&lt;/strong&gt; &lt;code&gt;index.html&lt;/code&gt; exists in cache:
respond with the &lt;code&gt;index.html&lt;/code&gt; file from the cache.
&lt;strong&gt;Else&lt;/strong&gt;: pass on the request to the internet and return the response from the internet.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Service Worker Lifecycle.
&lt;/h2&gt;

&lt;p&gt;When you first register the service worker, It goes to &lt;code&gt;install&lt;/code&gt; state and after installing the service worker it goes to &lt;code&gt;active&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's say you updated the service worker, In this case, the new service worker goes to &lt;code&gt;install&lt;/code&gt; and then &lt;code&gt;waiting&lt;/code&gt; state while the old service worker still is in control and is &lt;code&gt;active&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After closing the tab and opening the fresh instance of the website, the service worker from the &lt;code&gt;waiting&lt;/code&gt; state takes control and goes &lt;code&gt;active&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Developers site has a nice detailed explanation of Service Worker Lifecycle, I will suggest checking it out: &lt;a href="https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle" rel="noopener noreferrer"&gt;https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  How to implement Service Worker
&lt;/h1&gt;

&lt;p&gt;Before we go into code here are a few things that you should know:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, you need to tell your website where your service worker file is. (i.e. Register Service Worker).&lt;/li&gt;
&lt;li&gt;Service Worker file does not get access to DOM. If you've worked with Web Workers before, the Service Worker is also a kind of a JavaScript Worker.&lt;/li&gt;
&lt;li&gt;You can &lt;code&gt;postMessage&lt;/code&gt; back and forth from the Service Worker file which allows you to talk to the Service Worker.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  1. Service Worker Registration.
&lt;/h2&gt;

&lt;p&gt;In your &lt;code&gt;index.html&lt;/code&gt; (or any of the .js file which is sourced to .html)&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&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Your HTML --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ServiceWorker Registration&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serviceWorker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serviceworker.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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;registration&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;// Registration was successful&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ServiceWorker registration successful with scope: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;registration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scope&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;err&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;// registration failed :(&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ServiceWorker registration failed: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&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="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;This will register the file &lt;code&gt;/serviceworker.js&lt;/code&gt; as a service worker. Now all your service worker handling code will go into the &lt;code&gt;/serviceworker.js&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Handling Requests with Service Worker
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2a. Storing URLs to Cache.
&lt;/h3&gt;

&lt;p&gt;Yay🎉, we have Service Worker registered! Now we want to add our necessary files into the cache so that we can later load them without the internet connection.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;serviceworker.js&lt;/code&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="nx"&gt;CACHE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version-1&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;urlsToCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.html&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="s1"&gt;assets/logo-192.png&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="s1"&gt;assets/coverblur.jpg&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="s1"&gt;index.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Install the service worker and open the cache and add files mentioned in array to cache&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;install&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CACHE_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Opened cache&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="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;urlsToCache&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;p&gt;&lt;code&gt;caches.open(CACHE_NAME)&lt;/code&gt; open the caches that match the name passed to it ("version-1" in our case).&lt;br&gt;
&lt;code&gt;cache.addAll(urlToCache)&lt;/code&gt; adds all the URLs to the cache.&lt;/p&gt;

&lt;p&gt;Now we have all the files that we need to load offline in our cache.&lt;/p&gt;
&lt;h3&gt;
  
  
  2b. Loading file from the Cache.
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;serviceworker.js&lt;/code&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="c1"&gt;// Listens to request from application.&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="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;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// The requested file exists in the cache so we return it from the cache.&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="p"&gt;}&lt;/span&gt;

                &lt;span class="c1"&gt;// The requested file is not present in cache so we send it forward to the internet&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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;p&gt;&lt;code&gt;caches.match(event.request)&lt;/code&gt; checks if the match for event.request is found in the CacheStorage and if it does it responds it in promise.&lt;/p&gt;

&lt;p&gt;If the file is not present in the cache, it returns a falsy value and thus you can send the request further to fetch data through the internet.&lt;/p&gt;

&lt;p&gt;(If you want to load an offline page, you can check if the fetch is throwing error. If the fetch call fails, in the .catch() block you can respond with &lt;code&gt;offline.html&lt;/code&gt;. I have mentioned an example to load offline page below.)&lt;/p&gt;

&lt;h2&gt;
  
  
  2c. Handling new Cache versions (OPTIONAL - You can avoid this if you hate your life).
&lt;/h2&gt;

&lt;p&gt;So Woah! You've come a long way. Maybe drink water here.&lt;/p&gt;

&lt;p&gt;"But wait, Saurabh, I already know how to add to cache and respond from the cache and my code is perfectly working so isn't this article suppose to end here?"&lt;/p&gt;

&lt;p&gt;Well yes but actually no. &lt;/p&gt;

&lt;p&gt;Here's a problem,&lt;br&gt;
Now you make changes in your code or let's say you added a new JavaScript file. You want those changes to reflect in your app but.. your app still showing older file.. why? because that is what the service worker has in the cache. Now you want to delete the old cache and add your new cache instead.&lt;/p&gt;

&lt;p&gt;Now, what we need to do is, we need to tell the service worker to delete all the caches except the new one that has just been added.&lt;/p&gt;

&lt;p&gt;We've given caches a key/name right? "version-1". Now if we want to load new cache we will change this name to "version-2" and we would want to delete the cache of name "version-1"&lt;/p&gt;

&lt;p&gt;This is how you would do that.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;serviceworker.js&lt;/code&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="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;activate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&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;cacheWhitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// add cache names which you do not want to delete&lt;/span&gt;
    &lt;span class="nx"&gt;cacheWhitelist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CACHE_NAME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheNames&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nx"&gt;cacheNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cacheWhitelist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&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;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&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;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;So since we updated the CACHE_NAME to "version-2". We will delete every cache that is not under "version-2".&lt;/p&gt;

&lt;p&gt;When we have a new Service Worker activated we delete the unnecessary old cache.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Complete Example for Implementing Service Worker
&lt;/h1&gt;

&lt;h2&gt;
  
  
  3a. Code for loading &lt;code&gt;index.html&lt;/code&gt; and &lt;code&gt;index.js&lt;/code&gt; offline
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;index.html&lt;/code&gt;
&lt;/h3&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&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Your HTML --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// ServiceWorker Registration&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serviceWorker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serviceworker.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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;registration&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;// Registration was successful&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ServiceWorker registration successful with scope: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;registration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scope&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;err&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;// registration failed :(&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ServiceWorker registration failed: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&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="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;h3&gt;
  
  
  &lt;code&gt;serviceworker.js&lt;/code&gt;
&lt;/h3&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;CACHE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;version-1&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;urlsToCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.html&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="s1"&gt;index.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Install the service worker and open the cache and add files mentioned in array to cache&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;install&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CACHE_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Opened cache&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="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;urlsToCache&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="c1"&gt;// Listens to request from application.&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="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;response&lt;/span&gt;&lt;span class="p"&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="nf"&gt;log&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="c1"&gt;// The requested file exists in cache so we return it from cache.&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="p"&gt;}&lt;/span&gt;

                &lt;span class="c1"&gt;// The requested file is not present in cache so we send it forward to the internet&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;activate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&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;cacheWhitelist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// add cache names which you do not want to delete&lt;/span&gt;
    &lt;span class="nx"&gt;cacheWhitelist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CACHE_NAME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheNames&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nx"&gt;cacheNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;cacheWhitelist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&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;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheName&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;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;
  
  
  3b. Code for loading &lt;code&gt;offline.html&lt;/code&gt; when you are offline
&lt;/h2&gt;

&lt;p&gt;To load &lt;code&gt;offline.html&lt;/code&gt; instead of the actual site, we would add &lt;code&gt;offline.html&lt;/code&gt; to &lt;code&gt;urlsToCache[]&lt;/code&gt; array. This would cache the &lt;code&gt;offline.html&lt;/code&gt; to your CacheStorage.&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;urlsToCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;offline.html&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 you are offline, the fetch operation would fail. So from the &lt;code&gt;catch&lt;/code&gt; block, we can return our cached &lt;code&gt;offline.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now replace this block with the fetch listener block in the example above.&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="c1"&gt;// Listens to request from application.&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="p"&gt;{&lt;/span&gt;

                &lt;span class="c1"&gt;// You can remove this line if you don't want to load other files from cache anymore.&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;response&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;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="c1"&gt;// If fetch fails, we return offline.html from cache.&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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;err&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;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;offline.html&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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Custom "Add to Homescreen" banner.
&lt;/h1&gt;

&lt;p&gt;This is how a default Add to Homescreen banner looks like in Chrome:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2qtfb0j17q3lvik5dxf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2qtfb0j17q3lvik5dxf.png" alt="Screenshot to show how Add to Homescreen Banner looks in Chrome" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get this banner (According to Chrome - &lt;a href="https://developers.google.com/web/fundamentals/app-install-banners/" rel="noopener noreferrer"&gt;https://developers.google.com/web/fundamentals/app-install-banners/&lt;/a&gt;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;The web app is not already installed and prefer_related_applications is not true.&lt;/li&gt;
&lt;li&gt;Includes a &lt;a href="https://developers.google.com/web/fundamentals/web-app-manifest/" rel="noopener noreferrer"&gt;web app manifest&lt;/a&gt; that includes:

&lt;ul&gt;
&lt;li&gt;short_name or name&lt;/li&gt;
&lt;li&gt;icons must include a 192px and a 512px sized icons&lt;/li&gt;
&lt;li&gt;start_url&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;display must be one of: fullscreen, standalone, or minimal-ui&lt;/li&gt;
&lt;li&gt;Served over HTTPS (required for service workers)&lt;/li&gt;
&lt;li&gt;Has registered a service worker with a fetch event handler&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;If your app passes these criteria, Users on your website will get the Add to Homescreen banner like the one shown in the image above.&lt;/p&gt;

&lt;p&gt;But instead of using the default banner we can even make a "Download App" button with our own UI. &lt;/p&gt;

&lt;p&gt;This is how I show "Download App" button in my web app &lt;a href="https://pocketbook.cc" rel="noopener noreferrer"&gt;PocketBook.cc&lt;/a&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3j0klpq405r8gpofgbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3j0klpq405r8gpofgbg.png" alt="Screenshot that shows Custom Download button instead of default Add to Homescreen" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a WebApp is downloadable (that is it passes the criteria set by the browser), it fires an event called &lt;code&gt;beforeinstallprompt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;we can listen to this event with &lt;code&gt;window.addEventListener('beforeinstallprompt', callback)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We store this event in variable so we can call the &lt;code&gt;.prompt()&lt;/code&gt; method later.&lt;br&gt;
&lt;code&gt;.prompt()&lt;/code&gt; method opens the Add to Homescreen dialog bar. So we can call this method when our Download App button is clicked.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;index.html&lt;/code&gt;, you can add&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;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"download-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Download App&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- Keep its display:none in css by default. --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and in JavaScript,&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;let&lt;/span&gt; &lt;span class="nx"&gt;deferredPrompt&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;downloadButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.download-button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;beforeinstallprompt&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="c1"&gt;// Stash the event so it can be triggered later.&lt;/span&gt;
    &lt;span class="nx"&gt;deferredPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Make the Download App button visible.&lt;/span&gt;
    &lt;span class="nx"&gt;downloadButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inline-block&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;downloadButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="nx"&gt;deferredPrompt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// This will display the Add to Homescreen dialog.&lt;/span&gt;
    &lt;span class="nx"&gt;deferredPrompt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userChoice&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;choiceResult&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;choiceResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outcome&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accepted&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;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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User accepted the A2HS prompt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User dismissed the A2HS prompt&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;deferredPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;h1&gt;
  
  
  Helpful Links:
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/thepracticaldev/dev.to/blob/39618f66a2167e88e65527b68d0fd996f0869c0a/app/assets/javascripts/serviceworker.js.erb"&gt;DEV's Service Worker file for example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/web/fundamentals/primers/service-workers/" rel="noopener noreferrer"&gt;Google Developer: Service Workers - An Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle" rel="noopener noreferrer"&gt;Google Developer: Service Worker Lifecycle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/web/fundamentals/app-install-banners/" rel="noopener noreferrer"&gt;Google Developer: App Install Banners&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I hope this article was helpful. This article was part 1 of my series &lt;strong&gt;Make Websites work offline&lt;/strong&gt; and the next part would be about &lt;strong&gt;IndexedDB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Thank You for reading this🦄 Do comment on what you think and if you are using a service worker for something different and interesting, do let me know in the comment section!&lt;/p&gt;

&lt;p&gt;byeeeee 🌻.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>html</category>
    </item>
    <item>
      <title>My year in review - 2019🌻 || Started Writing Articles, Travelled the country, and Contributing to open-source🎉</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Tue, 31 Dec 2019 20:52:50 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/my-year-in-review-2019-started-writing-articles-travelled-the-country-and-contributing-to-open-source-4l07</link>
      <guid>https://dev.to/saurabhdaware/my-year-in-review-2019-started-writing-articles-travelled-the-country-and-contributing-to-open-source-4l07</guid>
      <description>&lt;p&gt;&lt;em&gt;I'm just writing my heart out in this article, sorry if this gets boring or lengthy but it is for me to remind myself the things I did this year :)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hi, I am Saurabh (pronounced as SAW-rub). 2019 was the worst and best year at the same time and I don't know how to express but you get it right? Professionally and Emotionally I had hit my lowest and highest. 2019 was a roller coaster! &lt;/p&gt;

&lt;p&gt;Moving further in this article I will headline the important events, some of them went well some of them didn't work out but they are part of my 2019 and they did end up teaching me something.&lt;/p&gt;

&lt;h1&gt;
  
  
  January - March
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Google Summer of Code
&lt;/h2&gt;

&lt;p&gt;So I started 2019 by preparing for the &lt;a href="https://developers.google.com/open-source/gsoc/timeline" rel="noopener noreferrer"&gt;GSoC&lt;/a&gt;, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Google Summer of Code, often abbreviated to GSoC, is an international annual program, first held from May to August 2005,[1] in which Google awards stipends, which depends on the purchasing power parity of the country the student's university belongs to,[2] to all students who successfully complete a requested free and open-source software coding project during the summer. The program is open to university students aged 18 or over.&lt;/p&gt;

&lt;p&gt;-- &lt;cite&gt;&lt;a href="https://en.wikipedia.org/wiki/Google_Summer_of_Code" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I've always been more into the maintaining and creating side of the open-source and less into contributing and I was scared of pushing a wrong code or doing something dumb to the repository but I finally decided to break this anxiety by participating in Google Summer of Code. &lt;/p&gt;

&lt;p&gt;I started contributing to an organization that I liked and made a small PR (3 lines of code to check the validation of a form field) and IT WAS MERGED! I was extremely happy as it was my first PR into someone else's repository.&lt;/p&gt;

&lt;p&gt;the results were announced in April and I couldn't make it through and I was sad but I think it's ok to be sad and the whole experience of writing the application was extremely helpful for me to get started with the open-source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built website for the College Technical Fest!
&lt;/h2&gt;

&lt;p&gt;Every year our college arranges a technical festival called Avalon. I was part of the web team in Avalon 2018 as well and in 2019 I was the head of Creativity Team (WEB) and building a website was all up to me.&lt;/p&gt;

&lt;p&gt;I always loved developing portfolio sort of websites. They let you go out of the box and there isn't any "standard" way for these websites.&lt;/p&gt;

&lt;p&gt;For Avalon 2019, our theme was about Mars Exploration so I decided to build something totally out of the world (hehe). &lt;/p&gt;

&lt;p&gt;Here's how that website looked like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F438p64o12rhitpxixnru.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F438p64o12rhitpxixnru.gif" alt="Screen record of Avalon website" width="600" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used ThreeJS to build mars, its moons, and the sun! and you could move it with your mouse/touch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs8lhater5z30kh5h1bdz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs8lhater5z30kh5h1bdz.gif" alt="GIF of Avalon 2019 " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code behind the rocket is the piece of code that I am most proud of. I change the bottom and right values on the scroll event and there's some trigonometry to make it move that way.&lt;/p&gt;
&lt;h2&gt;
  
  
  Travelling to Bangalore for Hackathon
&lt;/h2&gt;

&lt;p&gt;We are a team of 4 people and we usually apply to a lot of hackathons and so we applied to a hackathon in Bangalore and we were shortlisted for the offline round! we traveled from Mumbai to Bangalore and it was the first time for me to travel to a different state for a hackathon and also the first time in Bangalore.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Fun Fact: &lt;a href="https://en.wikipedia.org/wiki/Bangalore" rel="noopener noreferrer"&gt;Bangalore&lt;/a&gt; is sometimes referred to as a "Silicon Valley of India"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rdnm5fcd4bc9vbj9t33.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3rdnm5fcd4bc9vbj9t33.jpeg" alt="Bangalore image" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftof71gm1robf7jtanu3k.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftof71gm1robf7jtanu3k.jpeg" alt="Bangalore image" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was an RPA hackathon and we were told to build a bot that performs some actions like, reading price of the products and applying some filters on an E-commerce website. We didn't win this either but it was a fun experience to go out with friends.&lt;/p&gt;
&lt;h1&gt;
  
  
  March - August
&lt;/h1&gt;

&lt;p&gt;These 6 months, was the most difficult time I ever faced in my life. I couldn't do much during this and was not very stable emotionally. I usually try to avoid coding when I am not feeling my best.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcjwj3ork8e1kdk1hmgc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdcjwj3ork8e1kdk1hmgc.jpeg" alt="saurabhdaware contribution graph from github" width="441" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After June I started coding actively but it was only because I had to. After June things got worse, to be honest.&lt;/p&gt;
&lt;h2&gt;
  
  
  A Blockchain hackathon in Hyderabad.
&lt;/h2&gt;

&lt;p&gt;In June, we were selected in another hackathon which was in Hyderabad. Even though I was not at my best (probably I was at my worst) I went for the hackathon and liked those few days. &lt;/p&gt;

&lt;p&gt;We built a Smart Contract application to sell properties without paperwork (sort of like an Amazon for buying a house)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7pck5oljp4tluv04r8x2.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7pck5oljp4tluv04r8x2.jpeg" width="800" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh89sjdvo6t61lwt1micg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fh89sjdvo6t61lwt1micg.jpeg" width="720" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  August - December
&lt;/h1&gt;

&lt;p&gt;August was all about recovery🌻 I went on solo dates, started reading a book (The Grand Design by Stephen Hawking and Leonard Mlodinow), and started appreciating people I have around.&lt;/p&gt;

&lt;p&gt;Appreciating people helped me a lot to get back that positivity I had lost in the last few months. (I can literally write a whole separate article on how appreciating other people help me.)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw9t357602h9596uekmpj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fw9t357602h9596uekmpj.jpeg" width="616" height="1280"&gt;&lt;/a&gt;&lt;br&gt;
I went to college and the college was closed so I just started roaming around my college and found this place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fngbvmv09ojvj1pv30mkt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fngbvmv09ojvj1pv30mkt.jpeg" width="730" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Started writing on DEV
&lt;/h2&gt;

&lt;p&gt;AANDDD FINALLY I did the best possible thing!! wrote an article!!! on DEV!!!! yaaaay!! it was one of the best decisions of my life!! &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/saurabhdaware" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F174161%2Fe04efa48-2ea8-42ba-82a0-824e81857d50.png" alt="saurabhdaware"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/saurabhdaware/turn-existing-website-to-pwa-in-1-minute-using-pwainit-8do" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Turn existing website to PWA in 1 minute using PWAinit&lt;/h2&gt;
      &lt;h3&gt;Saurabh Daware 🌻 ・ Aug 27 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#npm&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#pwa&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
I was not really sure if I was ready but I simply wrote about the thing that I made and had zero expectations from the article and surprisingly it got 65 REACTIONS! this was (and still is) a huge number for me.

&lt;p&gt;The best part about DEV is the people. The community is soo positive and has always been super supportive with whatever I wrote.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hackathon in Pune
&lt;/h2&gt;

&lt;p&gt;This time we finally won! not the first prize though we were runner ups still it was very special. We finally had a trophy in our hands. We built an automated plagiarism checker to check the plagiarized content from technical papers and reply to the user accordingly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trip with family to Gujarat
&lt;/h2&gt;

&lt;p&gt;We trekked to the highest mountain in Gujarat, Girnar hill which is 1031m tall. It was one of the best experiences of my life! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgkkeiq67j33lf15hp7qn.jpeg" class="article-body-image-wrapper"&gt;&lt;img alt="Gujarat" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgkkeiq67j33lf15hp7qn.jpeg" width="800" height="385"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1xuc7bm7y59x3vrd5f2a.jpeg" class="article-body-image-wrapper"&gt;&lt;img alt="Picture" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F1xuc7bm7y59x3vrd5f2a.jpeg" width="800" height="385"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgkeuen0jlgslrz933e5q.jpeg" class="article-body-image-wrapper"&gt;&lt;img alt="Picture" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgkeuen0jlgslrz933e5q.jpeg" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Hacktoberfest
&lt;/h2&gt;

&lt;p&gt;AND THEN ANOTHER BIG MONTH! OCTOBER! finally time for Hacktberfest! I was extremely excited about the Hacktoberfest. I was now comfortable with the contributions part still I never had any major contributions on GitHub.&lt;/p&gt;

&lt;p&gt;I decided to break this and make some meaningful contributions and finally ended up contributing to DEV.to, React, Prompts, Tomorrow App.&lt;/p&gt;

&lt;p&gt;Writing a color preview feature for DEV was my favorite contribution.&lt;/p&gt;

&lt;p&gt;This is how I prototyped the idea to Jess 😂😭😭&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/thepracticaldev/dev.to/issues/4106#issuecomment-536584845"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        Comment for
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#4106&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars0.githubusercontent.com%2Fu%2F30949385%3Fu%3De0c1e72ac25023c5ea5f9ee93a00ef1e7652c854%26v%3D4" alt="saurabhdaware avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;saurabhdaware&lt;/a&gt;
        &lt;/strong&gt; commented on &lt;a href="https://github.com/thepracticaldev/dev.to/issues/4106#issuecomment-536584845"&gt;&lt;time&gt;Sep 30, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;How about having a DEV logo in edit profile that changes color as you change background color and color? This can help you tell if background color and color match properly.
something like:
&lt;a href="https://user-images.githubusercontent.com/30949385/65887188-28897f80-e3bb-11e9-90f6-452d6b2f28c6.jpeg" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F30949385%2F65887188-28897f80-e3bb-11e9-90f6-452d6b2f28c6.jpeg" width="300"&gt;&lt;/a&gt;
(Sorry for my drawing skills I edited in instagram stories 😭 🤣 )&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/thepracticaldev/dev.to/issues/4106#issuecomment-536584845"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Here's the pull request:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/thepracticaldev/dev.to/pull/4212"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        Fix #4106: Showing color preview in Edit Profile
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#4212&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars1.githubusercontent.com%2Fu%2F30949385%3Fv%3D4" alt="saurabhdaware avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/saurabhdaware" rel="noopener noreferrer"&gt;saurabhdaware&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/thepracticaldev/dev.to/pull/4212"&gt;&lt;time&gt;Oct 03, 2019&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;What type of PR is this? (check all applicable)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Refactor&lt;/li&gt;
&lt;li&gt;[x] Feature&lt;/li&gt;
&lt;li&gt;[ ] Bug Fix&lt;/li&gt;
&lt;li&gt;[ ] Documentation Update&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Description&lt;/h2&gt;
&lt;p&gt;Fixes #4106.&lt;/p&gt;
&lt;p&gt;The current color-picker does not show a preview so it is hard to guess the color contrast. I added a preview (screenshot added below) which shows your selected colors.&lt;/p&gt;
&lt;p&gt;Also, Added a &lt;code&gt;&amp;lt;input type="color"&amp;gt;&lt;/code&gt; which makes it is easy to select the color.&lt;/p&gt;
&lt;p&gt;Since there are other pages that depend on 'color-picker' class I did not change anything in &lt;code&gt;colorPicker.js&lt;/code&gt; or any of the styles of current color-picker. I created a new file &lt;code&gt;colorPreview.js&lt;/code&gt; and some new classes in html.&lt;/p&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Mobile &amp;amp; Desktop Screenshots/Recordings (if there are UI changes)&lt;/h2&gt;
&lt;h3&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Mobile&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://user-images.githubusercontent.com/30949385/66120518-a8505d80-e5f8-11e9-875d-ebe1b01e597e.png" rel="nofollow noopener noreferrer"&gt;&lt;img width="300" alt="Mobile screenshot of color preview feature" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F30949385%2F66120518-a8505d80-e5f8-11e9-875d-ebe1b01e597e.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Desktop&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://user-images.githubusercontent.com/30949385/66120485-94a4f700-e5f8-11e9-9d4d-817d94521ec0.png" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F30949385%2F66120485-94a4f700-e5f8-11e9-9d4d-817d94521ec0.png" alt="Desktop Screenshot of color preview feature"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Recording&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://user-images.githubusercontent.com/30949385/66121015-d2eee600-e5f9-11e9-8d70-e6fb83ee0739.gif" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F30949385%2F66121015-d2eee600-e5f9-11e9-8d70-e6fb83ee0739.gif" alt="Recording of color preview feature"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;Added to documentation?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[ ] docs.dev.to&lt;/li&gt;
&lt;li&gt;[ ] readme&lt;/li&gt;
&lt;li&gt;[x] no documentation needed&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
&lt;span class="octicon octicon-link"&gt;&lt;/span&gt;[optional] What gif best describes this PR or how it makes you feel?&lt;/h2&gt;
&lt;p&gt;My first PR To DEV!
I was not very sure if I could do this or not since DEV's codebase is probably the largest codebase I've ever worked on but now I'm super proud of myself to complete this 🌻&lt;/p&gt;
&lt;p&gt;Me showing this code to everyone :
&lt;a href="https://camo.githubusercontent.com/9a38d0d198c161ecd136f00bbb80d9c16849385d/68747470733a2f2f36362e6d656469612e74756d626c722e636f6d2f39313661356466343437353538636330326362636266626461376162366236622f74756d626c725f70316d67636c634c6344317369656975656f315f3530302e676966" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/9a38d0d198c161ecd136f00bbb80d9c16849385d/68747470733a2f2f36362e6d656469612e74756d626c722e636f6d2f39313661356466343437353538636330326362636266626461376162366236622f74756d626c725f70316d67636c634c6344317369656975656f315f3530302e676966" alt="Elsa showing magic to Anna"&gt;&lt;/a&gt;&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/thepracticaldev/dev.to/pull/4212"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;So I finished my Hackatoberfest successfully🎉&lt;/p&gt;

&lt;p&gt;Also, received my tee and stickers of Hacktoberfest!&lt;br&gt;
P.S. I ordered the wrong size t-shirt so now my whole body fits into that t-shirt😂😭 I still love it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Job Interview
&lt;/h2&gt;

&lt;p&gt;I usually apply to a lot of companies and very few replies and one of the companies that I always wanted join replied and asked me to send a resume. I did and they selected my resume and I cleared the next few rounds as well then there was an interview with the head developer and it was the BEST INTERVIEW OF MY WHOLE LIFE! She gave a very fair chance to prove myself and we had a discussion about building a snake game. It was a super cool conversation and I did not feel scared or uncomfortable even for a bit. However, I was rejected later in the algorithms round. Still, this will always be the best interview I ever had. &lt;/p&gt;

&lt;p&gt;Sometimes it's not really about getting selected but it's that experience.&lt;/p&gt;




&lt;p&gt;And if you feel sad, just remember that it's ok to be sad, It's ok if you want to cry, that's what humans do! Crying just makes you realize how important that particular thing was.&lt;/p&gt;

&lt;p&gt;When I started my year my plan was to complete the Google Summer of Code, Get good marks and get a good job and my 2019 was literally everything but that 😂😭😭&lt;/p&gt;

&lt;p&gt;While we want our lives to be just like we planned. Sometimes we have to appreciate this non-perfectness in life. At the start of my year, I had no idea that something like DEV existed. Writing articles was never in a plan, I built &lt;a href="https://github.com/saurabhdaware/pwainit" rel="noopener noreferrer"&gt;PWAinit&lt;/a&gt;, &lt;a href="https://github.com/saurabhdaware/projectman" rel="noopener noreferrer"&gt;ProjectMan&lt;/a&gt;, &lt;a href="https://pocketbook.cc" rel="noopener noreferrer"&gt;PocketBook&lt;/a&gt; and a lot of other things this year which were not in a plan as well.&lt;/p&gt;

&lt;p&gt;Now when I look back to 2019, It wasn't exactly the way I wanted but it still was pretty cool and it is something to appreciate. I am super proud of myself for getting through this year. Also, want to thank the people that I have in my life who are always there for emotional support.&lt;/p&gt;

&lt;p&gt;Thank you and wish you all a very Happy New Year🎉🌻&lt;/p&gt;

</description>
      <category>yearinreview</category>
      <category>mentalhealth</category>
      <category>career</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I made PocketBook.cc 🌻 a Google Keep alternative that lets you create notebooks and manage important notes📝🦄</title>
      <dc:creator>Saurabh Daware 🌻</dc:creator>
      <pubDate>Sat, 14 Dec 2019 19:40:59 +0000</pubDate>
      <link>https://dev.to/saurabhdaware/introducing-pocketbook-ml-a-google-keep-alternative-that-lets-you-create-notebooks-and-manage-important-notes-2j22</link>
      <guid>https://dev.to/saurabhdaware/introducing-pocketbook-ml-a-google-keep-alternative-that-lets-you-create-notebooks-and-manage-important-notes-2j22</guid>
      <description>&lt;p&gt;&lt;em&gt;Note: I've moved the domain from .ml to .cc&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A lot of times I have to note down something important. Sometimes it could be an important point of tech or I might have to write down my feelings and Notebook, Pen are not always accessible.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://pocketbook.cc" rel="noopener noreferrer"&gt;PocketBook.cc&lt;/a&gt;, I wanted to create a place where you can write down anything you want! It could be your secret or an important point or your todo list.&lt;/p&gt;

&lt;p&gt;PocketBook stores data in browser storage(IndexedDB) by default so that you can write down your deepest secrets without letting any company read your data.&lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;[A 37-second youtube video of pocketbook.cc demo]&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/g5zASA2V0NI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  Key Features
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Stores data in browser storage by default thus keeping your data private.&lt;/li&gt;
&lt;li&gt;Works offline.&lt;/li&gt;
&lt;li&gt;You can use it without a login/registration.&lt;/li&gt;
&lt;li&gt;Downloadable (Go to more options on the main page and click download button(I've only tested in Chrome yet))&lt;/li&gt;
&lt;li&gt;You can choose to make your notebook remotely accessible which puts notebook content in cloud storage and thus you can edit its content from other devices as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what do you guys think about this project? Do let me know in the comments below! &lt;/p&gt;

&lt;p&gt;Thank you so much for reading this🌻&lt;/p&gt;

&lt;p&gt;For more information on how I store the data, check out &lt;a href="https://pocketbook.cc/info" rel="noopener noreferrer"&gt;https://pocketbook.cc/info&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PocketBook Link:&lt;/strong&gt; &lt;a href="https://pocketbook.cc" rel="noopener noreferrer"&gt;https://pocketbook.cc&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Edit2: I've moved the website from pocketbook.ml to pocketbook.cc (Some countries and browser were not supporting the domain), Since the indexeddb data is domain-specific, the notebooks you made on pocketbook.ml will not be accessible from .cc. For the users who have data on .ml domain will get an option to move data on the main page of .ml website&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
