<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Himani Mehra</title>
    <description>The latest articles on Forem by Himani Mehra (@himanimehra).</description>
    <link>https://forem.com/himanimehra</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%2F1215291%2F18559955-de07-4d09-88e4-190493af8813.jpeg</url>
      <title>Forem: Himani Mehra</title>
      <link>https://forem.com/himanimehra</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/himanimehra"/>
    <language>en</language>
    <item>
      <title>React notes</title>
      <dc:creator>Himani Mehra</dc:creator>
      <pubDate>Fri, 18 Jul 2025 04:47:02 +0000</pubDate>
      <link>https://forem.com/himanimehra/react-notes-2mp9</link>
      <guid>https://forem.com/himanimehra/react-notes-2mp9</guid>
      <description>&lt;p&gt;🧠 Emmet (Shortcuts for HTML/CSS)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What: A shortcut tool in editors like VS Code to write HTML/CSS faster.&lt;/li&gt;
&lt;li&gt;Why: Saves time by expanding short code into full HTML/CSS.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTML Example:&lt;br&gt;
ul&amp;gt;li*3&lt;br&gt;
➜ Expands to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;CSS Example:&lt;br&gt;&lt;br&gt;
m10&lt;br&gt;&lt;br&gt;
➜ Expands to:&lt;br&gt;&lt;br&gt;
margin: 10px;&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Usage: Just type and press Tab.&lt;br&gt;
Library vs Framework&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Library:
👉 You call the code when needed (You decide when and where to use it.)
👉 You are in control.
(e.g., React, Lodash)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Framework:&lt;br&gt;
👉 Framework calls your code.&lt;br&gt;
👉 It controls the flow. (It tells when to run your code — you just “plug in” your logic.)&lt;br&gt;
(e.g., Angular, Next.js)&lt;br&gt;
✅ Why React is a Library?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React only handles the UI (view).&lt;/li&gt;
&lt;li&gt;You decide how the rest of the app works.&lt;/li&gt;
&lt;li&gt;It doesn’t force structure or tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧩 Tools You Choose in React:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routing: react-router-dom&lt;/li&gt;
&lt;li&gt;State: useState, Redux, Zustand, Recoil&lt;/li&gt;
&lt;li&gt;Data Fetching: fetch, axios, React Query, SWR&lt;/li&gt;
&lt;li&gt;Forms: Formik, React Hook Form&lt;/li&gt;
&lt;li&gt;Styling: CSS, SCSS, Tailwind, styled-components&lt;/li&gt;
&lt;li&gt;Testing: Jest, React Testing Library, Cypress&lt;/li&gt;
&lt;li&gt;Build Tools: Vite, Webpack, CRA, Next.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🎯 Summary: React is flexible — it’s a UI library, not a full framework.&lt;/p&gt;

&lt;p&gt;🧠 So… is Vue a library or a framework?&lt;br&gt;
➡️ Vue 2: Mostly considered a library (like React) — focuses on the view layer.&lt;br&gt;
➡️ Vue 3 with ecosystem (Vuex, Vue Router, CLI): Becomes a framework.&lt;br&gt;
React Vue 2 — library ; Vue 3 + Tools Framework-ish ; Angular — Full Framework&lt;/p&gt;

&lt;p&gt;🧠 How does the browser know about &lt;code&gt;document&lt;/code&gt;, &lt;code&gt;createElement&lt;/code&gt;, etc.?&lt;br&gt;
These come from Browser APIs, not from JavaScript itself.&lt;/p&gt;

&lt;p&gt;🔧 How it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser has a JavaScript engine (like Chrome’s V8).&lt;/li&gt;
&lt;li&gt;The browser provides built-in objects like:
— window
— document
— console
— localStorage
— fetch, etc.&lt;/li&gt;
&lt;li&gt;These are called Web APIs — part of the browser environment, not core JavaScript.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 Example:&lt;/p&gt;

&lt;p&gt;const div = document.createElement(“div”);&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;document&lt;/code&gt; comes from the DOM API.&lt;/li&gt;
&lt;li&gt;It’s not part of core JS — it’s provided by the browser when JS runs in the browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ Note:&lt;br&gt;
If you run JavaScript outside the browser (like in Node.js),&lt;br&gt;
→ You won’t get &lt;code&gt;document&lt;/code&gt; or &lt;code&gt;window&lt;/code&gt; — because there’s no DOM.&lt;/p&gt;

&lt;p&gt;✅ In short:&lt;br&gt;
JS runs inside the browser’s environment,&lt;br&gt;
and the browser gives extra objects (like &lt;code&gt;document&lt;/code&gt;) via Browser APIs.&lt;/p&gt;

&lt;p&gt;We can inject react library with a bare minimum thing&lt;/p&gt;

&lt;p&gt;What is CDN?&lt;/p&gt;

&lt;p&gt;🧠 What is a CDN?&lt;/p&gt;

&lt;p&gt;CDN = Content Delivery Network&lt;/p&gt;

&lt;p&gt;It’s a network of distributed servers that deliver files (JS, CSS, images) from the &lt;strong&gt;nearest location to the user&lt;/strong&gt; — making websites faster and more reliable.&lt;/p&gt;

&lt;p&gt;🌍 Real-world example:&lt;/p&gt;

&lt;p&gt;When you visit a site using a CDN:&lt;/p&gt;

&lt;p&gt;If you’re in India, the content may load from a server in Mumbai&lt;br&gt;
If you’re in the US, it loads from a New York or LA server&lt;br&gt;
This minimizes latency and speeds up loading.&lt;/p&gt;

&lt;p&gt;📦 How does it relate to React?&lt;/p&gt;

&lt;p&gt;React can be included via &lt;strong&gt;CDN links&lt;/strong&gt; instead of installing via npm.&lt;/p&gt;

&lt;p&gt;Example:&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;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;”https://unpkg.com/react@18/umd/react.development.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-dom@18/umd/react-dom.development.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

🧠 Real-life example of using a CDN:

Let’s say you want to use a **carousel/slider** in your web app.

Instead of downloading the whole library,
you can just include its **CDN link** in your HTML:

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

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
html&lt;br&gt;
&amp;lt;! — Slick Carousel CSS →&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&amp;lt;! — Slick Carousel JS →&lt;/p&gt;

&lt;p&gt;🚀 Why use CDN links?&lt;/p&gt;

&lt;p&gt;Quick setup — no build tools needed&lt;br&gt;
Great for testing or small apps&lt;br&gt;
No need to install Node.js or npm&lt;br&gt;
⚠️ Not ideal for large/production apps → Use bundlers like Vite or Webpack for better control.&lt;/p&gt;

&lt;p&gt;A CDN serves files faster from nearby servers.&lt;/p&gt;

&lt;p&gt;React’s CDN version lets you use React by just adding  tags — no installation required.&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;🧠 What is &amp;lt;code&amp;gt;crossorigin&amp;lt;/code&amp;gt; in a &amp;lt;code&amp;gt;&amp;amp;lt;script&amp;amp;gt;&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;amp;lt;link&amp;amp;gt;&amp;lt;/code&amp;gt; tag?&amp;lt;br&amp;gt;
The &amp;lt;code&amp;gt;crossorigin&amp;lt;/code&amp;gt; attribute tells the browser how to handle &amp;lt;strong&amp;gt;cross-origin requests&amp;lt;/strong&amp;gt; — when you’re loading files from a &amp;lt;strong&amp;gt;different domain&amp;lt;/strong&amp;gt; (like a CDN).&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;— -&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;🌍 Example:&amp;lt;br&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight html"&amp;gt;&amp;lt;code&amp;gt;&amp;lt;span class="nt"&amp;gt;&amp;amp;lt;script
&amp;lt;/span&amp;gt;&amp;lt;span class="na"&amp;gt;src=&amp;lt;/span&amp;gt;&amp;lt;span class="s"&amp;gt;”https://unpkg.com/react@18/umd/react.development.js"&amp;lt;/span&amp;gt;
&amp;lt;span class="na"&amp;gt;crossorigin&amp;lt;/span&amp;gt;
&amp;lt;span class="nt"&amp;gt;&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;&amp;lt;/span&amp;gt;

🧠 What does *“different domain”* mean in `crossorigin`?

It means the file (like a script or image) is **NOT hosted on your website**, but coming from **another server**.

— -

🌐 Example:

You made a website:
👉 `https://myportfolio.com`

Now, you add this:

&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;br&amp;gt;
html&amp;lt;/p&amp;gt;

&amp;lt;script src=”https://unpkg.com/react@18/umd/react.development.js" crossorigin&amp;gt;

&lt;/p&gt;
&lt;p&gt;📦 That script is from &lt;a href="https://unpkg.com" rel="noopener noreferrer"&gt;https://unpkg.com&lt;/a&gt; — a different domain.&lt;/p&gt;

&lt;p&gt;So: myportfolio.com ≠ unpkg.com → cross-origin request&lt;br&gt;
Different domain” means the file is loaded from another website/serve&lt;/p&gt;

&lt;p&gt;🧠 Shortest React program (with CDN):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;”https://unpkg.com/react@18/umd/react.development.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-dom@18/umd/react-dom.development.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;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;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;|
✅ This runs without any build tools (like npm, Vite, etc.)
✅ Just open in browser — you’ll see: Hello React

why? Because in console write React and it give React object (like windows object). Also React is a global object

React is just a peice of JS code written by meta developers.

Why 2 files : React and ReactDOM ; because react is not just limited to browsers. Thers is react native for mobile, react 3D as well, react also used in rendering engines.

So react@18 is core library of react
react-dom: the web version of react

Heading using React
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Document&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;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;/body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script
    &lt;/span&gt;&lt;span class="na"&gt;crossorigin&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/react@18/umd/react.production.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;crossorigin&lt;/span&gt;
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/react-dom@18/umd/react-dom.production.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;/html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;heading&lt;/span&gt; &lt;span class="o"&gt;=&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="s2"&gt;h1&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Heading using react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// it taskes 3 argument - 1.the tag 2.object 3.value&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
// h1 comes from the core library of react
now heading is created, now we need to put heading into the root element

  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;heading&lt;/span&gt; &lt;span class="o"&gt;=&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="s2"&gt;h1&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Heading using react&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;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;//this tells react what is the root element inside my app. Also here we used ReactDOM because now we are manipulating DOM&lt;/span&gt;
    &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;heading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// passing react element inside the root&lt;/span&gt;
  &lt;span class="c1"&gt;// So this render method takes react element and injects it into the DOM and modifies it&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
🧠 Is `createElement` an API?

Yes — `React.createElement()` is a **React API**.

It’s a method provided by the React library to **create React elements** (UI building blocks) without using JSX.

— -

🔧 Syntax:

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

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
js&lt;br&gt;
React.createElement(type, props, children)&lt;/p&gt;

&lt;p&gt;if we do:&lt;br&gt;
console.log(heading); // it is plain JS object&lt;/p&gt;

&lt;p&gt;// so the react code that meta developers wrote is taking : "h1", {}, "Heading usi&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How To Make Parallel API calls in VueJS Applications — Typescript Version</title>
      <dc:creator>Himani Mehra</dc:creator>
      <pubDate>Sun, 17 Dec 2023 04:54:42 +0000</pubDate>
      <link>https://forem.com/himanimehra/how-to-make-parallel-api-calls-in-vuejs-applications-typescript-version-178e</link>
      <guid>https://forem.com/himanimehra/how-to-make-parallel-api-calls-in-vuejs-applications-typescript-version-178e</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yKWUAH97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pdyqnkjczvborryp9ks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yKWUAH97--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5pdyqnkjczvborryp9ks.png" alt="Image description" width="698" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In web applications, all the data you show on the page should reside somewhere, for example, cache, database, storage account, etc. You need to fetch the data from the different sources and do some processing and then render the data on the UI. All the data can be accessed through APIs nowadays and most of the time the format would be in the JSON format.&lt;/p&gt;

&lt;p&gt;Sometimes, making one API call is not enough you might need to get the data from different sources and these sources might be different APIs. We can make all the calls in parallel to decrease the latency of the application.&lt;/p&gt;

&lt;p&gt;In this post, we will see how to make parallel API calls in Vue applications (written in typescript) using Fetch and Axios. You can do API calls with either of these.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prerequisites&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example Project&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API Endpoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UI Implementation and Integration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call The APIs with Fetch and Promise.all&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call The APIs with Axios and Promise.all&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Demo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Summary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conclusion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are some prerequisites for this article. You need to have NodeJS installed on your laptop and know-how HTTP works. If you want to practice and run this on your laptop you need to have these on your machine.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/en/"&gt;&lt;strong&gt;NodeJS&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cli.vuejs.org/"&gt;&lt;strong&gt;Vue CLI&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://code.visualstudio.com/"&gt;&lt;strong&gt;VSCode&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://bootstrap-vue.org/"&gt;&lt;strong&gt;BootstrapVue&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.typescriptlang.org/"&gt;Typescript&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please go through these links if you are new to web development and make sure you understand how UI and API work together.&lt;/p&gt;

&lt;p&gt;How To Develop and Build Vue.js App With NodeJS&lt;/p&gt;

&lt;p&gt;How To Make API calls in Vue.JS Applications&lt;/p&gt;

&lt;p&gt;Example Project&lt;br&gt;
Here is the example project in which we are making three API calls and combining them and loading the table. Those three calls take different times to complete.&lt;/p&gt;

&lt;p&gt;// clone the project&lt;br&gt;
git clone…&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How I created my own digital cursive writing notebook..</title>
      <dc:creator>Himani Mehra</dc:creator>
      <pubDate>Wed, 22 Nov 2023 07:11:58 +0000</pubDate>
      <link>https://forem.com/himanimehra/how-i-created-my-own-digital-cursive-writing-notebook-1fg1</link>
      <guid>https://forem.com/himanimehra/how-i-created-my-own-digital-cursive-writing-notebook-1fg1</guid>
      <description>&lt;p&gt;After successfully hosting a project (&lt;em&gt;&lt;a href="https://www.paletto.org/"&gt;Paletto&lt;/a&gt;&lt;/em&gt;). I started searching for a new project idea. One day, my friend ordered a pen tablet for note-taking. We were both excited to use it and opened MSPaint and Google Keep.&lt;br&gt;
We tried sketching, writing words, using technical jargon, and creating flowcharts, arrows, and other figures commonly used in note-making. It felt like being a toddlers, knowing what to write but struggling with how to write. Then searched for a site where we could practice alphabets, numbers, or sketches but only plain canvas was available. And from there emerged an idea for my next project i.e. &lt;em&gt;&lt;strong&gt;&lt;a href="https://cursive.paletto.org/"&gt;Practice Digital Handwriting&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4_NwFodE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbm6xobagrxv3z6tmsyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4_NwFodE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xbm6xobagrxv3z6tmsyz.png" alt="Image description" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now this is unlike my previous project (&lt;em&gt;&lt;a href="https://www.paletto.org/"&gt;https://www.paletto.org/&lt;/a&gt;&lt;/em&gt;), where I made a blueprint and noted down what users were unsatisfied with competitors, here the only thing I searched was the user base/customer demographic that will use the product and found out they were one of these:-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Online teachers/educators&lt;/li&gt;
&lt;li&gt;Students/professionals making notes (The very purpose, my 
friend bought the pen tablet)&lt;/li&gt;
&lt;li&gt;School kids might be practicing cursive writing online as well&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this project, idea was clear to give users a canvas space for them to practice and improve their handwriting. This is where I went wrong in planning and organizing my project as I directly started coding without making a blueprint of what my landing page would be, would it be directly canvas or a welcome page. I have written about** Developing Forward Visionary** in my blog for Domain Hosting.&lt;br&gt;
Moving on to the technical details, We will be going backward i.e. from the final page to the landing page, as I want to keep a real experience rather than showcasing to the reader that it is a smooth journey like we first go to landing page then click on this card then canvas is displayed &lt;strong&gt;"NO"&lt;/strong&gt;. &lt;br&gt;
The landing page was developed at last😅.&lt;br&gt;
Now we will go through the actual journey of development. I am going to follow a template because the final goal was to have a better, easy and smooth user experience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What I coded&lt;/li&gt;
&lt;li&gt;Found out the flaws during critical analysis of code and UI.&lt;/li&gt;
&lt;li&gt;Working on the flaws and improving the code and UI.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So first I coded a plain canvas and hardcoded alphabets (A-Z) on it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Flaws:
&lt;/h2&gt;

&lt;p&gt;1.) I was able to write with the mouse but when I was trying to &lt;br&gt;
    write with a pen table (which was the center point of making &lt;br&gt;
    this project). The cursor was getting disappeared, in &lt;br&gt;
    technical terms, the event listeners was unable to recognize &lt;br&gt;
    this event.&lt;br&gt;
2.) I hardcoded the alphabet, leaving users with no choice of &lt;br&gt;
    practicing anything but capital alphabets.&lt;br&gt;
3.) The color of the alphabets in the canvas was too dark and I &lt;br&gt;
    was unable to see the letters I had traced.&lt;br&gt;
4.) The default font was &lt;em&gt;Sans-serif&lt;/em&gt;, but the font has to be &lt;br&gt;
    something related to free handwriting having free and loose &lt;br&gt;
    strokes.&lt;br&gt;
5.) While making any mistake, there was no option to erase or &lt;br&gt;
    clear the screen and most importantly user might want to see &lt;br&gt;
    only his traced part and not the printed alphabets on canvas.&lt;/p&gt;

&lt;p&gt;So to tackle the &lt;strong&gt;first and the prime issue&lt;/strong&gt; I searched and found mousedown, mousemove, mouseup would not work for an external connected pen.&lt;br&gt;
Extra event listners that needs to be added in the code were touchstart, touchmove, touchend:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;canvas.addEventListener('mousedown', handleWritingStart);
canvas.addEventListener('mousemove', handleWritingInProgress);
canvas.addEventListener('mouseup', handleDrawingEnd);
canvas.addEventListener('mouseout', handleDrawingEnd);

canvas.addEventListener('touchstart', handleWritingStart);
canvas.addEventListener('touchmove', handleWritingInProgress);
canvas.addEventListener('touchend', handleDrawingEnd);
clearButton.addEventListener('click', handleClearButtonClick);

function getMosuePositionOnCanvas(event) {
  const clientX = event.clientX || event.touches[0].clientX;
  const clientY = event.clientY || event.touches[0].clientY;
  const { offsetLeft, offsetTop } = event.target;
  const canvasX = clientX - offsetLeft;
  const canvasY = clientY - offsetTop;
  return { x: canvasX, y: canvasY };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To tackle the &lt;strong&gt;second flaw&lt;/strong&gt;, brainstorming was done around how many options should be provided, and decided to provide users with the following cards to practice:&lt;/p&gt;

&lt;p&gt;1.) Uppercase alphabets (A-Z)&lt;br&gt;
2.) Lowercase alphabets (a-z)&lt;br&gt;
3.) Numbers (0–9)&lt;br&gt;
4.) Special characters&lt;br&gt;
5.) Giving an upload option so that the user can upload any image &lt;br&gt;
    and practice sketching.&lt;/p&gt;

&lt;p&gt;Now to give these many options and have spaceous writing areas, I took inspiration from my previous project &lt;em&gt;Paletto&lt;/em&gt;, to divide the screen in the left and right section. The leftsection is scrollable and has all the option cards whereas the right section is fully dedicated to writing practice:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4yZ5pc-o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnfvfw83fynwspxiyiub.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4yZ5pc-o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rnfvfw83fynwspxiyiub.png" alt="Image description" width="800" height="376"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="container hidden" id="first-card-section"&amp;gt;
        &amp;lt;div class="left-section" id="options"&amp;gt;
            &amp;lt;div class="paper-section" onchange="startPractice()"&amp;gt;
                &amp;lt;div class="option_paper" data-option="uppercase"&amp;gt;ABC&amp;lt;/div&amp;gt;
                &amp;lt;div class="option_paper" data-option="lowercase"&amp;gt;abc&amp;lt;/div&amp;gt;
                &amp;lt;div class="option_paper" data-option="numbers"&amp;gt;123&amp;lt;/div&amp;gt;
                &amp;lt;div class="option_paper" data-option="special"&amp;gt;$*/&amp;lt;/div&amp;gt;
                &amp;lt;div class="option_paper" data-option="upload"&amp;gt;
                    &amp;lt;input type="file" id="imageInput" accept="image/*"&amp;gt;Upload &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div id="right-section" class="right-section"&amp;gt;
            &amp;lt;div class="canvas-space"&amp;gt;
                &amp;lt;canvas id="drawing-area" class="drawing-area" height="500" width="950"&amp;gt;&amp;lt;/canvas&amp;gt;
                &amp;lt;canvas id="overlay-canvas" class="drawing-area" height="500" width="950"&amp;gt;&amp;lt;/canvas&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JS code:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function startPractice(selectedOption) {
  const canvas = document.getElementById("drawing-area");
  const ctx = canvas.getContext("2d");
  let content = "";
  if (selectedOption === "uppercase") {
    content = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  } else if (selectedOption === "lowercase") {
    content = "abcdefghijklmnopqrstuvwxyz";
  } else if (selectedOption === "numbers") {
    content = "0123456789";
  } else if (selectedOption === "special") {
    content = "!@#$%^&amp;amp;*(){}[]:;?/&amp;lt;&amp;gt;";
  } else if (selectedOption === "image") {
    const img = new Image();
    img.onload = function () {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    };
    img.src = "./images/sample.png";
  }
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.font = '30px "classic notes", cursive';
  ctx.textBaseline = "middle";
  ctx.textAlign = "center";
  const numPerRow = 6;
  const charWidth = canvas.width / numPerRow;
  const charHeight = canvas.height / Math.ceil(content.length / numPerRow);
  for (let i = 0; i &amp;lt; content.length; i++) {
    const char = content[i];
    const col = i % numPerRow;
    const row = Math.floor(i / numPerRow);
    const x = col * charWidth + charWidth / 2;
    const y = row * charHeight + charHeight / 2;
    ctx.fillText(char, x, y);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To tackle the &lt;strong&gt;third flaw&lt;/strong&gt; , I reduced the opacity of the canvas area. But a major issue arose from it, the opacity of the tracing pen also reduced, and again both the opacity being the same I was unable to see and differentiate between writing and printed letters.&lt;br&gt;
So from there emerged the idea of having two canvases (one over the other) rather than one.&lt;/p&gt;

&lt;p&gt;The first canvas will have the printing stuff (letters, numbers etc) with low opacity and the second canvas will be placed exactly over the first one having opacity as 1( i.e the written stuff would be fully visible):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="canvas-space"&amp;gt;
      &amp;lt;canvas id="drawing-area" class="drawing-area" height="500" width="950"&amp;gt;&amp;lt;/canvas&amp;gt;
      &amp;lt;canvas id="overlay-canvas" class="drawing-area" height="500" width="950"&amp;gt;&amp;lt;/canvas&amp;gt;
  &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To tackle the &lt;strong&gt;Forth flaw ** of font-family, I googled what are the most commonly used freehand writing fonts and got "Classic Notes.ttf", "Classic Notes.ttf" and "Classic Notes.ttf". I downloaded all these files (can view the code and all the files in my **&lt;em&gt;&lt;a href="https://github.com/himani-mehra/cursive-writing"&gt;Github&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;). Found Classic Notes.ttf to be the most suitable for free and loose strokes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.dropdown-container {
    height: 50px;
    width: 150px;
    border-radius: 10px;
    background-color: #517dd4;
    color: white;
    font-size: 20px;
    font-family:"classic notes";
}
  @font-face {
    font-family:"Life-Lessons";
    src: url("Life-Lessons.ttf") format("truetype");
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To tackle the &lt;strong&gt;fifth flaw&lt;/strong&gt;, it was easy to identify the basic tools required for a canvas as we have been using various graphics editors like MS Paint since the early stages of our school. I came to the conclusion to have 3 options:-&lt;/p&gt;

&lt;p&gt;1.) Clear all-  To clear the canvas and give a fresh writing area &lt;br&gt;
                to the user.&lt;br&gt;
2.) Eye icon- To hide/show the printed stuff(letters, numbers, &lt;br&gt;
              etc) allowing users to see and compare their &lt;br&gt;
              handwriting with the printed ones.&lt;br&gt;
3.) Color Gradient- As there is an image upload option, the user &lt;br&gt;
                    may use  different colors to sketch out the &lt;br&gt;
                    uploaded image.&lt;/p&gt;

&lt;p&gt;So these three items were kept in a widget design and after coding it , during the testing process found out that everytime for clearing or using any of the three icon I have to move my hand to a significant distance towards right in the pen tablet. Hence I decided the make the widget draggable/ movable throughout the screen for easy access and better user experience:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div id="draggable-container"&amp;gt;
            &amp;lt;div class="options-container"&amp;gt;
                &amp;lt;button id="clear-button" class="clear-button" type="button"&amp;gt; &amp;lt;img class="eraser" src="./images/eraser.png" /&amp;gt;
                &amp;lt;/button&amp;gt;
                &amp;lt;button id="hide-canvas" class="hide-canvas" type="button"&amp;gt; &amp;lt;img class="eraser" src="./images/hide.png" /&amp;gt;
                &amp;lt;/button&amp;gt;
                &amp;lt;button id="color-button" class="color-button" type="button"&amp;gt; &amp;lt;img class="paint" src="./images/color.png" /&amp;gt;
                    &amp;lt;input type="color" id="colorPicker" style="display: none;"&amp;gt;&amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#draggable-container {
    user-select: none;
    cursor: pointer;
    touch-action: none;
    position: absolute;
    top: 17%;
    left: 84%;
    transform: translate(0, 0);
    user-select: none;
    cursor: pointer;
    touch-action: none;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Images showing the feature for eye icon working:&lt;/p&gt;

&lt;p&gt;traced some alphabets:-&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R4i3pX-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyimf4pskg4exl3fw6f7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R4i3pX-U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyimf4pskg4exl3fw6f7.png" alt="Image description" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;used the eye icon (hide/show) feature to compare:-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O9Bm4InR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zwazme8l3kcxajqibnw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O9Bm4InR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zwazme8l3kcxajqibnw.png" alt="Image description" width="800" height="185"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var isDragging = false;
var offset = { x: 0, y: 0 };
var draggableContainer = document.getElementById("draggable-container");
draggableContainer.addEventListener("mousedown", (e) =&amp;gt; {
  isDragging = true;
  offset.x = e.clientX - draggableContainer.getBoundingClientRect().left;
  offset.y = e.clientY - draggableContainer.getBoundingClientRect().top;
});
draggableContainer.addEventListener("mousemove", (e) =&amp;gt; {
  if (isDragging) {
    draggableContainer.style.left = e.clientX - offset.x + "px";
    draggableContainer.style.top = e.clientY - offset.y + "px";
  }
});
document.addEventListener("mouseup", () =&amp;gt; {
  isDragging = false;
});
draggableContainer.addEventListener("touchstart", (e) =&amp;gt; {
  isDragging = true;
  offset.x = e.touches[0].clientX - draggableContainer.getBoundingClientRect().left;
  offset.y = e.touches[0].clientY - draggableContainer.getBoundingClientRect().top;
});
draggableContainer.addEventListener("touchmove", (e) =&amp;gt; {
  if (isDragging) {
    e.preventDefault();
    draggableContainer.style.left = e.touches[0].clientX - offset.x + "px";
    draggableContainer.style.top = e.touches[0].clientY - offset.y + "px";
  }
});
document.addEventListener("touchend", () =&amp;gt; {
  isDragging = false;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above JS code, notice "isDragging" is set to false by default and then added event listeners to make to movable throughout the screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  After this much, I was happy to finish the project, but soon some questions popped up in my mind:
&lt;/h2&gt;

&lt;p&gt;1.) What is the user wants to try one alphabet multiple times, &lt;br&gt;
    because its not possible to get a grip of anything in one &lt;br&gt;
    shot.&lt;br&gt;
2.) I forgot to cover cursive writing templates for &lt;br&gt;
    "kindergartners" or "preschoolers."&lt;/p&gt;

&lt;p&gt;Now this was a tricky situation, honestly I started feeling overwhelmed 😓.&lt;br&gt;
Because again there were multiple tasks to be done like for individual aphabets , canvas only displaying 'A' let say 20 times, then 'B' till 'Z'. Then canvas only displaying 'a' let say 20 times, then 'b' till 'z'. Then canvas only displaying '0' let say 20 times, then '1' till '9' and so on for special characters. So I need to have 26 cards (uppercase alphabets) + 26 cards (lowercase alphabets) + 10 cards(numbers) + 20 cards(special characters : "! @ # $ % ^ &amp;amp; * ( ) { } [ ] : ; ? / &amp;lt; &amp;gt; ") and how can I forget the cursive writing template.&lt;/p&gt;

&lt;p&gt;After sometime I took a breath and said lets breakdown the problem and pick the alphabets part, lets achive it first and applied a for loop to form a grid of 26 upper case alphabets:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NGs0jL9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h01ig5nq3cs3dh186lua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NGs0jL9X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h01ig5nq3cs3dh186lua.png" alt="Image description" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JS code:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for (let asciiCode = 65; asciiCode &amp;lt;= 90; asciiCode++)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTML:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="image-grid" id="image-grid-1"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.image-grid {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-around;
      }

      .card {
        flex: 0 0 calc(12.5% - 10px);
        margin: 7px;
        box-sizing: border-box;
        width: 95px;
        height: 120px;
        word-break: break-all;
      }

      .card img {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, during this process, I figured out the UX for displaying all the cards and that was to have &lt;strong&gt;another grid&lt;/strong&gt; and yes that was the landing page of my project (which initially I talked about that was developed at last😅).&lt;/p&gt;

&lt;p&gt;So now the flow is: on landing page of the &lt;strong&gt;&lt;em&gt;&lt;a href="https://cursive.paletto.org/"&gt;project&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;, user will see a grid like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vk8wzmrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tk799beckvdl61fq0032.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vk8wzmrE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tk799beckvdl61fq0032.png" alt="Image description" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then on-click on any card, we will get the second grid (will show some):&lt;/p&gt;

&lt;p&gt;uppercase grid:-&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dIOcp0I3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bg353qf03cc70bizkl2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dIOcp0I3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bg353qf03cc70bizkl2.png" alt="Image description" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;special characters grid:-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p1BbXnFx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emgm5j70e2z5eii5cq7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p1BbXnFx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/emgm5j70e2z5eii5cq7y.png" alt="Image description" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;cursive writing template grid:-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--in2YIR9z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsscew7gh7t37wd6rpsm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--in2YIR9z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsscew7gh7t37wd6rpsm.png" alt="Image description" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now on click on any card say from second card (lowercase) of the landing page , you selected letter 'b' to practice. So in the canvas it will be displayed like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sa20FxdS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edtktwklsio64wka5mtg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sa20FxdS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edtktwklsio64wka5mtg.png" alt="Image description" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTML:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="card-grid"&amp;gt;
        &amp;lt;div class="card" data-option="uppercase" id="uppercase-card"&amp;gt;ABC&amp;lt;/div&amp;gt;
        &amp;lt;div class="card" data-option="lowercase" id="lowercase-card"&amp;gt;abc&amp;lt;/div&amp;gt;
        &amp;lt;div class="card" data-option="numbers" id="numbers-card"&amp;gt;123&amp;lt;/div&amp;gt;
        &amp;lt;div class="card" data-option="special" id="special-card"&amp;gt;$*/&amp;lt;/div&amp;gt;
        &amp;lt;div class="card" data-option="upload"&amp;gt;Upload&amp;lt;/div&amp;gt;
        &amp;lt;div class="card gap-class" data-option="image" id="image-card-1"&amp;gt; Cursive Writing&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="image-grid" id="image-grid-1"&amp;gt;&amp;lt;/div&amp;gt;

    &amp;lt;div class="second-card-grid" onclick="showSubHeading()"&amp;gt;

    &amp;lt;/div&amp;gt;
    &amp;lt;div class="sub-headings" id="subheadingEl"&amp;gt;
        &amp;lt;span class="uppercase_second_card common" onclick="redirectToUppercaseCards()"&amp;gt;A-Z&amp;lt;/span&amp;gt;
        &amp;lt;span class="lowercase_second_card common" onclick="redirectToLowercaseCards()"&amp;gt;a-z&amp;lt;/span&amp;gt;
        &amp;lt;span class="numbers_second_card common" onclick="redirectToSpecialcaseCards()"&amp;gt;0-9&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JS:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// JS code for uppercase , similarly others were achived
document.getElementById('uppercase-card').addEventListener('click', displayUppercaseCharacters);

function displayUppercaseCharacters() {
  const secondCardGrid = document.querySelector('.second-card-grid');
  const container = document.querySelector('#first-card-section');
  const cardGrid = document.querySelector('.card-grid');
  let canvas = document.getElementById('drawing-area');
  let ctx = canvas.getContext('2d');
  secondCardGrid.innerHTML = '';

  for (let asciiCode = 65; asciiCode &amp;lt;= 90; asciiCode++) {
    const char = String.fromCharCode(asciiCode);
    const card = document.createElement('div');
    card.classList.add('card');
    card.textContent = char;
    card.addEventListener('click', function () {
      container.classList.remove('hidden');
      cardGrid.style.display = 'none';
      secondCardGrid.style.display = 'none';
      const lettersPerRow = 7;
      const letterSize = 28;
      const canvasWidth = canvas.width;
      const canvasHeight = canvas.height;
      const columnSpacing = canvasWidth / lettersPerRow;
      const rowSpacing = canvasHeight / Math.ceil(26 / lettersPerRow);
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      for (let j = 0; j &amp;lt; 26; j++) {
        const row = Math.floor(j / lettersPerRow);
        const col = j % lettersPerRow;
        const x = col * columnSpacing + (columnSpacing - letterSize) / 2;
        const y = row * rowSpacing + (rowSpacing - letterSize) / 2;
        ctx.font = `40px "classic notes", cursive`;
        ctx.fillText(char, x, y);
      }
    });
    secondCardGrid.appendChild(card);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly for all items (Refer my &lt;strong&gt;&lt;em&gt;&lt;a href="https://github.com/himani-mehra/cursive-writing"&gt;Github &lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;to see the logic). And that's how I achieved a comprehensive and detailed flow. Most importantly, now it was organized. Now one more thing, say a user selects wrong card my mistake and want to choose another one so to achieve this functionality I kept some options on the top of the canvas :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DeQft35T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3xdbx8z857odn0cll6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DeQft35T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y3xdbx8z857odn0cll6v.png" alt="Image description" width="800" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTML:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="sub-headings" id="subheadingEl"&amp;gt;
        &amp;lt;span class="uppercase_second_card common" onclick="redirectToUppercaseCards()"&amp;gt;A-Z&amp;lt;/span&amp;gt;
        &amp;lt;span class="lowercase_second_card common" onclick="redirectToLowercaseCards()"&amp;gt;a-z&amp;lt;/span&amp;gt;
        &amp;lt;span class="numbers_second_card common" onclick="redirectToSpecialcaseCards()"&amp;gt;0-9&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JS:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function redirectToUppercaseCards() {
  const container = document.querySelector('#first-card-section');
  container.style.display = 'none';
  const secondCardGrid = document.querySelector('.second-card-grid');
  secondCardGrid.style.display = 'block'
}

function redirectToLowercaseCards() {
  const container = document.querySelector('#first-card-section');
  container.style.display = 'none';
  const secondCardGrid = document.querySelector('.second-card-grid');
  secondCardGrid.style.display = 'block'
}

function redirectToSpecialcaseCards() {
  const container = document.querySelector('#first-card-section');
  container.style.display = 'none';
  const secondCardGrid = document.querySelector('.second-card-grid');
  secondCardGrid.style.display = 'block'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To see the github process of pushing the code, coding practices such as constantly pushing the code refer my article on &lt;strong&gt;&lt;em&gt;&lt;a href="https://medium.com/p/2e808ecefb84/edit"&gt;Paletto &lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;and to learn domain hosting (host the project live) refer the article on &lt;strong&gt;&lt;em&gt;&lt;a href="https://medium.com/p/76cc8813b673/edit"&gt;Domain Hosting&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some learnings:
&lt;/h2&gt;

&lt;p&gt;Initially when the project was started, I was not aware of the fact that it can expand to this extent, hence made it in simple JS, HTML,CSS.&lt;br&gt;
Later when it expanded , realized that it would have been easier if a framework is used like Vue.js, react etc as it has a concept of different components. So the three pages (first grid , second grid , canvas area) were three different components (say three different vue files) , and on back button we need to just hide/show the components.&lt;/p&gt;

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

&lt;p&gt;:&lt;br&gt;
Concluding this journey, an idea originated from the inability to write and affinity to improve, finding a tool for it , and when not getting a complete package to practice, developed one not only for myself but for a larger user base. There were some hiccups, and obstcales during the project development, some later realization to use generic code and frameworks, but its fine these learning will be helpful in making the next project easier to develope, organised, and successful.&lt;/p&gt;

&lt;p&gt;I have improved my writing a lot and have started making online notes.What about you?😄&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hue8RWv3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6cnbso1t4eg4nd1i72t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hue8RWv3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6cnbso1t4eg4nd1i72t.png" alt="Image description" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building Beyond the Web: Crafting Chrome Extension 'Screenshot Pro'</title>
      <dc:creator>Himani Mehra</dc:creator>
      <pubDate>Wed, 22 Nov 2023 07:11:49 +0000</pubDate>
      <link>https://forem.com/himanimehra/building-beyond-the-web-crafting-chrome-extension-screenshot-pro-59dc</link>
      <guid>https://forem.com/himanimehra/building-beyond-the-web-crafting-chrome-extension-screenshot-pro-59dc</guid>
      <description>&lt;p&gt;After making some major projects (&lt;strong&gt;&lt;a href="https://www.paletto.org/"&gt;&lt;em&gt;Paletto&lt;/em&gt;&lt;/a&gt;&lt;/strong&gt; , &lt;strong&gt;&lt;em&gt;&lt;a href="https://cursive.paletto.org/"&gt;Practice-digital-handwriting&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;, etc), hosted live on my &lt;em&gt;&lt;strong&gt;&lt;a href="https://himanimehra.paletto.org/"&gt;website&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;. whose main purpose of these projects was to encourage as many people as possible to use it and derive maximum benefits from it. What could be a more effective means to reach the public than a Chrome extension ?&lt;/p&gt;

&lt;p&gt;We all use Chrome extensions for various purposes, I personally use many of them to ease out my work. The idea for full page screenshot popped up due to the fact that during my previous project development, for UI/UX review, I was constantly referring some friends (coders and non-coders)to give feedback, so that I have a holistic approach of user perspective. For that, we constantly share the screenshots and at times need to send screenshots of a single page in two parts(upper and bottom section) which at some point started creating inconvenience (hundreds of such screenshots have been shared so far). So from there aroused the idea of having my own Chrome extension that takes full page screenshots 😇 and I translated my ideas into a coding language and created an extension: &lt;strong&gt;&lt;em&gt;&lt;a href="https://chromewebstore.google.com/detail/screenshot-pro-full-page/kkkmllcaoomjhohpmbjdffenjkidginf"&gt;Screenshot Pro&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fxmRQXzy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8c24dw6o5ple89sy2qjh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fxmRQXzy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8c24dw6o5ple89sy2qjh.png" alt="Image description" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But before &lt;em&gt;&lt;strong&gt;&lt;a href="https://chromewebstore.google.com/detail/screenshot-pro-full-page/kkkmllcaoomjhohpmbjdffenjkidginf"&gt;Screenshot Pro&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;, I need to have knowledge about :&lt;/p&gt;

&lt;p&gt;1.) How Chrome extension code is written, and what are the &lt;br&gt;
    practices we need to follow?&lt;br&gt;
2.) What is the difference between a normal project code and &lt;br&gt;
    Chrome extension code? Is there a certain protocol we need to &lt;br&gt;
    follow?&lt;br&gt;
3.) How to publish Chrome extension?&lt;br&gt;
4.) Okay if published, what is the featured tag, and how to apply &lt;br&gt;
    for feature tag?&lt;/p&gt;

&lt;p&gt;So started my journey of searching going through different sites , best would be to go through google documentation, going through the comment sections of the competitors and what the users were unsatisfied with. I came to the following conclusion:&lt;/p&gt;

&lt;p&gt;1.) &lt;strong&gt;&lt;em&gt;Less is more&lt;/em&gt;&lt;/strong&gt;: I searched for competitors and while going through the comment section one thing common was too complicated. Exactly for a full page screenshot why to give too many functionality? So my extension simply captures the screenshot till the end of the page and downloads .png file as: screenshot.png.&lt;/p&gt;

&lt;p&gt;2.) The project for the Chrome extension needs to have the &lt;br&gt;
   following files:-&lt;br&gt;
   1.) &lt;strong&gt;&lt;em&gt;manifest.json&lt;/em&gt;&lt;/strong&gt;:The manifest.json file is essential for &lt;br&gt;
       Chrome extensions as it contains crucial configuration &lt;br&gt;
       details, such as extension metadata, permissions, scripts, &lt;br&gt;
       icons, and more. It provides the necessary information for &lt;br&gt;
       the proper integration and functioning of the extension &lt;br&gt;
       within the Chrome browser.&lt;br&gt;
   2.) &lt;strong&gt;&lt;em&gt;background.js&lt;/em&gt;&lt;/strong&gt;: This file is a script used in Chrome &lt;br&gt;
       extensions to run tasks in the background, separate from &lt;br&gt;
       the user interface. It is specified in the manifest.json &lt;br&gt;
       file and is crucial for handling background processes, &lt;br&gt;
       event listeners, and maintaining extension state.&lt;br&gt;
   3.) &lt;em&gt;&lt;strong&gt;content.js&lt;/strong&gt;&lt;/em&gt;: This file is used to inject scripts into web &lt;br&gt;
       pages. It is specified in the manifest.json file and serves &lt;br&gt;
       as a content script, allowing the extension to interact &lt;br&gt;
       with and modify the content of web pages. This file is &lt;br&gt;
       essential for implementing features that require &lt;br&gt;
       manipulation or enhancement of the webpage's DOM (Document &lt;br&gt;
       Object Model) and enables seamless integration of the &lt;br&gt;
       extension's functionality with the content of visited web &lt;br&gt;
       pages.&lt;br&gt;
   4.) &lt;em&gt;&lt;strong&gt;popup.js and popup.html&lt;/strong&gt;&lt;/em&gt; : In a Chrome extension, &lt;br&gt;
       popup.js and popup.html typically work together to create &lt;br&gt;
       the popup interface that appears when a user clicks on the &lt;br&gt;
       extension icon in the browser's toolbar.&lt;br&gt;
  5.) &lt;em&gt;&lt;strong&gt;Other JS files&lt;/strong&gt;&lt;/em&gt; : This is very important to note that &lt;br&gt;
     if we require any external js file , we cannot simply embed &lt;br&gt;
     it putting script . But the whole file needs to be &lt;br&gt;
     included (download the file in the project section) in the &lt;br&gt;
     project. It is one of the major differences between v2 and v3 &lt;br&gt;
     update of chrome extension (&lt;em&gt;&lt;strong&gt;&lt;a href="https://developer.chrome.com/docs/extensions/migrating/"&gt;Read about it&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;So let's dive deep down into the technical details:-&lt;br&gt;
manifest.json file:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "Screenshot Pro : Full page screenshot",
  "description": "Complete Page Screenshot",
  "version": "2.0.0",
  "manifest_version": 3,
  "icons": {
    "16": "images/icon16.png",
    "48": "images/icon48.png",
    "128": "images/icon128.png"
  },
  "action": {
    "default_popup": "popup.html",
    "default_title": "SnapScreen",
    "default_icon": {
      "16": "images/icon48.png",
      "48": "images/icon16.png",
      "128": "images/icon128.png"
    }
  },
  "background": {
    "service_worker": "background.js"
  },
  "permissions": [
    "scripting"
  ],
  "host_permissions": [
    "https://*/*",
    "http://*/*"
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-name: "Screenshot Pro : Full page screenshot"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;description: "Complete Page Screenshot"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;version: "2.0.0" (initially it was 1.0.0)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;manifest_version: 3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;icons: Icon images for different sizes (16x16, 48x48, 128x128 pixels).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;action: Defines the default popup, title, and icon for the extension's browser action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;default_popup: "popup.html" - the HTML file for the extension popup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;default_title: "SnapScreen" - default title for the extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;default_icon: Icon images for different sizes used in the browser action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;background: Specifies the service worker script "background.js" for background tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;permissions: Requests permission for the "scripting" API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;host_permissions: Specifies permissions for accessing content on "https://" and "http://" URLs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: The three images with sizes 16x16, 48x48, and 128x128 pixels are specified in the default_icon property of the manifest.json file to provide icons for different contexts within the Chrome browser, such as the toolbar, extension management page, and the Chrome Web Store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chrome.runtime.onMessage.addListener((message, sender, sendResponse) =&amp;gt; {
  if (message.action === 'captureScreenshot') {
      chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
          let activeTab = tabs[0];
          chrome.scripting.executeScript({
              target: { tabId: activeTab.id },
              files: ['html2canvas.js']
          }, () =&amp;gt; {
              chrome.scripting.executeScript({
                  target: { tabId: activeTab.id },
                  files: ['content.js']
              });
          });
      });
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above code sets up a listener in a Chrome extension. When a message with the action 'captureScreenshot' is received, it queries the active tab, injects two scripts ('html2canvas.js' and 'content.js') into the tab, triggering a process, possibly related to capturing a screenshot. Similary you can go through other files such as popup.js and popup.html in my Github, it contains the readme.md file as well for detailed information. Have explained the major and important files above.&lt;/p&gt;

&lt;p&gt;Once the extension is developed and tested, next milestone is to sucessfully publish it. I followed the below steps and the we will talk about the mistakes I made and learnings:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step I&lt;/strong&gt;: Go to Publish in the Chrome Web Store from &lt;a href="https://developer.chrome.com/docs/webstore/publish/"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;strong&gt;Step II:&lt;/strong&gt; Follow the step very clearly defined there:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E11Ke8P8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0o7bp7qnq8impnbvh9ru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E11Ke8P8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0o7bp7qnq8impnbvh9ru.png" alt="Image description" width="800" height="344"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Step III&lt;/strong&gt;: Use this image resizer: &lt;em&gt;&lt;a href="https://imageresizer.com/"&gt;ImageResizer&lt;/a&gt;&lt;/em&gt;, very useful while resizing&lt;br&gt;
 the promo icons, marquee promo title, screenshots etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---ZiRyyQ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6igry5azq4pn4s3d8umc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---ZiRyyQ9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6igry5azq4pn4s3d8umc.png" alt="Image description" width="800" height="532"&gt;&lt;/a&gt;&lt;br&gt;
Once everything is done and zip file is uploaded and you click on "Publish", there will a popup saying "&lt;em&gt;It might take some time to review the code and publish, you will be notified&lt;/em&gt;". After three days or so I got a mail that my request has been rejected and when I got into details, it was because I asked for extra permissions from google:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"permissions": [
    "scripting",
    "storage",
    "activeTab"
  ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where as only first one was needed😅. I removed extra permissions and published again and after few days got a mail: Congrats! your extension has successfully been published:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AR1RqxfQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2lcju2yg90wzmy61q1zn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AR1RqxfQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2lcju2yg90wzmy61q1zn.png" alt="Image description" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistakes and learnings:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extension name were not appealing&lt;/strong&gt; : Initially named as 'Snapscreen ', extension was published but still there was something missing that is the on searching my extension it was not coming anywhere on top (ofcourse it was newly published having 0 users or ratings). But still detaching myself from the developer mindset having fancy names, thought from the perspective of the normal user. For eg. if anyone wants to capture a screenshot, what he or she will search of course the term "screenshot" needs to be there in the name. Hence I changed the name to Screenshot Pro.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Icons &amp;amp; screenshots were unattractive and lacked aesthetic appeal:&lt;/strong&gt; My images either for icons or screenshots were not relatable to the topic and had pixelation issues, causing a lack of clarity and visible breaks. Hence, instead of just uploading my icons and images, I created them using HTML and CSS and then uploaded them. After the updates were done in naming and images, I applied again for version: 2.0.0 and got successfully published within a day.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Featured badge:&lt;/strong&gt; Apply for the feature badge ASAP, becasue firstly once you apply it takes a lot of time to get the badge and secondly it is important as it makes your extension more authentic and free from any malware:-&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PqkJXoU5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sggs8u7vevrc9qrbwjv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PqkJXoU5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sggs8u7vevrc9qrbwjv5.png" alt="Image description" width="670" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sbJmCEzG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/foxlwtqft1r9pyjede30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sbJmCEzG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/foxlwtqft1r9pyjede30.png" alt="Image description" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Permissions &lt;/strong&gt;: Google reviewers are very strict about the permissions you seek for your extension, the very reason my application got rejected for the first time I applied.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While testing noticed that for some websites extension is capturing successfully and for some, it is not (very rare). Thought it would be a coding issue. I opened the console and in the network tab noticed &lt;em&gt;CORS error 302 permission denied&lt;/em&gt;. Then realized some website due to security purposes have taken up precautionary measures by denying the access.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Taking screenshot successfully (you can cross verify from this link and the image below):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DJLT22dY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tb1dsg0fabne0l1segfo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DJLT22dY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tb1dsg0fabne0l1segfo.png" alt="Image description" width="800" height="1488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the below image notice instead of images, blank white boxes are there, It is due to CORS (see the image and very by this link):-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HUVJ2S8_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft3zy59g500r0673bh9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HUVJ2S8_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ft3zy59g500r0673bh9h.png" alt="Image description" width="259" height="1500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;I embarked on creating the "Screenshot Pro" Chrome extension to simplify full-page screenshots. My journey involved understanding Chrome extension coding, prioritizing simplicity, and learning from mistakes. I realized the importance of appealing names, attractive icons, and clear images, whole JS files need to be included in V3 version . Key files like manifest.json, background.js, and content.js played crucial roles. Applying for the featured badge enhanced authenticity. Despite challenges like permission rejections, the process taught valuable lessons. It's not only the coding you learn but the whole process of what was done (code and images without review) , what could have been avoided (extra permissions), and what more needs to be done(naming and creating images using HTML,CSS, applying for feature badge).&lt;/p&gt;

&lt;p&gt;You can access the code from my &lt;strong&gt;&lt;em&gt;&lt;a href="https://github.com/himani-mehra/SnapscreenPro"&gt;Github&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;. Try using &lt;strong&gt;&lt;em&gt;&lt;a href="https://chromewebstore.google.com/detail/screenshot-pro-full-page/kkkmllcaoomjhohpmbjdffenjkidginf"&gt;Screenshot Pro&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;😀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>chromeextension</category>
    </item>
    <item>
      <title>Paletto: Turning Job Search Frustrations into a Colorful Success</title>
      <dc:creator>Himani Mehra</dc:creator>
      <pubDate>Wed, 22 Nov 2023 07:10:03 +0000</pubDate>
      <link>https://forem.com/himanimehra/learning-the-hard-way-job-rejections-projects-and-paletto-34m6</link>
      <guid>https://forem.com/himanimehra/learning-the-hard-way-job-rejections-projects-and-paletto-34m6</guid>
      <description>&lt;p&gt;During my resume-building process for the job hunt, I created five projects:-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/Product-Detail-Page/"&gt;Product-detail-page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/interactive-comment-section/"&gt;Interactive-comment-section&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/Multi-step-form/"&gt;Multi-step-form&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/ip-address-tracker/"&gt;IP-address-tracker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/explore-country/"&gt;Country-explorer&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But a common mistake that I made while working on all these projects was to just go to YouTube and Google and take references (typical college mindset). I was in a hurry to add as many projects as possible (to compensate for my low industry work experience, about 1.5 years). Soon I realized that my resume was not shortlisted by any company. Frustrated by receiving rejection emails daily, stating, "&lt;em&gt;Unfortunately, we are proceeding ahead with other candidates&lt;/em&gt;" I googled and discovered that it's not the quantity but the quality that matters. Projects may not necessarily be top-notch and something no one has ever made. When there are nearly 27 million developers worldwide it's not possible. But the right mindset would be: Not to copy/paste, but rather pick an idea from scratch, work upon it, and develop a different spectrum of that idea. Search for the competitors. Go to the comments section(if there is any )and filter out the points people are unsatisfied with. Then start a project around that idea. Also having projects that are accessible to others on a live website, allows users to interact with them.&lt;/p&gt;

&lt;p&gt;One such project developed is &lt;a href="https://www.paletto.org/"&gt;Paletto&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Desktop view&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xKLEYKYz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxmxtlli64wf0a7g5pdb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xKLEYKYz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxmxtlli64wf0a7g5pdb.png" alt="Image description" width="800" height="476"&gt;&lt;/a&gt;        &lt;/p&gt;

&lt;p&gt;&lt;em&gt;mobile view&lt;/em&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t6NxAp-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4la29bgn79f1jqlxci56.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t6NxAp-H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4la29bgn79f1jqlxci56.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;               &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I built the project based on my idea, making adjustments along the way by removing, changing, and adding elements as needed during the ongoing development?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Initially, there was a static image, and I was working on fetching the colors correctly but soon I realized that this project will be hosted soon and open for the users to play and interact with it. So from these images, the idea of upload for Desktop and upload and camera for Mobile mode:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="file" id="user-image-input" accept="image/jpeg, image/png"&amp;gt;
&amp;lt;img class="upload-icon" id="upload-user-image" src="./images/cloud-upload.png"&amp;gt;
      &amp;lt;div class="left-header" id="header"&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div id="uploaded-image-container" class="image-container"&amp;gt;
        &amp;lt;img id="user-image" class="styled-image"&amp;gt;
        &amp;lt;button id="do-user-image" class="do-it-button" style="display: none;"&amp;gt;See color palette&amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now again a conflict was there: If an image has many colors where to keep the upload button so as to avoid the user's effort of scrolling again and again to the top for multiple uploads? Hence the solution was to separate out upload section and canvas display section. I divided them into left-column and right-column:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="container"&amp;gt;
    &amp;lt;div class="left-column"&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class="right-column"&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving on, the idea was to keep this color palette as the color card we use for painting out homes as it will be easy for developers as well as the common public to relate (Hence, I avoided using deep technical UX/UI that would be difficult for the user).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Secondly how and what information to display along with color?&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Initially, only the color was displayed (without the bottom part showing color codes), and the hex code appeared on hover, which could be copied by clicking on the color card. Then, I realized that users might need the RGB code or HSL code. I attempted to include all three codes on the color card, but it made the design look cluttered. The only solution was to separate the codes from the color. For UI/UX inspiration, I searched on Dribbble (a nice website for web design) and referred to examples. Afterward, I used Figma to ensure precision in color height, width, font adjustments, and other design elements.&lt;/p&gt;

&lt;p&gt;Finally added the color codes at the bottom of the respective color. Now my &lt;em&gt;color card = color + color codes&lt;/em&gt;. So the flow is to copy any color the user need to click on the code, that is it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function outputColors(colors) {
    var output = document.getElementById('output');
    var colors_list = document.createElement('ul');
    colors_list.id = 'colors';
    for (var c in colors) {
        var color = colors[c];
        var colorBox = document.createElement('li');
        var upperColorBox = document.createElement('div');
        upperColorBox.className = 'color-box';
        upperColorBox.style.backgroundColor = color;
        upperColorBox.dataset.hexCode = color;
        var hexCode = document.createElement('div');
        hexCode.className = 'hex-code';
        hexCode.textContent = color;
        hexCode.addEventListener('click', function () {
            var code = this.textContent;
            copyToClipboard(code);
            var codeBox = this;
            codeBox.textContent = 'Copied!';
            setTimeout(function () {
                codeBox.textContent = code;
            }, 1000);
        });
        var rgbCode = document.createElement('div');
        rgbCode.className = 'code';
        rgbCode.textContent = getRGBCode(color);
        rgbCode.addEventListener('click', function () {
            var code = this.textContent;
            copyToClipboard(code);
            var codeBox = this;
            codeBox.textContent = 'Copied!';
            setTimeout(function () {
                codeBox.textContent = code;
            }, 1000);
        });
        var hslCode = document.createElement('div');
        hslCode.className = 'code';
        hslCode.textContent = getHSLCode(color);
        hslCode.addEventListener('click', function () {
            var code = this.textContent;
            copyToClipboard(code);
            var codeBox = this;
            codeBox.textContent = 'Copied!';
            setTimeout(function () {
                codeBox.textContent = code;
            }, 1000);
        });
        var hexCode = document.createElement('div');
        hexCode.className = 'code';
        hexCode.textContent = color;
        hexCode.addEventListener('click', function () {
            var code = this.textContent;
            copyToClipboard(code);
            var codeBox = this;
            codeBox.textContent = 'Copied!';
            setTimeout(function () {
                codeBox.textContent = code;
            }, 1000);
        });
        colorBox.appendChild(upperColorBox);
        colorBox.appendChild(hexCode);
        colorBox.appendChild(rgbCode);
        colorBox.appendChild(hslCode);
        colors_list.appendChild(colorBox);
    }
    output.innerHTML = "&amp;lt;h2 style='text-align: center;'&amp;gt;&amp;lt;/h2&amp;gt;";
    output.appendChild(colors_list);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Second color's RGB code is copied on-click:-&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3QAgN2x---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bn4z71dwlfuacnvtrhca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3QAgN2x---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bn4z71dwlfuacnvtrhca.png" alt="Image description" width="467" height="211"&gt;&lt;/a&gt;&lt;br&gt;
Coming back to the left section again.&lt;br&gt;
Users will not only upload the image and copy codes. There was something missing. Yes, and that was proving them with some other functionality. How I started thinking about what all users can do with this color palette??&lt;/p&gt;

&lt;p&gt;1.) Users may need more shades of a particular color. &lt;br&gt;
   For instance, if a user wants a shade similar to a specific red &lt;br&gt;
   color or has a photo with a beautiful red shade but wants &lt;br&gt;
   something slightly lighter or darker, I incorporated Google and &lt;br&gt;
   Cooler palettes. Users can simply visit the provided links, &lt;br&gt;
   click on the shade they desire, and easily implement it. &lt;br&gt;
   (&lt;em&gt;&lt;strong&gt;Google Palette&lt;/strong&gt;&lt;/em&gt;🔗&lt;em&gt;&lt;strong&gt;Coolors Palette&lt;/strong&gt;&lt;/em&gt;🔗)&lt;/p&gt;

&lt;p&gt;2.) Users may need to click on the screenshot of the color palette &lt;br&gt;
   from the specific photo or the image they have uploaded. ( &lt;br&gt;
   &lt;em&gt;*&lt;em&gt;Screenshot⭳ *&lt;/em&gt;&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;3.) Users may want to download the color palette for future &lt;br&gt;
    reference, not just the screenshot including the image but &lt;br&gt;
    specifically the color palette. ( &lt;em&gt;&lt;strong&gt;SVG⭳&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;ASE⭳&lt;/strong&gt;&lt;/em&gt; ).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BBLPtP1I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfp4znrnnx22u84vilg2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BBLPtP1I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfp4znrnnx22u84vilg2.png" alt="Image description" width="469" height="101"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="button-container"&amp;gt;
        &amp;lt;span class="clickable-text" id="download-button"&amp;gt;SVG⭳&amp;lt;/span&amp;gt;
        &amp;lt;span class="clickable-text" id="download-ase-button"&amp;gt;ASE⭳&amp;lt;/span&amp;gt;
        &amp;lt;span class="clickable-text" id="take-screenshot"&amp;gt;Screenshot⭳&amp;lt;/span&amp;gt;
        &amp;lt;span class="clickable-text" id="google-palette-button"&amp;gt;Google Palette🔗&amp;lt;/span&amp;gt;
        &amp;lt;span class="clickable-text" id="generate-coolors-button"&amp;gt;Coolors Palette🔗&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now during the ongoing project development, I recognized the significance of incorporating sample images. This proves especially useful for users who may not have an image readily available or prefer to quickly assess the website's functionality without uploading their own. To facilitate this, I included four sample images:-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E1x3vvtS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wq83xi28pmi5rypbe5co.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E1x3vvtS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wq83xi28pmi5rypbe5co.png" alt="Image description" width="428" height="106"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="last-sec"&amp;gt;
        &amp;lt;div class="second-sub"&amp;gt;
          &amp;lt;div class="need-sample"&amp;gt;No image?&amp;lt;/div&amp;gt;
          &amp;lt;div class="need-sample-2"&amp;gt;Try these :&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="sample-image" id="sample-image"&amp;gt;
          &amp;lt;img class="sample-img" id="imageId-1" src="./images/images.jpg"&amp;gt;
          &amp;lt;img class="sample-img" id="imageId-2" src="./images/samplee.webp"&amp;gt;
          &amp;lt;img class="sample-img" id="imageId-3" src="./images/download.jpg"&amp;gt;
          &amp;lt;img class="sample-img" id="imageId-4" src="./images/room.jpg"&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Js:-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const sampleImages = document.querySelectorAll('.sample-img');
const targetImage = document.getElementById('coke');

sampleImages.forEach(sampleImg =&amp;gt; {
    sampleImg.addEventListener('click', function () {
        targetImage.src = this.src;
        console.log(targetImage.src);
        const imageId = this.id;
        do_it(imageId);
    });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly was tracking, testing, and developing the mobile mode as well (mostly CSS and some JS functions).&lt;br&gt;
&lt;strong&gt;&lt;em&gt;Note&lt;/em&gt;&lt;/strong&gt;: Always remember to frequently push the code to GitHub (small but useful advice).&lt;/p&gt;

&lt;p&gt;After my project was ready, I followed these steps (You can also my blog on: "&lt;strong&gt;&lt;em&gt;&lt;a href="https://medium.com/p/76cc8813b673/edit"&gt;Domain hosting&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;" if you want to host this project live) :&lt;/p&gt;

&lt;p&gt;Step I: Push the code to &lt;a href="https://github.com/himani-mehra/"&gt;Github&lt;/a&gt;.&lt;br&gt;
Step II: Go to settings ➝ pages&lt;br&gt;
Step III: Select branch as "main" and click on save.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Select "main" branch&lt;/em&gt;:-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jOlci9YC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3o3yssmo906szw0eg0pc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jOlci9YC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3o3yssmo906szw0eg0pc.png" alt="Image description" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a minute or so, There will be a message on top stating: Your website is live at &lt;em&gt;dummywebsite.github.io&lt;/em&gt;. And the project is hosted, ready to use, and play.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;In building Paletto, I discovered that quality outweighs quantity. Initially, I replicated projects, but job rejections prompted me to seek uniqueness. So, I developed Paletto from scratch, considering users at every turn. I determined where to place buttons, drawing inspiration from home paint cards. Deciding which color codes to display took careful thought, and reviewing designs on Figma provided insights. Paletto isn't just about colors; it's a journey. Integrating useful features like downloads and sample images made it a practical, interactive tool. Taking it online was the finishing touch, transforming code into something accessible to everyone.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>frontend</category>
      <category>development</category>
    </item>
    <item>
      <title>How I did my first opensource contribution and so can you?</title>
      <dc:creator>Himani Mehra</dc:creator>
      <pubDate>Wed, 22 Nov 2023 07:02:17 +0000</pubDate>
      <link>https://forem.com/himanimehra/open-source-contribution-gitlab-31hn</link>
      <guid>https://forem.com/himanimehra/open-source-contribution-gitlab-31hn</guid>
      <description>&lt;p&gt;It was 3 months since I left my job as a frontend developer and during the process of job hunt, A new fear crept into my head : &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It's been a long time since I last had hands-on practice making changes in large company repositories, risking the loss of real industry experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2.Debugging code in a big repository with a substantial codebase and fixing it&lt;/p&gt;

&lt;p&gt;The best option for overcoming this fear was either to get a job ASAP 😝 or opensource contribution till you get one (a job).&lt;br&gt;
I started with the latter one. Went through many projects like Github, Apache, Gitlab, etc.&lt;/p&gt;

&lt;p&gt;I decided to contribute to Gitlab as, it has very nice and detailed documentation and articles about the process of open source contribution, how to set up GDK (Gitlab Development Kit)in local, even about the commit messages, MR procedure, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Areas where I faced issues:
&lt;/h2&gt;

&lt;p&gt;I use Windows, but the local setup (cloning the repository and running the service in local) has to be done in Linux. So installed Linux OS as well, and cloned the repo but didn't work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution 💡
&lt;/h2&gt;

&lt;p&gt;GitLab has its own vscode. Hence every time I work on any issue assigned to me, I proceed with the following steps:&lt;br&gt;
1.) login to Gitpod.&lt;br&gt;
2.) Go to Developing GitLab with GDK on Gitpod (here). From here &lt;br&gt;
    you'll get the username and password (you can change it &lt;br&gt;
    later).&lt;br&gt;
3.) Gitlab vscode will get open and in the terminal :&lt;/p&gt;

&lt;h2&gt;
  
  
  Some useful commands : 
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;gdk start (to start gitlab developement kit)&lt;/li&gt;
&lt;li&gt;gdk doctor (run this command if the service is not up even 
after gdk start )&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Then I used to get some suggestions like  :
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;bundle install (bundle file is a single, relocatable file that 
contains all the artifacts , needed to run your application)&lt;/li&gt;
&lt;li&gt;bundle fund&lt;/li&gt;
&lt;li&gt;Then we can access the service as &lt;a href="https://local.host/3000/"&gt;https://local.host/3000/&lt;/a&gt;
Note: UI will not immediately reflect , It will take some time 
from 30 sec to 2 minutes and page will automatically refresh 
after every 5 seconds:-&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z653emf3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cff3nl6xt5li0mky111w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z653emf3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cff3nl6xt5li0mky111w.png" alt="Image description" width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the local setup is done, I extensively focussed on searching, filtering, and grabbing the issues based on my tech stack.&lt;br&gt;
Some of the tickets and their merge requests (MR) successfully deployed to production:-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;VSA table: Change the default sort by to 'Duration time' : &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/427429"&gt;(Issue)&lt;/a&gt; 
&lt;a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135386"&gt;(MR)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;VSA table: Change the default sort by to 'Duration time' : &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/428200"&gt;(Issue)&lt;/a&gt; 
&lt;a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135694"&gt;(MR)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;VSA table: Change the default sort by to 'Duration time' : &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/384964"&gt;(Issue)&lt;/a&gt; 
&lt;a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136602"&gt;(MR)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;VSA table: Change the default sort by to 'Duration time' : &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/429984"&gt;(Issue)&lt;/a&gt; 
&lt;a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136625"&gt;(MR)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;VSA table: Change the default sort by to 'Duration time' : &lt;a href="https://gitlab.com/gitlab-org/gitlab/-/issues/423753"&gt;(Issue)&lt;/a&gt; 
&lt;a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135891"&gt;(MR)&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Some Learnings :
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Gained confidence in my skills by actively making code changes 
in the company's codebase.&lt;/li&gt;
&lt;li&gt;Experienced (SDE-2 / SDE-3) frontend developers as well as the 
UX folks were added as reviewers who used to review my code. Got 
to interact with them. All were very supportive and helpful, 
providing the implementation guidelines. And there used to be a 
thread of comments where we discussed till the assigned issue 
was crystal clear to me.&lt;/li&gt;
&lt;li&gt;Faced the main challenge was with writing the test cases:-&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4CSjqufZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3y9owdoxsqmf0dqqpul4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4CSjqufZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3y9owdoxsqmf0dqqpul4.png" alt="Image description" width="800" height="373"&gt;&lt;/a&gt;&lt;em&gt;Focus on the last pipeline failed: Test coverage was insufficient&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Need to be very specific and stick to commit message guidelines 
as it is one of the reasons for the pipeline to fail apart from 
test cases.&lt;/li&gt;
&lt;li&gt;Role of "&lt;strong&gt;&lt;em&gt;prettier&lt;/em&gt;&lt;/strong&gt;": Even if the code has no error (logical, 
syntactical or runtime). It will not allow to push the code. 
Reason being the formatting. Hence use &lt;em&gt;&lt;strong&gt;npx prettier - - write 
fileName&lt;/strong&gt;&lt;/em&gt;. It will do the required formatting in the respective 
file, the we can go ahead with the commit and push process.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The question lingered: Is it worth it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From setting up the service, reading articles, and navigating documents throughout the process, to handling my first ticket. Progressing not just in receiving the ticket, but also in debugging it in a large repository, identifying pages in the UI, solving the issue, and creating a Merge Request (MR) with recorded changes - comparing before and after. From writing test cases to ensuring a pipeline with all green ticks, to assigning a senior reviewer and interacting until the issue was crystal clear, leading to approval and merging of my MR into the master branch.&lt;br&gt;
Moving from having one MR merged within 24 hours to having multiple MRs merged and achieving the status of a level 2 contributor in Gitlab. I must say, "Yes, it is worth it."&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>frontend</category>
    </item>
    <item>
      <title>My Journey to Domain Hosting</title>
      <dc:creator>Himani Mehra</dc:creator>
      <pubDate>Wed, 22 Nov 2023 07:01:41 +0000</pubDate>
      <link>https://forem.com/himanimehra/my-journey-to-domain-hosting-3b6</link>
      <guid>https://forem.com/himanimehra/my-journey-to-domain-hosting-3b6</guid>
      <description>&lt;p&gt;During my resume-building process for the job hunt, I created five projects:-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/Product-Detail-Page/"&gt;Product-detail-page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/interactive-comment-section/"&gt;Interactive-comment-section&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/Multi-step-form/"&gt;Multi-step-form&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/ip-address-tracker/"&gt;IP-address-tracker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://himanimehra.paletto.org/explore-country/"&gt;Country-explorer&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Assuming that my resume was strong after completing numerous projects. However, A project doesn't necessarily have to be top-notch or something entirely novel, especially in a world where there are many developers in world. However, the right mindset would be: don't just copy and paste; instead, generate an idea from scratch, work on it, and develop various aspects of that idea. Look for competitors, explore the comments section (if available), and identify points that people are dissatisfied with. Then, initiate a project based on that refined idea.&lt;/p&gt;

&lt;p&gt;After creating my first major project ready to live (&lt;em&gt;&lt;a href="https://www.paletto.org/"&gt;Paletto&lt;/a&gt;&lt;/em&gt;), I bought a domain from GoDaddy:  paletto.org. Now we will go through the actual journey of hosting  my project and all the issues I faced, what alternatives I used:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step I&lt;/strong&gt;: Pushed my project on &lt;em&gt;&lt;strong&gt;&lt;a href="https://github.com/himani-mehra/color-palette"&gt;GitHub&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Step II: Go to &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.godaddy.com/en-in/offers/godaddy"&gt;GoDaddy&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;, and click on the manage DNS button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zkGdDegK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpgk8i8kyon6jsljlom8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zkGdDegK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpgk8i8kyon6jsljlom8.png" alt="Image description" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step III&lt;/strong&gt;: Then click on add new records:&lt;/p&gt;

&lt;p&gt;Add new records: IPv4 , www , etc:-&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t5ZZ6lBe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55ekzt1a00oml0kcfr3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t5ZZ6lBe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55ekzt1a00oml0kcfr3g.png" alt="Image description" width="800" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As I mentioned earlier, I believe in sharing both successes and challenges. Unfortunately, the approach mentioned earlier didn't work out for me. It wasn't due to a lack of knowledge, but every time I attempted to add a record, &lt;em&gt;I encountered either a connection timeout or a simple unable to add the record.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternative Used:
&lt;/h2&gt;

&lt;p&gt;Searched and found out we can add records via _&lt;a href="https://www.cloudflare.com/"&gt;Cloudflare &lt;/a&gt;_as well.&lt;/p&gt;

&lt;p&gt;Steps that were followed to successfully add records:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step I&lt;/strong&gt;: Login to  &lt;em&gt;&lt;a href="https://www.cloudflare.com/"&gt;Cloudflare &lt;/a&gt;_as well.&lt;br&gt;
&lt;strong&gt;Step II&lt;/strong&gt;: Click on _add a site&lt;/em&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a4zjF5WC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zh80qvp34azd0obshrxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a4zjF5WC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zh80qvp34azd0obshrxz.png" alt="Image description" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step III&lt;/strong&gt;: Enter the domain name (without any sub domain).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tA-DCKQu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x612blj8xj2cah7jot3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tA-DCKQu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x612blj8xj2cah7jot3v.png" alt="Image description" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step IV&lt;/strong&gt;: Select a plan, for most applications free plan is fine. Now Cloudflare will scan the domain name for existing DNS records. After a few seconds, it will show all the existing records for my current name server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EgfkO6FN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82d6o9iwnhow62wt1ocr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EgfkO6FN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82d6o9iwnhow62wt1ocr.png" alt="Image description" width="774" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: These (existing) records will not work for my website since it is located on a different hosting server, hence I deleted all. And even if any required record is deleted, it can be added at any time (Thats the whole point of Cloudflare).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step V&lt;/strong&gt;: We need to tell the registrar (GoDaddy in my case)to point to Cloudflare's nameserver, so copy first nameserver.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bjAEVf7t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/us0wrrqnq0tqwzlwuygg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bjAEVf7t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/us0wrrqnq0tqwzlwuygg.png" alt="Image description" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I went to my domain name registrar i.e GoDaddy , then to DNS settings , changed the first name server I copied from Cloudflare, similary done for the second nameserver. Yes that is it.&lt;/p&gt;

&lt;p&gt;Important thing to note is unless the website is properly installed and configured to work in https uncheck the automatic https settings:-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NxhAloAd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ulc49mpby19nehb2mi1v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NxhAloAd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ulc49mpby19nehb2mi1v.png" alt="Image description" width="751" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the last thing to note is, while adding the records, use '@' (shortcut for domain root) and if you want subdomain then add the subdomain name instead of '@' :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rNtvgIWO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf2o3voygx330b967tci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rNtvgIWO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf2o3voygx330b967tci.png" alt="Image description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So what job Cloudflare did for GoDaddy ?
&lt;/h2&gt;

&lt;p&gt;When you buy a domain (like &lt;a href="https://www.paletto.org/"&gt;https://www.paletto.org/&lt;/a&gt;), you need a way for people's computers to find the correct place on the internet when they type that address. That's where DNS (Domain Name System) comes in - it's like a phonebook for the internet, translating human-friendly domain names into computer-readable IP addresses.&lt;br&gt;
Now, GoDaddy is where you initially register your domain, and it usually helps manage your DNS settings. However, if you decide to use Cloudflare for your DNS, it means Cloudflare is taking over the job of managing the information that helps direct traffic to your website. So, when you can't add a record on GoDaddy, it's because Cloudflare is now in charge of handling those records instead. You'll need to go to your Cloudflare account to make any changes or additions to your DNS settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step VI:&lt;/strong&gt; It is the final step and the crucial one.&lt;/p&gt;

&lt;p&gt;Go to Github 🠖 Go to the particular project you want to host(Paletto in my case) 🠖 settings 🠖 pages (on left sidebar) 🠖 scroll downto Custom Domain 🠖 add the domain name (&lt;a href="http://www.paletto.org"&gt;www.paletto.org&lt;/a&gt; in my case) 🠖 uncheck the enforce https configurations and click on save. Good to go, now you can access your website by clicking on : your website is live at "&lt;em&gt;yourwebsite.com&lt;/em&gt;". Carefully see each and every detail mentioned above in the image attached below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nahKUIYF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/twerklocgc7y2xqi89ck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nahKUIYF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/twerklocgc7y2xqi89ck.png" alt="Image description" width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Learning (say mistake):
&lt;/h2&gt;

&lt;p&gt;I bought a very specific domain name (&lt;a href="https://www.paletto.org/"&gt;&lt;strong&gt;&lt;em&gt;paletto.org&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;). The reason I'm saying this is because soon I made two more projects which have no commonality in theme or for say their purpose (one such project is "&lt;strong&gt;&lt;em&gt;&lt;a href="https://cursive.paletto.org/"&gt;Practice Digital Writing&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;") So the learning is &lt;strong&gt;Develop Forward Visionary&lt;/strong&gt; as now even my main website name is &lt;strong&gt;&lt;em&gt;&lt;a href="https://himanimehra.paletto.org/"&gt;himanimehra.paletto.org&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; 😅.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;My journey into domain hosting underscored the significance of quality over quantity in the job market. Guided by the principle that "What is seen is sold," I hosted my major project, Paletto, on a GoDaddy domain.&lt;/p&gt;

&lt;p&gt;Encountering setbacks during my initial record addition attempt, I turned to Cloudflare as a seamless alternative for managing records. Lessons were learned, notably the importance of a versatile domain name. While paletto had a specific domain (paletto.org), subsequent projects prompted a more forward-thinking approach, resulting in a domain structure accommodating diverse projects, like himanimehra.paletto.org.&lt;/p&gt;

&lt;p&gt;This journey not only involved overcoming technical challenges but also highlighted the vital roles of adaptability and foresight in the evolving landscape of domain hosting and project development.&lt;/p&gt;

</description>
      <category>domainhosting</category>
    </item>
  </channel>
</rss>
