<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tulsi Prasad</title>
    <description>The latest articles on DEV Community by Tulsi Prasad (@thebuildguy).</description>
    <link>https://dev.to/thebuildguy</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%2F248065%2F664c7ee3-7aaa-42a0-9073-09ae6d89162f.jpg</url>
      <title>DEV Community: Tulsi Prasad</title>
      <link>https://dev.to/thebuildguy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thebuildguy"/>
    <language>en</language>
    <item>
      <title>ProgressPals: Your last productivity app</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Fri, 17 Jan 2025 07:51:01 +0000</pubDate>
      <link>https://dev.to/thebuildguy/progresspals-your-last-productivity-app-4dm0</link>
      <guid>https://dev.to/thebuildguy/progresspals-your-last-productivity-app-4dm0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github"&gt;GitHub Copilot Challenge&lt;/a&gt; : New Beginnings&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;Being a productivity nerd, I’ve tried out dozens of productivity apps starting from ones that block websites to habit trackers but I’ve always felt something missing in all of them. Remember a day before exam during school, we all could easily focus even 10+ hours each day but rest of the time even forgetting to check off habits from habit tracker.&lt;/p&gt;

&lt;p&gt;Yes, it’s because of accountability and the fear of losing (being seen as a failure in front of someone) that’s why we could focus before exams but not on everyday matters. &lt;/p&gt;

&lt;p&gt;Hence I build — ProgressPals.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A community focused productivity app that let’s you set challenges (and bet even real money yes) to accomplish something in a given time, people can join your challenge to audit you and track your daily progress (through live chat/progress pics). If you win, then you get to keep your wager, if you lose you’ve to donate to a charity of your choice. &lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Here’s a quick 5 min demo of the app, let me know what features you’d like to see and how would you use this platform.&lt;/p&gt;

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

&lt;p&gt;You can check the app here: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://progress-pals.vercel.app" class="ltag_cta ltag_cta--branded" rel="noopener noreferrer"&gt;Click to view demo&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Repo
&lt;/h2&gt;

&lt;p&gt;Here’s the link to GitHub repo (feel free to drop a star if you’ve liked it) —&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/heytulsiprasad" rel="noopener noreferrer"&gt;
        heytulsiprasad
      &lt;/a&gt; / &lt;a href="https://github.com/heytulsiprasad/progress-pals" rel="noopener noreferrer"&gt;
        progress-pals
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Ending procrastination since yesterday morning
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Progress Pals&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/52394293/402095269-d960a94f-ed52-48c1-9096-f4fde7bca11c.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzcxMDE0OTgsIm5iZiI6MTczNzEwMTE5OCwicGF0aCI6Ii81MjM5NDI5My80MDIwOTUyNjktZDk2MGE5NGYtZWQ1Mi00OGMxLTkwOTYtZjRmZGU3YmNhMTFjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAxMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMTE3VDA4MDYzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYyYmZiZTE1MzQxYjg3YTVkNDlhMGYxMDA5NWY5MmNlN2VmYjMwNmUwMTdhZDZhM2M0MTlmODNjOTk3MzY1ZTImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.VxsSBSxy8TuUU_71G4A8RLkH09OuiIlhkATg20sxM-A"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F52394293%2F402095269-d960a94f-ed52-48c1-9096-f4fde7bca11c.png%3Fjwt%3DeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzcxMDE0OTgsIm5iZiI6MTczNzEwMTE5OCwicGF0aCI6Ii81MjM5NDI5My80MDIwOTUyNjktZDk2MGE5NGYtZWQ1Mi00OGMxLTkwOTYtZjRmZGU3YmNhMTFjLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAxMTclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMTE3VDA4MDYzOFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTYyYmZiZTE1MzQxYjg3YTVkNDlhMGYxMDA5NWY5MmNlN2VmYjMwNmUwMTdhZDZhM2M0MTlmODNjOTk3MzY1ZTImWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.VxsSBSxy8TuUU_71G4A8RLkH09OuiIlhkATg20sxM-A" alt="CleanShot 2025-01-10 at 22 45 23@2x"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hope this will be an end to our perrenial procrastination&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Built in within a day for &lt;a href="https://dev.to/challenges/github" rel="nofollow"&gt;GitHub Copilot 1-Day Build Challenge&lt;/a&gt; using Copilot 🦄 and procrastination beating discipline.&lt;/p&gt;
&lt;p&gt;Launch post coming soon 🪄&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/heytulsiprasad/progress-palsx.com/thebuildguy" rel="noopener noreferrer"&gt;DM to talk&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/heytulsiprasad/progress-pals" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Copilot Experience
&lt;/h2&gt;

&lt;p&gt;I pretty much code in public (if that makes sense 😅). Here’s something I tweeted while running this challenge:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1878048037248868655-480" src="https://platform.twitter.com/embed/Tweet.html?id=1878048037248868655"&gt;
&lt;/iframe&gt;

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



 &lt;/p&gt;

&lt;p&gt;Last time I used copilot was ~few months back and only did chat completion/chat with GPT then but this time they’ve completely blown the game by introducing: “Edit with Copilot”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysp80ry36ds2tirbedd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysp80ry36ds2tirbedd9.png" alt="Edit with copilot in VS code" width="489" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I’ve realised is, the more detailed your prompt is and more accurate files that you attach to the context (don’t go spamming #codebase) all the time, you’ll get brilliant results. It edits and even creates new files in accurate folders and also shows you a diff of what it has done which I’ve pretty much accepted &amp;gt;90% of time. It depends on your prompt crafting though, as it might not be fully aware of your knowledge.&lt;/p&gt;

&lt;p&gt;I love tab completion feature as well, although it seems a bit slow at times but most of the time I’ve used the inline edit which does most of the jobs pretty easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Models
&lt;/h2&gt;

&lt;p&gt;I’ve mainly used &lt;code&gt;GPT 4o&lt;/code&gt; as it felt like the fastest there is and gets the job done almost always. However I felt &lt;code&gt;Claude 3.5 Sonnet&lt;/code&gt; is a bit better at crafting UI’s that look aesthetic, but it’s a bit slow so I’ve used it very less. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk56tmv3n24ascf9jxin4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk56tmv3n24ascf9jxin4.png" alt="All models in VS Code" width="717" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also tried out the &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-copilot-vision" rel="noopener noreferrer"&gt;Vision for Copilot Preview&lt;/a&gt; which fixed some UI issues but I still have to test out by giving it exact Figma snapshots, as I couldn’t in this challenge due to lack of time.&lt;/p&gt;

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

&lt;p&gt;If you see the &lt;a href="https://progress-pals.vercel.app/" rel="noopener noreferrer"&gt;footer on my app&lt;/a&gt;, I’ve said, “Built after 179 days of having the idea” and it’s fricking true as you can see the day I posted this on Twitter lol.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1812852056912490956-784" src="https://platform.twitter.com/embed/Tweet.html?id=1812852056912490956"&gt;
&lt;/iframe&gt;

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



 &lt;/p&gt;

&lt;p&gt;Although I’ve made a huge chunk, it still need some refining and actual payment integrations and good UI to maximise usability and accountability (if your real money is in stake lol). &lt;/p&gt;

&lt;h3&gt;
  
  
  Does it have real potential as a product?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia0.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExNHBncHR4bGZreWZscXk1ODhlNHZjc3FlMDBmdHVlajZvZzJlZHBmOSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F2gNOZeTdqbLUeEvVjA%2Fgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia0.giphy.com%2Fmedia%2Fv1.Y2lkPTc5MGI3NjExNHBncHR4bGZreWZscXk1ODhlNHZjc3FlMDBmdHVlajZvZzJlZHBmOSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw%2F2gNOZeTdqbLUeEvVjA%2Fgiphy.gif" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, I’m still testing the idea among people, but in my opinion if we’d have a right accountability partner who pushes us I’ve no doubt this would be a huge catalyst in people’s challenges, therefore making our app the next facebook! 😂&lt;/p&gt;

&lt;p&gt;Until then thanks for reading and don’t forget to stay hydrated (leave a feedback to help me improve). 🌱&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to use WebView in React Native?</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Thu, 22 Aug 2024 01:12:11 +0000</pubDate>
      <link>https://dev.to/thebuildguy/how-to-use-webview-in-react-native-3gma</link>
      <guid>https://dev.to/thebuildguy/how-to-use-webview-in-react-native-3gma</guid>
      <description>&lt;p&gt;A WebView is an embedded browser that can be used to display web pages inside your React Native applications. It can display anything starting from custom HTML elements to entire web applications inside React Native.&lt;/p&gt;

&lt;p&gt;In React Native, we can use the Webview by using a third-party package called, &lt;a href="https://github.com/react-native-webview/react-native-webview" rel="noopener noreferrer"&gt;react-native-webview&lt;/a&gt;. This is the official implementation of webview after it was removed from the &lt;a href="https://github.com/react-native-community/discussions-and-proposals/pull/3" rel="noopener noreferrer"&gt;React native core&lt;/a&gt; to keep the core as lean as possible.&lt;/p&gt;

&lt;p&gt;In this post, we're going to implement a simple project to see how to work with Webview's on React Native and what are some of the good use cases it serves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a React Native project
&lt;/h2&gt;

&lt;p&gt;To get started we need to begin a new project with React Native CLI. You can do this with expo if you don't want to go through a tedious installation process.&lt;/p&gt;

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

npx react-native init ExperimentingWithWebview


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

&lt;/div&gt;

&lt;p&gt;With Expo:&lt;/p&gt;

&lt;p&gt;If you're using Expo, you can jump straight to &lt;strong&gt;Implementing a Basic WebView&lt;/strong&gt; after this.&lt;/p&gt;

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

&lt;span class="nx"&gt;expo&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;native&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;webview&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Add dependencies
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

// For npm &lt;span class="nb"&gt;users
&lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-native-webview


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

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

// If you&lt;span class="s1"&gt;'re using yarn

yarn add react-native-webview


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Link native dependencies
&lt;/h2&gt;

&lt;p&gt;You'll only need this if you're not using Expo and using React Native CLI to start your project.&lt;/p&gt;

&lt;p&gt;If you're using &lt;code&gt;react-native&lt;/code&gt; ≥ 0.60 autolinking will take care of this step so feel free to skip, but don't forget to run &lt;code&gt;pod install&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

react-native &lt;span class="nb"&gt;link &lt;/span&gt;react-native-webview


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

&lt;/div&gt;

&lt;p&gt;If you ever uninstall this package,&lt;/p&gt;

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

react-native &lt;span class="nb"&gt;unlink &lt;/span&gt;react-native-webview


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  For iOS and macOS
&lt;/h3&gt;

&lt;p&gt;If using cocoapods, in &lt;code&gt;ios/&lt;/code&gt; or &lt;code&gt;macos/&lt;/code&gt; directory run,&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pod &lt;span class="nb"&gt;install&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  For Android
&lt;/h3&gt;

&lt;p&gt;If you're using react-native-webview &amp;lt; 6: Feel free to skip&lt;/p&gt;

&lt;p&gt;If you're using react-native-webview ≥ 6.x.x&lt;/p&gt;

&lt;p&gt;Make sure AndroidX is enabled in your project by editing &lt;code&gt;android/gradle.properties&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

android.useAndroidX=true
android.enableJetifier=true


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

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Chances are this is already done by React Native CLI automatically.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing a basic WebView
&lt;/h2&gt;

&lt;p&gt;It's time to get rid of the boilerplate code inside &lt;code&gt;app.js&lt;/code&gt; and write our code for webview.&lt;/p&gt;

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

&lt;span class="c1"&gt;// App.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SafeAreaView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StatusBar&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebView&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&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;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StatusBar&lt;/span&gt; &lt;span class="na"&gt;barStyle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dark-content"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://medium.com/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This is all you need to do inorder to display a website into your application.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  &lt;code&gt;originWhitelist&lt;/code&gt; prop
&lt;/h2&gt;

&lt;p&gt;This is a list of origin strings that you are allowed to navigate inside the webview component. It takes an array of strings. By default it's values are, &lt;code&gt;http://&lt;/code&gt; and &lt;code&gt;https://&lt;/code&gt;. If the user navigates to a new page that isn't in whitelisted origins, the URL will be handled by the OS.&lt;/p&gt;

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

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
  &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.educative.io/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;originWhitelist&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&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;https://*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;git://*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Loading local/inline HTML files
&lt;/h2&gt;

&lt;p&gt;You can also load local or inline HTML files into a Webview and this is how you can achieve that.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sourceHtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// your html file here&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sourceHtml&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Or add some inline HTML.&lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;htmlSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;h1 style="font-size:100px; padding: 50px; text-align: center;"&amp;gt;Hello World 🌍&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;htmlSource&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SafeAreaView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

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

&lt;h2&gt;
  
  
  Injecting custom javascript to webview
&lt;/h2&gt;

&lt;p&gt;You can also add your own javascript that can run inside the webview. You can use it to manipulate the behavior of the website you're loading as per your needs.&lt;/p&gt;

&lt;p&gt;There are two ways to do this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;injectedJavascript&lt;/code&gt; prop&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;injectJavascript&lt;/code&gt; method&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Their names can be confusing so shall understand them based on their purpose, it'll be clear to you in a few examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;injectedJavascript&lt;/code&gt; prop
&lt;/h2&gt;

&lt;p&gt;This is a prop to the Webview component which contains the scripts that'll run once the web page loads for this first time. It only runs once, even if the webpage is reloaded or navigated away.&lt;/p&gt;

&lt;p&gt;For example&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebView&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&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;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
      document.body.style.backgroundColor = 'hotpink';
      document.querySelector("h1").style.color = 'skyblue';
      document.querySelector("p").style.padding = '20px';
      true;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
        &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;injectedJavaScript&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;scripts&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

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

&lt;h2&gt;
  
  
  &lt;code&gt;injectJavascript&lt;/code&gt; method
&lt;/h2&gt;

&lt;p&gt;As we know the above &lt;code&gt;injectedJavascript&lt;/code&gt; prop that we discussed only works on first load and there is no other way if we want to run scripts at multiple times or page navigations. That's why, Webview exposes this method &lt;code&gt;injectJavascript&lt;/code&gt; on its reference.&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebView&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&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;getRandomColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0123456789ABCDEF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&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="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getRandomColor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`
      document.body.style.backgroundColor = '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;';
      document.body.style.color = '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;';
      document.body.querySelector("a").style.color = '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;';
      true;
      `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;injectJavaScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
          &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

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

&lt;p&gt;While all these ways can help you manipulate the webview as per your needs, one more requirement of yours can be sending or receiving data from the webpage inside WebView. So now we'll discuss how you can communicate between your JS and React Native app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communicating between JS and React Native
&lt;/h2&gt;

&lt;p&gt;This requires the use of two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;window.ReactNativeWebView.postMessage&lt;/code&gt; function&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onMessage&lt;/code&gt; prop&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;window.ReactNativeWebView.postMessage&lt;/code&gt; is a function that's exposed to the injected scripts inside WebView. You can basically pass anything to it, provided they're properly serialized. It'll be clear in the below example.&lt;/p&gt;

&lt;p&gt;Rest apart, whatever you pass inside &lt;code&gt;postMessage&lt;/code&gt; can be accessed in React Native through the callback passed into &lt;code&gt;onMessage&lt;/code&gt; prop. &lt;code&gt;onMessage&lt;/code&gt; is a prop for the Webview which takes a callback and is triggered anytime a message is sent using &lt;code&gt;postMessage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebView&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&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;getRandomColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;letters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0123456789ABCDEF&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;letters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&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="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scripts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getRandomColor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`
      document.body.style.backgroundColor = '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;';
      document.querySelector("h1").style.color = 'hotpink';    

      window.ReactNativeWebView.postMessage(document.body.style.backgroundColor);
      true;
      `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;injectJavaScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;scripts&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
          &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This simply logs the background color of the webpage whenever it's changed. As you can see, we are passing the callback inside &lt;code&gt;onMessage&lt;/code&gt; prop which gets triggered on &lt;code&gt;postMessage&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;The actual event object that's passed inside &lt;code&gt;onMessage&lt;/code&gt; callback is this, &lt;code&gt;[nativeEvent.data](http://nativeevent.data)&lt;/code&gt; is the argument we passed inside &lt;code&gt;window.ReactNativeWebView.postMessage&lt;/code&gt;.&lt;/p&gt;

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

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;nativeEvent&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;canGoBack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canGoForward&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(247, 75, 142)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Example Domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
             &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Handling Navigation State Changes
&lt;/h2&gt;

&lt;p&gt;Now we'll discuss how you can intercept whenever a user navigates inside the webview to a different webpage or clicks on any link. You can place a callback that'll happen anytime the route changes.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;onNavigationStateChange&lt;/code&gt; prop
&lt;/h3&gt;

&lt;p&gt;This takes a callback which is triggered whenever the user navigates inside the webview. It passes the current navigation state as an argument that can be accessed inside the callback.&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebView&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native-webview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;handleNavigationStateChanged&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;navState&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;navState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;});&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;WebView&lt;/span&gt;
          &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;webref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;onNavigationStateChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleNavigationStateChanged&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Basic &lt;code&gt;navState&lt;/code&gt; param structure passed into &lt;code&gt;handleNavigationStateChanged&lt;/code&gt;:&lt;/p&gt;

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

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canGoBack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canGoForward&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Example Domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiukziwripbycaz8npj8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiukziwripbycaz8npj8k.png" alt="Demo of application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just as a cool project you can play around with WebView and use many of its available methods such as &lt;code&gt;goForward&lt;/code&gt; and &lt;code&gt;goBack&lt;/code&gt;, &lt;code&gt;stopLoading&lt;/code&gt; (or even add &lt;a href="https://github.com/react-native-webview/react-native-webview/commit/30685edda045f7ba5d1400b415278e1109436dcd" rel="noopener noreferrer"&gt;apple pay support&lt;/a&gt;) to replicate a browser-like feel for your users, just like we used &lt;code&gt;injectJavascript&lt;/code&gt; method above.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;You can refer to React Native WebView &lt;a href="https://github.com/react-native-webview/react-native-webview/tree/master/docs" rel="noopener noreferrer"&gt;docs&lt;/a&gt; to have an overview of all that it offers or &lt;a href="https://github.com/react-native-webview/react-native-webview/blob/master/docs/Reference.md" rel="noopener noreferrer"&gt;references page&lt;/a&gt; to grab a look at all the available props and methods. If you're down for the above project, you can go over this &lt;a href="https://heartbeat.fritz.ai/how-to-handle-navigation-with-webviews-in-a-react-native-app-1ed51ab3342f" rel="noopener noreferrer"&gt;blog tutorial&lt;/a&gt; if you ever get stuck.&lt;/p&gt;

&lt;p&gt;Feel free to reach out to me on Twitter (&lt;a href="https://twitter.com/thebuildguy" rel="noopener noreferrer"&gt;@thebuildguy&lt;/a&gt;) if you've any questions and for more tech content.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>javascript</category>
      <category>mobile</category>
    </item>
    <item>
      <title>How to paginate queries in Firestore?</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Wed, 21 Aug 2024 04:34:59 +0000</pubDate>
      <link>https://dev.to/thebuildguy/how-to-paginate-queries-in-firestore-3pdc</link>
      <guid>https://dev.to/thebuildguy/how-to-paginate-queries-in-firestore-3pdc</guid>
      <description>&lt;p&gt;I recently had to create a paginated list view at work using Firebase which took a considerable amount of research and learning good practices, so writing this for someone who’s looking to hook up pagination in their existing firestore database or even for my future self in 5 months who has forgotten everything once again! 😅&lt;/p&gt;

&lt;p&gt;Firebase is a backend as a service (BaaS) platform, that enables us build and grow applications without having to write our own backend. You just plug and play whatever services you need on the go and you only pay for what you use in the long run. Now if you’re here already, I expect you might have used Firebase by now, but if not just follow the instructions it’ll make sense slowly.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Getting Started&lt;/li&gt;
&lt;li&gt;Building the app&lt;/li&gt;
&lt;li&gt;Implementing Pagination in Firestore&lt;/li&gt;
&lt;li&gt;Tips and Best Practices&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;We need to setup a react project with firebase to begin working with, along with database support using firestore. If you need help using setup you can follow along in &lt;a href="https://dev.to/thebuildguy/building-an-entire-fullstack-project-with-firebase-10-and-react-vite-dfe"&gt;this&lt;/a&gt; blog, it’s pretty straightforward. So without any further ado, let’s jump into some coding. &lt;/p&gt;

&lt;p&gt;Tip: You don’t have to note down all the code snippets from here, you can access this entire working repo from the following repo. 🌟&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/heytulsiprasad" rel="noopener noreferrer"&gt;
        heytulsiprasad
      &lt;/a&gt; / &lt;a href="https://github.com/heytulsiprasad/find-mates" rel="noopener noreferrer"&gt;
        find-mates
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Huge people's directory used to demonstrate pagination in firestore
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;Demo project for my blog post on &lt;a href="https://dev.to/thebuildguy/how-to-paginate-queries-in-firestore-3pdc" rel="nofollow"&gt;How to paginate queries in Firestore?&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Search through a list of 10k+ people&lt;/li&gt;
&lt;li&gt;Connect with random people from the internet&lt;/li&gt;
&lt;li&gt;Use prev and next buttons to navigate through the list&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/heytulsiprasad/find-mates" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Building the app
&lt;/h2&gt;

&lt;p&gt;Now that you know the importance of pagination and firestore as well 😅, this is how you start achieving that. We’re going to build a directory called find mates, of over 10k peoples which you can search through and view details about the people from the paginated views.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k5ycnb46luvj5wa8n9j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2k5ycnb46luvj5wa8n9j.png" alt="Home page of find mates app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re using good old Next 14 and tailwind with daisyUI for styles. If you go through the repo, we’ve a pretty straight forward structure. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The each individual card is called, PeopleCard&lt;/li&gt;
&lt;li&gt;PeopleList is the list container holding all the people in the paginated view.&lt;/li&gt;
&lt;li&gt;Paginator is just the row containing current page info and previous/next buttons.&lt;/li&gt;
&lt;li&gt;You can ignore DevSection, I used that to add the peoples data to firestore, using &lt;a href="https://fakerjs.dev/" rel="noopener noreferrer"&gt;faker&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9hdzrum4yood9py1k7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr9hdzrum4yood9py1k7n.png" alt="Code structure of find mates"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, you can create a new firebase project and add the variables to a local env file named as, &lt;code&gt;.env.local&lt;/code&gt;&lt;/p&gt;

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

NEXT_PUBLIC_FIREBASE_API_KEY=
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
NEXT_PUBLIC_FIREBASE_PROJECT_ID=
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
NEXT_PUBLIC_FIREBASE_APP_ID=


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

&lt;/div&gt;

&lt;p&gt;As you can see I also have an Auth Context to store authentication info, but later I realized I didn’t need this for the demo. It was for creating a bunch of users in secure way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Pagination in Firestore
&lt;/h2&gt;

&lt;p&gt;Great, now that you’ve setup the repo, we can move on to fun things.&lt;/p&gt;

&lt;p&gt;We’re going to start by looking how our firestore data looks like. As we’re having lots of people’s data to be stored, we’ll create a people collection and store each people as a document inside the collection.&lt;/p&gt;

&lt;p&gt;If you’ve anything huge to store you have to store them as documents inside a collection like tweets or list of people etc, as a document has a 1MB upper limit so we can’t basically store infinite amount of data and also we could use more advanced firebase queries and filters on collections to get the data we need. You can learn more about it with an example &lt;a href="https://cloud.google.com/firestore/docs/data-model#hierarchical-data" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is how my firestore dashboard looks like.&lt;/p&gt;

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

&lt;p&gt;Now you can create a component where you want to show the paginated data and upon it’s render we need to fetch the number of people data we want to show on one page. Let’s call it: &lt;code&gt;PEOPLE_PER_PAGE&lt;/code&gt;. We’ll start by creating all the state variables that we need.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;peopleList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPeopleList&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;afterThis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAfterThis&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;beforeThis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBeforeThis&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;totalPeople&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTotalPeople&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here these are the following use cases of these variables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;peopleList&lt;/code&gt; : list of all people’s that are shown in current page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;afterThis&lt;/code&gt;: snapshot of the last document in a page query. we’ll use it to start fetching the documents from after this document in a next page query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;beforeThis&lt;/code&gt;: snapshot of the first document in a query. we’ll use it to start fetching the documents from before this document in a previous page query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;page&lt;/code&gt; : index of current page&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;totalPeople&lt;/code&gt; : the total number of people exists in database&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re getting intimidated by all this don’t, coz we’ll see one by one how is each property being used and initiated.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Getting total number of people
&lt;/h3&gt;

&lt;p&gt;Let’s first update the &lt;code&gt;totalPeople&lt;/code&gt; value as based on it we’ll declare which page we’re currently showing. I’ve passed the searchTerm as a parameter as based on what the user searches, the total page (available people) changes.&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;startAfter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getDocs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getCountFromServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;limitToLast&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;endBefore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firebase/firestore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Get total count of people in Firestore (based on search term)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getTotalCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collectionRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;people&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;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;collectionRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;uf8ff&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aggregateQuerySnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getCountFromServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aggregateQuerySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;setTotalPeople&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

&lt;span class="c1"&gt;// Initiate value of total pages inside component&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TOTAL_PAGES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;totalPeople&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;PEOPLE_PER_PAGE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In the above query, we’re using where to filter out the people names by firstName which match with our searchTerm. Here “&amp;gt; =” is used in alphabetical manner, which means it returns all the documents in which &lt;code&gt;firstName&lt;/code&gt; starts with or comes after &lt;code&gt;searchTerm&lt;/code&gt; alphabetically. The addition of &lt;code&gt;"\uf8ff"&lt;/code&gt;  is a special unicode character, and is used as a sort of "maximum" character, allowing the query to include all possible variations of a string that start with a certain prefix. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. Fetch first batch of data on render
&lt;/h3&gt;

&lt;p&gt;Now we need to create the first query that we should run when the component renders. This will fetch the first batch of data that we want to show and user can continue from there by pressing next and previous buttons and we’ll have separate handlers for those.&lt;/p&gt;

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

&lt;span class="c1"&gt;// Fetch data based on searchTerm&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collectionRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;people&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;collectionRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;uf8ff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PEOPLE_PER_PAGE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;collectionRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PEOPLE_PER_PAGE&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;querySnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getDocs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&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;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;setPeopleList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setAfterThis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We use &lt;code&gt;orderBy&lt;/code&gt; firstName to arrange the list of people names in ascending order and &lt;code&gt;limit&lt;/code&gt; method to limit the total number of people to fetch per query. &lt;/p&gt;

&lt;p&gt;In order to actually run it, we need to call the above two functions inside an useEffect. We must pass the parameter &lt;code&gt;searchTerm&lt;/code&gt; to the useEffect dependency as if that changes, our queries are also changed and we need to fetch it again. Here’s how it looks.&lt;/p&gt;

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

&lt;span class="c1"&gt;// Fetch data on initial render and when searchTerm changes&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Fetch data based on searchTerm&lt;/span&gt;
  &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Get total count of people and store in state&lt;/span&gt;
  &lt;span class="nf"&gt;getTotalCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This is why when we search something, we get a new batch of data as this useEffect basically re-runs and both our current data and total page count is changed. Don’t worry about the individual People card components, I’ll show the entire code in a few.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before search:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31g7sloaa68mvhuhj6co.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31g7sloaa68mvhuhj6co.png" alt="Home page of find mates without search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After search:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73w1auipews5rlln6y9a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F73w1auipews5rlln6y9a.png" alt="Home page of find mates with search"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Handlers for previous and next buttons
&lt;/h3&gt;

&lt;p&gt;Now all we need are the handlers for previous and next button and show everything in a fancy design then we’re good to go. Here’s how you can create the handlers.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleNext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collectionRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;people&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;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;collectionRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PEOPLE_PER_PAGE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;startAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;afterThis&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;querySnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getDocs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&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;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;setAfterThis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="nf"&gt;setBeforeThis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="nf"&gt;setPeopleList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setPage&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlePrev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collectionRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;people&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;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;collectionRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firstName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;limitToLast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PEOPLE_PER_PAGE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;endBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;beforeThis&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;querySnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getDocs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;q&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;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;setAfterThis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="nf"&gt;setBeforeThis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="nf"&gt;setPeopleList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setPage&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Working of next handler:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We use the same format of querying as with earlier queries, however one thing that’s new here is the &lt;code&gt;startAfter&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We store the last document snapshot in the &lt;code&gt;afterThis&lt;/code&gt; state value and we pass it to &lt;code&gt;startAfter&lt;/code&gt; method in order for the query to start looking for documents from &lt;code&gt;afterThis&lt;/code&gt; doc.&lt;/li&gt;
&lt;li&gt;We also increment the page index by 1 after running the next handler.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Working of previous handler:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Similarly we use &lt;code&gt;beforeThis&lt;/code&gt; here to store the first document in the current people list.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;endBefore&lt;/code&gt; method in Firestore is used to create a query that retrieves documents ending before a specified document.&lt;/li&gt;
&lt;li&gt;We decrement the page index by 1 after running the previous handler.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Creating the Paginator component
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Paginator&lt;/code&gt; component shows the previous and next buttons as well as the current page shown out of total pages. This contains all the handlers and values we need to show the required data inside. it. You can see how it looks below.&lt;/p&gt;

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

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Paginator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;totalPages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;handleNext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;handlePrevious&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;nextDisabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;prevDisabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full flex items-center justify-between"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;clsx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn-primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prevDisabled&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn-disabled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handlePrevious&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Previous
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-lg"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Showing page &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; / &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;totalPages&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;clsx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn btn-primary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nextDisabled&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn-disabled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleNext&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Next
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here’s how the return statement looks of our container PeopleList looks like.&lt;/p&gt;

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

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"px-8 mt-12"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Pagination */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Paginator&lt;/span&gt;
    &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;totalPages&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;TOTAL_PAGES&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;handleNext&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleNext&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;handlePrevious&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handlePrev&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;nextDisabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;TOTAL_PAGES&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;prevDisabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid grid-cols-3 lgmax:grid-cols-2 mdmax:grid-cols-1 gap-x-4 gap-y-8 place-items-center"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;peopleList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;birthday&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;jobTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;sex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PeopleCard&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;jobTitle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;jobTitle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;birthday&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;birthday&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;sex&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sex&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  5. Creating the PeopleCard
&lt;/h3&gt;

&lt;p&gt;Now we’ll look at creating the people card to display the people info with some aesthetics! ✨&lt;/p&gt;

&lt;p&gt;As we know, &lt;code&gt;peopleList&lt;/code&gt; is the current batch of people’s data that’s fetched from firestore, we’re simply mapping over this list and passing the available data to PeopleCard (which looks as below). Let’s see inside PeopleCard. If you click on “Connect” you can connect with these imaginary people over email as well, let me know how it goes! 😅&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/* eslint-disable @next/next/no-img-element */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;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;PeopleCard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;birthday&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jobTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sex&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card bg-base-100 w-80 shadow-xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;figure&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-36 aspect-square mx-auto"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt;
          &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Avatar of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rounded-2xl"&lt;/span&gt;
        &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card-body text-center"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card-title justify-center w-full"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card-normal"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Job: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;jobTitle&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card-normal"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Email: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card-normal"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Birthday:&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;birthday&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleDateString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;numeric&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="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"card-actions justify-center mt-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"btn btn-primary"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`mailto:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            Connect
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;PeopleCard&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5a4v5tse2282ox2moto.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5a4v5tse2282ox2moto.png" alt="People card component"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips and Best Practices
&lt;/h2&gt;

&lt;p&gt;Even though pagination is not always the best option, but in case of large datasets (imagine an ecommerce dashboard) we probably want to use pagination. However there are some tips that you can keep in mind for a seamless integration.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Efficient Querying:&lt;/strong&gt; Ensure your Firestore collection is properly indexed, especially on fields you frequently query and order by. This can significantly speed up your queries and prevent Firestore from throwing an error due to missing indexes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle empty states edge cases:&lt;/strong&gt; When you’ve reached the last page of your query or on the first page (where you need to disable prev button), you’ve to make sure user knows it which page they’re on and if they’ve reached the end of the data set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching and performance:&lt;/strong&gt; ChatGPT suggested this, so I’m still in awe of how advanced AI has become. If you’re dealing with reading large amounts of data, you should do some sort of caching (or debouncing as well for potential users spamming the prev/next buttons). If you’re reading lots of data you’re also getting charged for total reads, hence it’s better as much as you can reduce this load on your server (also on your bank balance 😅)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s more info about firebase &lt;a href="https://firebase.google.com/pricing" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;. Left column is for free tier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuptwjg0qmnb3h1ob50qx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuptwjg0qmnb3h1ob50qx.png" alt="Pricing section of firebase"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I hope you’ve learned something new today and will be able to implement pagination in your apps now successfully. Even if now infinite scrolling is the new trend, most apps still need pagination. Now even &lt;a href="https://www.theverge.com/2024/6/25/24185727/google-search-continuous-scrolling-doomscrolling-graveyard" rel="noopener noreferrer"&gt;Google removed their infinite scroll&lt;/a&gt; and back to it’s paginated view. It’s a sure shot way to save you some bucks on overall reads on your server. 💰&lt;/p&gt;

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

&lt;p&gt;If you like this post, share with your friends and follow me on &lt;a href="https://x.com/thebuildguy" rel="noopener noreferrer"&gt;X/Twitter&lt;/a&gt; to know more nifty hacks on tech and stay tuned for more such content!&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Web Notifications API — One Byte Explainer</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Sat, 30 Mar 2024 12:36:28 +0000</pubDate>
      <link>https://dev.to/thebuildguy/web-notifications-api-one-byte-explainer-3jfg</link>
      <guid>https://dev.to/thebuildguy/web-notifications-api-one-byte-explainer-3jfg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for DEV Challenge v24.03.20, One Byte Explainer: Browser API or Feature.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explainer ⚡
&lt;/h2&gt;

&lt;p&gt;Imagine you ordered food from a restaurant but you don't get a reminder once it's ready.&lt;/p&gt;

&lt;p&gt;That's the pain Notifications API deems to solve.&lt;/p&gt;

&lt;p&gt;It sends notifications displayed at a system level, so even when you're absent you are alerted when your food is ready.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm26k3b7ikn7mowwb0wmt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm26k3b7ikn7mowwb0wmt.png" alt="Structure of how a notification works" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Context ✍️
&lt;/h2&gt;

&lt;p&gt;Websites becoming more advanced as applications these days have made them more interactive in our everyday lives, hence the in-built Notifications API is highly useful for web apps, PWAs, or even websites.&lt;/p&gt;

&lt;p&gt;Although it's quite difficult to get straight into coding once you understand the concept, the good news is that MDN has a great &lt;a href="https://github.com/mdn/dom-examples/tree/main/to-do-notifications"&gt;example&lt;/a&gt; that can get you started on it and learning &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API"&gt;documentation&lt;/a&gt; that you can refer if you get stuck.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Reading 💖
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API"&gt;Notifications API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.javascripttutorial.net/web-apis/javascript-notification/"&gt;Smallest example on the internet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If you're a video person, Web Dev Simplified has a great video. — &lt;a href="https://www.youtube.com/watch?v=Bm0JjR4kP8w"&gt;How To Send Push Notifications With JavaScript&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Let me know if you liked it at &lt;a href="https://twitter.com/thebuildguy"&gt;@thebuildguy&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>frontendchallenge</category>
      <category>devchallenge</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Top 5 things about Git learnt after I started working as a developer</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Wed, 11 Oct 2023 14:10:06 +0000</pubDate>
      <link>https://dev.to/thebuildguy/top-5-things-about-git-learnt-after-i-started-working-as-a-developer-58</link>
      <guid>https://dev.to/thebuildguy/top-5-things-about-git-learnt-after-i-started-working-as-a-developer-58</guid>
      <description>&lt;p&gt;Git is one of those things in software development, no one will tell you to use it but once you start working with a team or a company there’s no escape from Git. There’s no other concept which will be more useful than learning the ropes with Git, because it’ll be your saviour when you need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disclaimer ⭐
&lt;/h3&gt;

&lt;p&gt;If you’ve never heard of Git before, in simple words, it is used to work collaboratively. When we work on a big project multiple people need to contribute to a single codebase, for which we can use different branches on Git, or we can manage our codebase using commits, code merging and many more advanced stuff. &lt;/p&gt;

&lt;p&gt;Note: However if you’re complete new to Git, I’d recommend you go through this &lt;a href="https://www.freecodecamp.org/news/10-important-git-commands-that-every-developer-should-know/" rel="noopener noreferrer"&gt;10 Important Git Commands that Every Developer Should Know&lt;/a&gt; post on freeCodeCamp to know the basics.  &lt;/p&gt;

&lt;h2&gt;
  
  
  ✍️ How did I learn this?
&lt;/h2&gt;

&lt;p&gt;Well there’s no easy answer. I had this habit of &lt;a href="https://blog.isquaredsoftware.com/2020/09/coding-career-advice-daily-work-journal/" rel="noopener noreferrer"&gt;keeping a daily work journal&lt;/a&gt; which I picked from &lt;a href="https://blog.isquaredsoftware.com/about/" rel="noopener noreferrer"&gt;Mark Erikson&lt;/a&gt; (the maintainer of &lt;a href="https://redux.js.org/" rel="noopener noreferrer"&gt;Redux&lt;/a&gt;), in that mostly I’d write what features I worked on that day or bugs that scratched my itch. It really helped me look back on things I’ve learnt and write better documentation. &lt;/p&gt;

&lt;p&gt;However I observed that 90% of the issues related to code management could be solved by Git which will reduce our time usage and increase productivity. Hence I started maintaining a list of useful Git commands which you’re going to read right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Like always we’re going to start from a starter repo, in order to be on the same page. You can use it as a playground to get your hands dirty. All thanks to &lt;a href="https://www.w3schools.com/w3css/w3css_templates.asp" rel="noopener noreferrer"&gt;W3Schools&lt;/a&gt; for sharing this amazing templates! 🙌&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/heytulsiprasad" rel="noopener noreferrer"&gt;
        heytulsiprasad
      &lt;/a&gt; / &lt;a href="https://github.com/heytulsiprasad/git-top-skills" rel="noopener noreferrer"&gt;
        git-top-skills
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Git playground for learning git concepts
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;git-top-skills&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;Git playground for learning git concepts&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/heytulsiprasad/git-top-skills" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyxy0e16wjsz3f2baobz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyxy0e16wjsz3f2baobz.png" alt="UI of the project" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1️⃣ Git Reset
&lt;/h2&gt;

&lt;p&gt;Imagine a situation where you’re working on a new feature and before commiting to the repo you forgot to remove your debugging comments from your files. Now everywhere you can see &lt;code&gt;console.log("Hi bros")&lt;/code&gt; in the browser. 😅&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1710941362479104406-170" src="https://platform.twitter.com/embed/Tweet.html?id=1710941362479104406"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

&lt;p&gt;Yes you can remove them and create a new commit as well, but what if you want to remove those lines in the previous commit itself? Here comes, Git Reset to rescue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;@heytulsiprasad ➜ /workspaces/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log

commit 3d910a2debdf03ce57b22e97b5988c07a2c3437a &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; learn/reset, origin/learn/reset&lt;span class="o"&gt;)&lt;/span&gt;
Author: Tulsi Prasad &amp;lt;tulsi.prasad50@gmail.com&amp;gt;
Date:   Tue Oct 10 08:20:22 2023 +0000

    add comments

commit ae3d4cdd9e95f0da434e2be32a61addd824d633e &lt;span class="o"&gt;(&lt;/span&gt;origin/main, origin/HEAD, main&lt;span class="o"&gt;)&lt;/span&gt;
Author: Tulsi Prasad &amp;lt;tulsi.prasad50@gmail.com&amp;gt;
Date:   Tue Oct 10 08:14:20 2023 +0000

    feat: add script to populate blogs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Git Reset basically provides us a way to rewrite (or reset) our history as per our convinience. It comes with three modes depending on your usecase.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;--soft&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--mixed&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--hard&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  1. &lt;code&gt;git reset --soft&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This basically moves back to the specified commit and your changes remain staged and ready to be commited again. If you want to make any changes you can do them but don’t forget to add (stage) those changes before commiting again.&lt;/p&gt;

&lt;p&gt;Examples: &lt;code&gt;git reset --soft faf864e&lt;/code&gt;, or &lt;code&gt;git reset --soft HEAD~2&lt;/code&gt; (if you want to jump back 2 commits)&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;@heytulsiprasad ➜ /workspaces/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--soft&lt;/span&gt; HEAD~1

@heytulsiprasad ➜ /workspaces/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git status
On branch learn/reset
Your branch is behind &lt;span class="s1"&gt;'origin/learn/reset'&lt;/span&gt; by 1 commit, and can be fast-forwarded.
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git pull"&lt;/span&gt; to update your &lt;span class="nb"&gt;local &lt;/span&gt;branch&lt;span class="o"&gt;)&lt;/span&gt;

Changes to be committed:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git restore --staged &amp;lt;file&amp;gt;..."&lt;/span&gt; to unstage&lt;span class="o"&gt;)&lt;/span&gt;
        modified:   main.js

@heytulsiprasad ➜ /workspaces/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log
commit ae3d4cdd9e95f0da434e2be32a61addd824d633e &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; learn/reset, origin/main, origin/HEAD, main&lt;span class="o"&gt;)&lt;/span&gt;
Author: Tulsi Prasad &amp;lt;tulsi.prasad50@gmail.com&amp;gt;
Date:   Tue Oct 10 08:14:20 2023 +0000

    feat: add script to populate blogs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As you can see the last 1 commit is removed, but it’s changes are still in staging area.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. &lt;code&gt;git reset --mixed&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the default option. When you run this, you basically undo your commits and unstage your changes to your current working directory. After running this you can continue working on your specified commit and when you’re done you can commit those changes using git commit.&lt;/p&gt;

&lt;p&gt;Examples: &lt;code&gt;git reset faf86fe&lt;/code&gt; or &lt;code&gt;git reset --mixed HEAD~12&lt;/code&gt; (as mixed is default you don’t have to include the option)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Pro tip:&lt;/strong&gt; If you’ve accidentaly staged your changes using &lt;code&gt;git add .&lt;/code&gt; but decided to not add all of them, you can use &lt;code&gt;git reset&lt;/code&gt; to unstage all changes that are in current staging area. Later you can add files of your choice using &lt;code&gt;git add &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;@heytulsiprasad ➜ /workspaces/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log
commit 002f538b56529178e31f7042d7bb7a1e7ec18427 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; learn/reset&lt;span class="o"&gt;)&lt;/span&gt;
Author: Tulsi Prasad &amp;lt;tulsi.prasad50@gmail.com&amp;gt;
Date:   Tue Oct 10 08:28:25 2023 +0000

    add more comments

commit 120c7ddf4d56d93f49186758756e091748aedc59
Author: Tulsi Prasad &amp;lt;tulsi.prasad50@gmail.com&amp;gt;
Date:   Tue Oct 10 08:25:38 2023 +0000

    add comments

commit ae3d4cdd9e95f0da434e2be32a61addd824d633e &lt;span class="o"&gt;(&lt;/span&gt;origin/main, origin/HEAD, main&lt;span class="o"&gt;)&lt;/span&gt;
Author: Tulsi Prasad &amp;lt;tulsi.prasad50@gmail.com&amp;gt;
Date:   Tue Oct 10 08:14:20 2023 +0000

    feat: add script to populate blogs

@heytulsiprasad ➜ /workspaces/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--mixed&lt;/span&gt; ae3d4cdd9e95f0da434e2be32a61addd824d633e
Unstaged changes after reset:
M       main.js

@heytulsiprasad ➜ /workspaces/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git status
On branch learn/reset
Your branch is behind &lt;span class="s1"&gt;'origin/learn/reset'&lt;/span&gt; by 1 commit, and can be fast-forwarded.
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git pull"&lt;/span&gt; to update your &lt;span class="nb"&gt;local &lt;/span&gt;branch&lt;span class="o"&gt;)&lt;/span&gt;

Changes not staged &lt;span class="k"&gt;for &lt;/span&gt;commit:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add &amp;lt;file&amp;gt;..."&lt;/span&gt; to update what will be committed&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git restore &amp;lt;file&amp;gt;..."&lt;/span&gt; to discard changes &lt;span class="k"&gt;in &lt;/span&gt;working directory&lt;span class="o"&gt;)&lt;/span&gt;
        modified:   main.js

no changes added to commit &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add"&lt;/span&gt; and/or &lt;span class="s2"&gt;"git commit -a"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. &lt;code&gt;git reset --hard&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you ever want to discard all the changes in few commits entirely, you can use &lt;code&gt;--hard&lt;/code&gt;. This shifts the HEAD pointer to the specified commit and completely discards all the changes made till then, in both the staging area and working directory. This is a very powerful option so use it very carefully, because it deletes the commits permanently.&lt;/p&gt;

&lt;p&gt;Example: &lt;code&gt;git reset --hard faf86e&lt;/code&gt; or  &lt;code&gt;git reset --hard HEAD~3&lt;/code&gt; (removes last three commits). In the below example, we’re removing all our log commits using hard reset.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
9130158 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; learn/reset&lt;span class="o"&gt;)&lt;/span&gt; add more and more console logs
0e68a20 &lt;span class="o"&gt;(&lt;/span&gt;origin/learn/reset&lt;span class="o"&gt;)&lt;/span&gt; add all logs
ae3d4cd &lt;span class="o"&gt;(&lt;/span&gt;origin/main, origin/HEAD, main&lt;span class="o"&gt;)&lt;/span&gt; feat: add script to populate blogs
bf96bfb feat: add starter files
9017ea7 Initial commit

~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD~2
HEAD is now at ae3d4cd feat: add script to populate blogs

~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/reset&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
ae3d4cd &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; learn/reset, origin/main, origin/HEAD, main&lt;span class="o"&gt;)&lt;/span&gt; feat: add script to populate blogs
bf96bfb feat: add starter files
9017ea7 Initial commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;💡 &lt;strong&gt;Pro tip:&lt;/strong&gt; If you ever did some changes in your local or don’t know what’s missing and want to bring your working directory back to how it is in the remote repo (on GitHub), then you can first run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git fetch origin&lt;/code&gt; this fetches latest changes from remote without modifying your local working directory, next reset your local branch to match the remote branch using, &lt;code&gt;git reset --hard origin/main&lt;/code&gt;; You can replace &lt;code&gt;main&lt;/code&gt; with the branch you want to match it with.&lt;/p&gt;

&lt;p&gt;Note: It discards any local changes you’ve made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If you ever want to recover your &lt;code&gt;git reset&lt;/code&gt; commits which are permanently lost, git preserves the changes that are happening to it’s HEAD using reference logs. You can basically recover them using &lt;code&gt;git reflog&lt;/code&gt; but don’t be too reliant on it. To know how, check out my blog on it.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/thebuildguy" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F248065%2F664c7ee3-7aaa-42a0-9073-09ae6d89162f.jpg" alt="thebuildguy"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/thebuildguy/time-traveling-with-git-reflog-2f15" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Time traveling with Git Reflog&lt;/h2&gt;
      &lt;h3&gt;Tulsi Prasad ・ Sep 22 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#git&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#github&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  2️⃣ Git Stash
&lt;/h2&gt;

&lt;p&gt;This is a magical command and you’ll be surprised how much you’ll use this at workplaces. Imagine you’re working on a branch locally (dev) and suddenly there is another bug on master which you need to solve on priority, but your local branch already contains some changes which are not commit ready, what do you do? Git stash is your savior.&lt;/p&gt;

&lt;p&gt;Git stash, temporarily puts away your changes made to working directory in a branch, without having to commit them. You can stash your changes and go work on some other branch and come back and apply your saved stash and continue working from there.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To save your changes into the stash with a default name: &lt;code&gt;git stash&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To give a particular name to your stash: &lt;code&gt;git stash save -m "your stash name"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You can check all existing stash with this command: &lt;code&gt;git stash list&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;To retrieve the stash again (this will apply the latest stash): &lt;code&gt;git stash apply stash@{0}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Remove a stash entry from stash list: &lt;code&gt;git stash drop &amp;lt;stash_id&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Remove all stashes using: &lt;code&gt;git stash clear&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git status
On branch learn/stash
Changes not staged &lt;span class="k"&gt;for &lt;/span&gt;commit:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add &amp;lt;file&amp;gt;..."&lt;/span&gt; to update what will be committed&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git restore &amp;lt;file&amp;gt;..."&lt;/span&gt; to discard changes &lt;span class="k"&gt;in &lt;/span&gt;working directory&lt;span class="o"&gt;)&lt;/span&gt;
        modified:   index.html
        modified:   main.js

no changes added to commit &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add"&lt;/span&gt; and/or &lt;span class="s2"&gt;"git commit -a"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git stash save &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"add more blogs with media"&lt;/span&gt;
Saved working directory and index state On stash: add more blogs with media

~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git stash list
stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;: On stash: add more blogs with media
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However &lt;code&gt;git stash apply&lt;/code&gt; will only apply the stash but not remove it from stash list. If you want to remove the entry, use stash pop instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git stash apply stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;
On branch learn/stash
Changes not staged &lt;span class="k"&gt;for &lt;/span&gt;commit:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add &amp;lt;file&amp;gt;..."&lt;/span&gt; to update what will be committed&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git restore &amp;lt;file&amp;gt;..."&lt;/span&gt; to discard changes &lt;span class="k"&gt;in &lt;/span&gt;working directory&lt;span class="o"&gt;)&lt;/span&gt;
        modified:   index.html
        modified:   main.js

no changes added to commit &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add"&lt;/span&gt; and/or &lt;span class="s2"&gt;"git commit -a"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git stash list
stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;: On stash: add more blogs with media
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default stash will save both staged and unstaged files, in order to stash just staged files just do &lt;code&gt;git stash --keep-index&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Pro tip:&lt;/strong&gt; To apply the last made stash you can do (this also removes stash from stash list): &lt;code&gt;git stash pop&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git stash pop
On branch learn/stash
Changes not staged &lt;span class="k"&gt;for &lt;/span&gt;commit:
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add &amp;lt;file&amp;gt;..."&lt;/span&gt; to update what will be committed&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git restore &amp;lt;file&amp;gt;..."&lt;/span&gt; to discard changes &lt;span class="k"&gt;in &lt;/span&gt;working directory&lt;span class="o"&gt;)&lt;/span&gt;
        modified:   index.html
        modified:   main.js

no changes added to commit &lt;span class="o"&gt;(&lt;/span&gt;use &lt;span class="s2"&gt;"git add"&lt;/span&gt; and/or &lt;span class="s2"&gt;"git commit -a"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
Dropped refs/stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;2669f29b4f44ce1d48c9309196361f4efbd94449&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3️⃣ Interactive Rebase
&lt;/h2&gt;

&lt;p&gt;In Git, rebasing basically means to move any commit or sequence of commits to a new base commit (or update its base). It can be used in two different modes: manual or interactive. You might ask why do we need rebase if we can simply do a git merge instead? &lt;/p&gt;

&lt;p&gt;Imagine a scenario you’ve two branches, master and internal. Internal is a feature branch created from master. And while you were working there have been certain bug fixes that are directly pushed to master and now you need those fixes in internal. So, what do you do now?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna3egrjro8cn8x9yxt4e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna3egrjro8cn8x9yxt4e.png" alt="Rebasing of commits" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, we can rebase our &lt;code&gt;internal&lt;/code&gt; branch with &lt;code&gt;master&lt;/code&gt; branch (after fetching all pushes to master from remote) in order to get those latest code in internal. Before you do rebase you should always commit your latest work, as rebase basically rebases your commits. Now you can happily work in internal which also includes those new commits from master later you can push to master when your feature is ready! 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sjjkkdv730j1wdqnp2p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sjjkkdv730j1wdqnp2p.png" alt="State of commits after rebase" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code for the above action would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout internal
git fetch origin master
git rebase master &lt;span class="c"&gt;# you may face merge conflicts depending on code&lt;/span&gt;
git push origin internal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above is a simple rebase example. Now, let’s see what the heck is an interactive mode?&lt;/p&gt;

&lt;h3&gt;
  
  
  Under the hood of rebase
&lt;/h3&gt;

&lt;p&gt;Whenever we do rebase in a branch, it takes those sequence of commits and under the hood creates new commits and places them upon a new branch. Hence if you’re pushing your commits to remote, when you do a rebase you might get an error as your commit ids have changed in local. Hence, you might have to do a force push. &lt;code&gt;git push -f&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Do not force push if other people are also working on same branch, you might overwrite someones code accidentally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tell us what an interactive rebase is then?
&lt;/h3&gt;

&lt;p&gt;Ofcourse! So whenever you’re working on a feature you can do temporary commits which you don’t want to be visible on your main branch’s history. So what do you do now? You cannot revert those commits right, as &lt;code&gt;git revert&lt;/code&gt; basically creates another commit. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5k3mq8x7rmw2gxrjhe7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5k3mq8x7rmw2gxrjhe7.png" alt="Example of GitHub PR" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hence comes, &lt;code&gt;git rebase --i &amp;lt;commit_id&amp;gt;&lt;/code&gt;  🧑‍💻&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First check the git log to get the actual commit id
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
e7cd367 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; learn/stash, origin/learn/stash&lt;span class="o"&gt;)&lt;/span&gt; feat: add random photos to blog posts
a664717 plz work
d592e77 remove space
6bfe89b remove useless comments
8e6e68c feat: add more blogs
ae3d4cd &lt;span class="o"&gt;(&lt;/span&gt;origin/main, origin/HEAD, main, learn/reset&lt;span class="o"&gt;)&lt;/span&gt; feat: add script to populate blogs
bf96bfb feat: add starter files
9017ea7 Initial commit

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now run the interactive rebase command and provide the commit id of the root commit above which you want to rebase the branch.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/stash&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; ae3d4cd
hint: Waiting &lt;span class="k"&gt;for &lt;/span&gt;your editor to close the file...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As said, you’ll see your editor open a file which we’ll make changes to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45uyooctoxmlzq9a1neq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45uyooctoxmlzq9a1neq.png" alt="Git Interactive Rebase" width="800" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;strong&gt;squash&lt;/strong&gt; the commits if you want to discard the commit but preserve it’s contents, or &lt;strong&gt;reword&lt;/strong&gt; if you want to rename your commits and &lt;strong&gt;pick&lt;/strong&gt; will preserve the commit. All the operations are listed in the screenshot.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Added the necessary changes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9cu5q3ipxa690sgc6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fub9cu5q3ipxa690sgc6x.png" alt="Rebase interactive" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Close the file after editing. Now you’ll get to do the operations in new opening files and after you edit close all of them. This is my final screen, you can update your final rebase comment now.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfkt0lyhi5s3pp4tg1r8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvfkt0lyhi5s3pp4tg1r8.png" alt="Commit edit screen" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once it’s done you’ll get a message in console like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Date: Tue Oct 10 19:41:55 2023 +0530
 1 file changed, 13 deletions&lt;span class="o"&gt;(&lt;/span&gt;-&lt;span class="o"&gt;)&lt;/span&gt;
Successfully rebased and updated refs/heads/learn/stash.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you do git log now, you’ll see the changes you made.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0t8fwm3b9dooa845jt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0t8fwm3b9dooa845jt8.png" alt="Git log in oneline mode" width="800" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; To push the changes to our PR, we need to do a force push as we’ve an entirely different history of commits now&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkhdbvq3cc27p20zyvin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkhdbvq3cc27p20zyvin.png" alt="Git push error after rebase" width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run: &lt;code&gt;git push -f&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now we can see our history is cleared in the PR. 🙌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ksy5wci3yykr6q1icqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ksy5wci3yykr6q1icqb.png" alt="GitHub PR after force push" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even while merging a PR in GitHub we can do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a merge commit&lt;/li&gt;
&lt;li&gt;Squash and merge&lt;/li&gt;
&lt;li&gt;Rebase and merge&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We used the &lt;strong&gt;rebase and merge&lt;/strong&gt; to merge, and this way we avoided any mysterious merge commits on main branch which included entire feature code.&lt;/p&gt;

&lt;p&gt;Now you can see all our feature commits inside main branch history, as it’s merged by rebase instead of the usual merge commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c3u3ky0wvxyv5w9s1p7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3c3u3ky0wvxyv5w9s1p7.png" alt="Commit history after rebase and merge" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4️⃣ Git Cherry Picking
&lt;/h2&gt;

&lt;p&gt;This is a powerful tool under your toolbelt. Git cherry pick is used to pick the specified commit and put it in your working directory without having to merge or rebase the entire branch. I know it sounds like a hack, but trust me you’re going to love it.&lt;/p&gt;

&lt;p&gt;Imagine your working on a feature branch and you find a bug that affects your main branch and your boss insists you fix the bug before working on anything else. Now, you’ve already fixed the bug and commited on your feature branch. Do you merge your half made feature branch or fix the bug again after checking out to main branch?&lt;/p&gt;

&lt;p&gt;Easy. Use Git Cherry Pick. 🍒&lt;/p&gt;

&lt;p&gt;For example: We’re adding a popular posts section to our blog in a new branch and we decided to ship the popular post commit to main first then continue working more on the feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdory0vnz8x7nhf00bvfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdory0vnz8x7nhf00bvfb.png" alt="Popular posts UI" width="594" height="544"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how we’ll do it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; learn/cherry-pick &lt;span class="c"&gt;# b stands for create new branch&lt;/span&gt;

&lt;span class="c"&gt;# add code and commit your code&lt;/span&gt;
~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;learn/cherry-pick&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: add posts to popular post section"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;learn/cherry-pick 7dd2a8e] feat: add posts to popular post section
 2 files changed, 9 insertions&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;, 11 deletions&lt;span class="o"&gt;(&lt;/span&gt;-&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# checkout to main branch&lt;/span&gt;
git checkout main

~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git cherry-pick 7dd2a8e
&lt;span class="o"&gt;[&lt;/span&gt;main 8490a61] feat: add posts to popular post section
 Date: Tue Oct 10 20:59:57 2023 +0530
 2 files changed, 9 insertions&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;, 11 deletions&lt;span class="o"&gt;(&lt;/span&gt;-&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# we can see 7dd2a8e commit has been added to main with a new commit id&lt;/span&gt;
~/Desktop/Triage/dev/git-top-skills &lt;span class="o"&gt;(&lt;/span&gt;main&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
8490a61 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; main&lt;span class="o"&gt;)&lt;/span&gt; feat: add posts to popular post section
94bd178 &lt;span class="o"&gt;(&lt;/span&gt;origin/main, origin/HEAD&lt;span class="o"&gt;)&lt;/span&gt; feat: add random photos to blog posts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will pick the specific bug fix commit from your feature branch and put that in your main branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;-edit&lt;/code&gt; option if you want to update the commit message while cherry picking.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;--no-commit&lt;/code&gt; option to just move the changes of the specified commit into the working directory and not commit.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;--signoff&lt;/code&gt; option to add a signature line to end of cherry pick commit message. 🧑‍💻&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5️⃣ Searching for code
&lt;/h2&gt;

&lt;p&gt;Pretty much half my adult life must have gone into finding the right part of the code, if not more. 😅  So don’t make the same mistake as me, as Git makes pretty much easy to look through your code. There are times you want to filter the commits by author or the commits that are made between a specific dates, you can use these options to find out the files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Pro Tip:&lt;/strong&gt; You can use the &lt;code&gt;- num&lt;/code&gt; option to specify the exact number of commits you want to show.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;More ways to filter commit history:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By Date&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to show your commits by the date they were made, you can use this option. It’s simply writing &lt;code&gt;git log --after="YYYY-MM-DD"&lt;/code&gt; and it’ll output the desired logs. The below code only will output 2 logs as we’ve passed a new parameter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5olmbkon1q53eim83vw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5olmbkon1q53eim83vw.png" alt="Git Log with after" width="785" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notice:&lt;/strong&gt; You can also pass &lt;code&gt;--after&lt;/code&gt; and &lt;code&gt;--before&lt;/code&gt; commands together to give a range of commits and also the date value can be relative as in: &lt;code&gt;git log --after="yesterday"&lt;/code&gt; also works.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By Author&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can pass &lt;code&gt;git log --author="&amp;lt;name&amp;gt;"&lt;/code&gt; and it’ll return a list of all commits made by those person. Even if it’s not exact match, it just needs to contain the specified word.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfob80m2c0trzjuh6y0z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftfob80m2c0trzjuh6y0z.png" alt="Git Log with Author" width="794" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By Commit Message&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just like author, you can use &lt;code&gt;--grep&lt;/code&gt; option to pass any value to match it with commit message. Example: In the below command, we’re filtering two feature commits made by Tulsi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsptaqgfx7q0er1wawsiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsptaqgfx7q0er1wawsiq.png" alt="Git log with grep and author" width="764" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By File path&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sometimes you need to find the commits that made changes to specific files, hence it will come in handy.&lt;/p&gt;

&lt;p&gt;Use: &lt;code&gt;git log -- filename&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The following code returns the commit that makes changes to &lt;a href="http://README.md" rel="noopener noreferrer"&gt;README.md&lt;/a&gt; file, the &lt;code&gt;--&lt;/code&gt; denotes that the subsequent parameters are not branch names.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvgwty4jqkxl4rce63glt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvgwty4jqkxl4rce63glt.png" alt="Git log by file" width="651" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By Branch&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to check what commits are there in some branch and not in other, you can use this syntax.&lt;/p&gt;

&lt;p&gt;Use: &lt;code&gt;git log branchA..branchB&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The following code returns the commits that are there in &lt;code&gt;learn/cherry-pick&lt;/code&gt; branch but not in &lt;code&gt;main&lt;/code&gt;. So remember it as, the difference in commits from branch B to branch A. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4gdcz8op5ua96mf97rq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh4gdcz8op5ua96mf97rq.png" alt="Difference between branches using git log" width="762" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Bonus: Showing commits beautifully
&lt;/h2&gt;

&lt;p&gt;We can understand the state of our repository through &lt;code&gt;git log&lt;/code&gt; and for better understanding and quick access there are certain options you can make use of.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;git log --oneline&lt;/code&gt; : Returns the output in a single line and commit id&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git log --graph&lt;/code&gt; : Draws an ASCII graph representing the branch structure in commit history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git log --decorate&lt;/code&gt;: Decorates the git log output&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can use all of these options together to get the best results and also use &lt;code&gt;--all&lt;/code&gt; option if needed to see commits across all branches.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4r63333pnmyvzdgptlv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4r63333pnmyvzdgptlv.png" alt="Git log with pretty formatting" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Pro Tip&lt;/strong&gt;: You can also make an custom alias in your terminal as &lt;code&gt;git adog&lt;/code&gt; in order to run this command every time you want to view git history.&lt;/p&gt;

&lt;h2&gt;
  
  
  📕 Additional Reading
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;a href="https://www.atlassian.com/git/tutorials/advanced-overview" rel="noopener noreferrer"&gt;Atlassian’s Advanced Git Tutorials&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.isquaredsoftware.com/2021/01/coding-career-git-usage/" rel="noopener noreferrer"&gt;Using Git for Version Control Effectively&lt;/a&gt; by &lt;a href="https://twitter.com/acemarke" rel="noopener noreferrer"&gt;@acemarke&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.toptal.com/git/the-advanced-git-guide" rel="noopener noreferrer"&gt;The Advanced Git Guide&lt;/a&gt; by Toptal&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🏳️ Conclusion
&lt;/h2&gt;

&lt;p&gt;Git is going to be a very essential part of your work life, if not already! I really believe you’ll be a pro using these git commands and absolutely certain your life will be 10x if not 100x easier when you master these concepts and use them daily in your workflow. &lt;/p&gt;

&lt;p&gt;Let me know in the comments what other git commands have you used the most till date. 😼&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/zDpYQooxkwXkAWMxRK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/zDpYQooxkwXkAWMxRK/giphy.gif" alt="Until next time" width="480" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I’m &lt;a href="https://twitter.com/thebuildguy" rel="noopener noreferrer"&gt;@thebuildguy&lt;/a&gt; on Twitter, shoot me a DM if you’ve got any questions!&lt;/em&gt; 👋&lt;/p&gt;

</description>
      <category>git</category>
      <category>programming</category>
    </item>
    <item>
      <title>Building an entire fullstack project with Firebase 10 and React (Vite)</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Tue, 03 Oct 2023 14:22:33 +0000</pubDate>
      <link>https://dev.to/thebuildguy/building-an-entire-fullstack-project-with-firebase-10-and-react-vite-dfe</link>
      <guid>https://dev.to/thebuildguy/building-an-entire-fullstack-project-with-firebase-10-and-react-vite-dfe</guid>
      <description>&lt;p&gt;&lt;strong&gt;Firebase&lt;/strong&gt; is a BAAS (backend as a service) solution that drives the modern web. The most exciting part of it is you don’t need to configure any server running some server side code, as its all managed by Firebase. &lt;/p&gt;

&lt;p&gt;However it’s setup can be time consuming and takes a good amount of to and fro around the documentation. This is why I decided to write this, to make it as a reference for using basic features like authentication, hosting and &lt;strong&gt;firestore operations&lt;/strong&gt; (CRUD) to do in firebase/firestore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recently, firebase shifted its SDKs to a new modular approach with the launch of &lt;a href="https://firebase.google.com/support/release-notes/js" rel="noopener noreferrer"&gt;Firebase v9&lt;/a&gt;. It brings features like reduced SDK size and greater efficiency with modern JS build tools to optimize your apps (using tree-shaking etc). So we’ll be using it’s new Web Modular API.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1420112970453897216-17" src="https://platform.twitter.com/embed/Tweet.html?id=1420112970453897216"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Getting Started&lt;/li&gt;
&lt;li&gt;Setting up Firebase&lt;/li&gt;
&lt;li&gt;Setting up the starter files&lt;/li&gt;
&lt;li&gt;Understanding the starter files&lt;/li&gt;
&lt;li&gt;Authentication in Firebase&lt;/li&gt;
&lt;li&gt;Working with Data&lt;/li&gt;
&lt;li&gt;Deploying our project&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1️⃣ Getting Started
&lt;/h2&gt;

&lt;p&gt;We’re going to make a fullstack modern todo-list using firebase, react and tailwind stack. I know you’re like, why yet another todolist. But hear me out, we’re not learning how to build a todolist here, we’re here to know about how firebase basic functionailities work so that we can build our cool apps with it.&lt;/p&gt;

&lt;p&gt;Here's the link to final repository if you want to play around.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/heytulsiprasad" rel="noopener noreferrer"&gt;
        heytulsiprasad
      &lt;/a&gt; / &lt;a href="https://github.com/heytulsiprasad/modern-todolist-v1" rel="noopener noreferrer"&gt;
        modern-todolist-v1
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Starter files for blog on using Firebase 10, Firestore and React in Vite
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;React + Vite + Firebase 10&lt;/h1&gt;

&lt;/div&gt;
&lt;p&gt;This template provides a minimal setup to get React working in Vite and Firebase 10 and Firestore for authentication and real-time database usage.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/heytulsiprasad/modern-todolist-v1" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  2️⃣ Setting up Firebase
&lt;/h2&gt;

&lt;p&gt;You can skip to the next section if you know how to setup firebase proejcts already.&lt;/p&gt;

&lt;p&gt;Go to Firebase &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;dashboard&lt;/a&gt; and after logging in you can click on start a new project. &lt;/p&gt;

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

&lt;p&gt;After giving your project a name, click on continue.&lt;/p&gt;

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

&lt;p&gt;In the next screen, disable Google Analytics as we’re just doing this for learning purposes and then click on &lt;strong&gt;Create Project&lt;/strong&gt;. It might take upto ~1 min to create the project, once its done click continue and you can see the dashboard of your firebase console.&lt;/p&gt;

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

&lt;p&gt;In above dashboard, click on settings (gear icon) → &lt;strong&gt;project settings&lt;/strong&gt; and then click on the code icon in your apps section. It’ll create a web project inside firebase for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rw8vrxhazpzfmwumofy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rw8vrxhazpzfmwumofy.png" alt="firebase project settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you’re done with that, you’ll see the below screen and after you enter your app nickname, click on register app. No need of setting up firebase hosting now, as you can host it anywhere or set up at firebase later too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgclinyijhvwxl5qsdcxe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgclinyijhvwxl5qsdcxe.png" alt="create firebase app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you register the app you’ll see where these code snippets, which basically are the instructions on how to install firebase in your project. You can copy the firebase config code and paste it somewhere or come back to it later when we’ll install firebase in our app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3n2e8idvctvn1xyoens.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3n2e8idvctvn1xyoens.png" alt="get firebase config"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later click on continue to console. You can see your web app is created now and it’s listed inside your apps section. Awesome, we’ve done the setup inside firebase, lets setup our repository now.&lt;/p&gt;

&lt;h2&gt;
  
  
  3️⃣ Setting up the starter files
&lt;/h2&gt;

&lt;p&gt;We’re going to be using Vite for development with React. It is a performace based build tool that provides a faster development experience. That’s what I love about it, it’s super &lt;strong&gt;duper&lt;/strong&gt; fast and supports very fast &lt;a href="https://vitejs.dev/guide/features.html#hot-module-replacement" rel="noopener noreferrer"&gt;hot module replacement&lt;/a&gt; (HMR).&lt;/p&gt;

&lt;p&gt;All you have to do is run:&lt;/p&gt;

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

git clone https://github.com/heytulsiprasad/modern-todolist-v1.git


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

&lt;/div&gt;

&lt;p&gt;Once the repo is cloned, just run &lt;code&gt;npm install&lt;/code&gt; inside the directory. Now you can access the project pretty much by, &lt;code&gt;npm run dev&lt;/code&gt;. But you have to replace &lt;code&gt;firebaseConfig&lt;/code&gt; in &lt;code&gt;config/firebase.js&lt;/code&gt; with your own firebase config which we got from the web.&lt;/p&gt;

&lt;p&gt;If you don’t find it, go to Firebase dashboard → project settings → your apps. &lt;/p&gt;

&lt;p&gt;Now firebase is successfully added into our project and we can start building our cool features! 💃&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can checkout to final branch later for the final version of the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  4️⃣ Understanding the starter files
&lt;/h2&gt;

&lt;p&gt;In order to save our precious time, we’re not going to code the entire application from scratch, as we’re just here to expand our knowledge on how to interact with our data using Firestore. It has high scalability, advanced query capabilities and real-time updates.&lt;/p&gt;

&lt;p&gt;The project is build using several ready made components available within, &lt;a href="https://mantine.dev/" rel="noopener noreferrer"&gt;Mantine&lt;/a&gt;. It’s a fully featured React components library. However some places still use some custom CSS-in-JS so we used some good ol’ &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;styled components&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you check inside, &lt;code&gt;App.jsx&lt;/code&gt; we’re storing the user auth in local state of App component. You wouldn’t want something like this in your production though, as now we have various state management libraries for easy stage management, but as we’re just to learn we kinda go with local state.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb87h3o9t9eo5qr4k52xg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb87h3o9t9eo5qr4k52xg.png" alt="todo app homescreen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The tabs in Home page, is actually &lt;a href="https://mantine.dev/core/tabs/" rel="noopener noreferrer"&gt;Tabs component&lt;/a&gt; from mantine. It’s really easy to setup and just check out their &lt;a href="https://mantine.dev/core/tabs/" rel="noopener noreferrer"&gt;docs&lt;/a&gt; if you need any help.&lt;/p&gt;

&lt;h3&gt;
  
  
  One last thing before we chunk out code
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;We need to activate authentication from firebase.&lt;/li&gt;
&lt;li&gt;So go inside dashboard → click on authentication from sidebar and press &lt;strong&gt;Get Started&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeidpnxn08d05gr3h3ef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeidpnxn08d05gr3h3ef.png" alt="firebase authentication dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need to set up a sign in method in order to authenticate our user, so press on Set up sign-in method and click Add new provider.&lt;/li&gt;
&lt;li&gt;Let’s choose Google provider for now, as its the most easiest to setup.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  5️⃣ Authentication in Firebase
&lt;/h2&gt;

&lt;p&gt;As you can see there’s an &lt;code&gt;Avatar&lt;/code&gt; component in the Navbar, so let’s authenticate our user when he/she clicks on the Avatar component. To start with we’re only going to keep authentication using Google. However, feel free to add more options.&lt;/p&gt;

&lt;p&gt;Now, let’s add a &lt;code&gt;handleAuthentication&lt;/code&gt; callback to run when the user presses Avatar. As you can see in the below code, it’ll by default log in using Google. Here we’re using &lt;code&gt;signInWithPopup&lt;/code&gt; action to authenticate the user.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Navbar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;isAuth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsAuth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProfile&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleAuthentication&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authenticating user&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;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GoogleAuthProvider&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;try&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;signInWithPopup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provider&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="c1"&gt;// Set to state&lt;/span&gt;
      &lt;span class="nf"&gt;setIsAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;providerData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StyledNav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;#modern todolist&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Avatar&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleAuthentication&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"md"&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photoURL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;StyledNav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; If you’re using any domains other than &lt;a href="http://localhost" rel="noopener noreferrer"&gt;localhost&lt;/a&gt; to run the website, then upon authentication you’ll get an (auth/unauthorized-domain) error. To fix this you need to add your domain inside authorized domains.&lt;/p&gt;

&lt;p&gt;Go to authentication → Settings → Authorized domains → Add domain&lt;/p&gt;

&lt;p&gt;Now we’ll be able to login using any google account. Let’s code the sign out flow.&lt;/p&gt;

&lt;p&gt;As we have a state called, &lt;code&gt;isAuth&lt;/code&gt; so depending upon if its true we can log out user or else login user, on the same button click.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Navbar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;isAuth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsAuth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setProfile&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleAuthentication&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleLogout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Sign out user if authenticated&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Logging out user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Clear state&lt;/span&gt;
      &lt;span class="nf"&gt;setIsAuth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setProfile&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;StyledNav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;#modern todolist&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Avatar&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isAuth&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;handleLogout&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;handleAuthentication&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"md"&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;photoURL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;StyledNav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This will logout user when they’re logged in and log in the user when they’re logged out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzxjw6tcgbn23y5eb46i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzxjw6tcgbn23y5eb46i.png" alt="modern todolist homescreen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you did the above steps correctly, you’ll be able to see the profile picture of the logged in user in our Avatar section as shown above.&lt;/p&gt;

&lt;h2&gt;
  
  
  6️⃣ Working with data
&lt;/h2&gt;

&lt;p&gt;As we’re done with auth now, we can start adding todos for each user. We’ll be using Firestore SDK for this purpose and we’ll go over the most used CRUD operations so it’ll be easy for us to refer to it back when you’re doing something big.&lt;/p&gt;

&lt;p&gt;Before adding our data, we should know: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firestore stores all data in a NoSQL manner, inside collections and documents.&lt;/li&gt;
&lt;li&gt;Documents are the smallest unit of storage, each document is known by an id. Documents are very light weight JSON-like records, they’re not exactly JSON but support few more types of data like nested arrays, geo points, server timestamps etc!&lt;/li&gt;
&lt;li&gt;They can collect upto 1MB data max.&lt;/li&gt;
&lt;li&gt;Collections are the container of documents, we can have basically infinite number of documents inside each collection.&lt;/li&gt;
&lt;li&gt;Collections can be also made within documents, they’d be then called &lt;strong&gt;sub collection&lt;/strong&gt;. They can also store infinite sub documents.&lt;/li&gt;
&lt;li&gt;If we delete all documents inside a collection, the collection deletes itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. Creation of todos
&lt;/h3&gt;

&lt;p&gt;In our app, we’re going to store multiple todos for each user. So the schema would be like, &lt;code&gt;users/{userId}/todos/{todoId}&lt;/code&gt;. Here, users is the collection and {userId} is the id of the document. &lt;code&gt;todos&lt;/code&gt; is the sub collection and &lt;code&gt;{todoId}&lt;/code&gt; is the id of sub document.&lt;/p&gt;

&lt;p&gt;We can add documents into firestore in two types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using &lt;code&gt;setDoc&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;addDoc&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We use &lt;code&gt;setDoc&lt;/code&gt; when we want to give our document a specific id.&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDoc&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firebase/firestore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="c1"&gt;// Add a new document in collection "companies"&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;setDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;companies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bengaluru&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;India&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;But what if we don’t want to take the hassle of giving an id to our document everytime, thus we can let firestore auto generate an id for us.&lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addDoc&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firebase/firestore&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="c1"&gt;// Add a new document in collection "companies"&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;companyRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;companies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bengaluru&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;country&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;India&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// companyRef.id = auto generated id&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let’s create the todos in our app then. We’ve an Input component that handles the new todo entries by user, so we’re going to add this handler in order to add new todos.&lt;/p&gt;

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

&lt;span class="c1"&gt;// src/components/Input/index.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Add todo to database&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todosRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&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;todoRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;addDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todosRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;serverTimestamp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// updates state&lt;/span&gt;

      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Todo created with id: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;todoRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In above code, we’re first making a reference to todos collection, then using &lt;code&gt;addDoc&lt;/code&gt; we’re passing that reference and an object of new data that we’ve to add, then firebase creates a new document for us.&lt;/p&gt;

&lt;p&gt;This is how todos are created.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Read all todos
&lt;/h3&gt;

&lt;p&gt;Now in order to display all todos inside each tabs, we need to read all documents from firestore. How do we do that?&lt;/p&gt;

&lt;p&gt;We can do that either by fetching all documents once or subscribing to entire todos collection. So that our todos gets updated automatically if new todos gets created/updated/deleted. We’ll go over both of these ways separately.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Read all documents once&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchAllDocuments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allTodos&lt;/span&gt; &lt;span class="o"&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;todosRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&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;todosSnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getDocs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todosRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;todosSnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;allTodos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;      
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;allTodos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The above function calls the function for once, we can put it inside our &lt;code&gt;useEffect&lt;/code&gt; in order for it to run everytime the component is mounted. However this gets the data one time, if we update/delete or create a new todo, it doesn’t update the list again. For that we need to subscribe to a collection.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Subscribe to entire collection&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todosRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&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;unsubscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;onSnapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todosRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

        &lt;span class="nx"&gt;querySnapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;allTodos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

        &lt;span class="nf"&gt;setTodos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;allTodos&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;

      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// when component unmounts&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;show&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This is very fast in nature and updates the todos if there’s any change in data. It can also listen for &lt;a href="https://firebase.google.com/docs/firestore/query-data/listen?hl=en&amp;amp;authuser=0#events-local-changes" rel="noopener noreferrer"&gt;local changes&lt;/a&gt; itself, which means even before writing to the backend it’ll notify us about the new data. This is called, &lt;strong&gt;&lt;a href="https://firebase.google.com/docs/firestore/query-data/listen#events-local-changes" rel="noopener noreferrer"&gt;latency compensation&lt;/a&gt;&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;For this we just pass a query inside an &lt;code&gt;onSnapshot&lt;/code&gt; function and it takes care of the rest. As this subscription listens forever for new changes, we have to remove them so that our callback functions won’t be called anymore. We can do that calling &lt;code&gt;unsubscribe&lt;/code&gt; on unmount, as shown above.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Update todos
&lt;/h3&gt;

&lt;p&gt;We also need the ability to update our todos right? Like as you can see while creating the todos we had a &lt;code&gt;completed&lt;/code&gt; property which showed if a todo is completed or not. Hence, we use &lt;code&gt;updateDoc&lt;/code&gt; function to update documents. Here is an example.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleToggleComplete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todoId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todoRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;todoId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todoRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="c1"&gt;// smart way of converting any type to type Boolean&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;As we’ve used &lt;code&gt;onSnapshot&lt;/code&gt; to subscribe to our todos collection, we don’t need to refetch the latest documents after update, it’ll sync itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd4k92li3dcv04q9hevs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd4k92li3dcv04q9hevs.png" alt="modern todoist completed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You also get cool ready made methods to update specific types of data such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In nested arrays: &lt;code&gt;arrayRemove&lt;/code&gt; and &lt;code&gt;arrayUnion&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In numbers: &lt;code&gt;increment()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In nested objects: dot notation (&lt;code&gt;parent.child&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Refer &lt;a href="https://firebase.google.com/docs/firestore/manage-data/add-data#update_elements_in_an_array" rel="noopener noreferrer"&gt;original documentation&lt;/a&gt; for more examples on different languages too.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Delete todos
&lt;/h3&gt;

&lt;p&gt;Finally, we need the ability to delete todos. This is very simple, we just need to take reference over a todo document and use &lt;code&gt;deleteDoc&lt;/code&gt; method to delete it.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDelete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todoId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todoRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;todoId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deleteDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todoRef&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note on delete:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deleting a document doesn’t delete it’s subcollection. So if you want it’s subcollections to also be deleted you need to manually do that by iteration.&lt;/li&gt;
&lt;li&gt;You can delete a particular field inside an document, by using &lt;code&gt;deleteField()&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateDoc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteField&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;firebase/firestore&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;todoRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;todoId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Remove the 'capital' field from the document&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateDoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todoRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;deleteField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;You should not delete entire collections from the web client. It’s not as per practice and also your app can get very slow from out-of-memory errors as you need to load all documents.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  7️⃣ Deploying our project
&lt;/h2&gt;

&lt;p&gt;Nowadays you can deploy your client side web apps almost anywhere for free, like &lt;a href="https://www.netlify.com/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt;, &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt; or &lt;a href="https://surge.sh/" rel="noopener noreferrer"&gt;Surge&lt;/a&gt; or even &lt;a href="https://firebase.google.com/docs/hosting" rel="noopener noreferrer"&gt;Firebase hosting&lt;/a&gt;. However as we’re using Firebase in this tutorial, let’s explore deploying with firebase as well.&lt;/p&gt;

&lt;p&gt;Go to hosting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhd5l0tip33v831x0c3q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhd5l0tip33v831x0c3q.png" alt="firebase hosting dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to host your website:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install firebase tools (&lt;code&gt;npm install -g firebase-tools&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Initialize your project

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;firebase login&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;firebase init&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbme14he2bh5tg12vza4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbme14he2bh5tg12vza4z.png" alt="firebase command line"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;From features list, we need to choose: &lt;strong&gt;Hosting: Configure files for Firebase Hosting&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;What do you want to use as your public directory: &lt;strong&gt;dist&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure as a single page app (rewrite all urls to index.html): &lt;strong&gt;yes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Setup automatic deployments to Github: &lt;strong&gt;no&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;File dist/index.html exists, overwrite? &lt;strong&gt;Yes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Deploy complete ✅&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hbx7sudeiel3o1r300o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hbx7sudeiel3o1r300o.png" alt="deploy complete to firebase hosting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our web app is hosted on: &lt;a href="https://modern-todolist.web.app/" rel="noopener noreferrer"&gt;https://modern-todolist.web.app&lt;/a&gt; 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  🍞 Summary (TLDR)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Firebase provides all types of solutions for making fullstack projects like authentication, databases (firestore and realtime), hosting etc.&lt;/li&gt;
&lt;li&gt;Firestore is very good for scalability, realtime data syncronisation and advanced querying support. We’re using firestore in this project to make our fullstack app.&lt;/li&gt;
&lt;li&gt;In firestore we’ve certain ways of interacting with data.

&lt;ul&gt;
&lt;li&gt;To read any data, create a reference to it first. Use methods like &lt;code&gt;collection()&lt;/code&gt; or &lt;code&gt;doc()&lt;/code&gt; to do the same.&lt;/li&gt;
&lt;li&gt;Then to create documents use &lt;code&gt;setDoc()&lt;/code&gt; or &lt;code&gt;addDoc()&lt;/code&gt; and to modify/update data use &lt;code&gt;updateDoc()&lt;/code&gt; . To delete doc we use &lt;code&gt;deleteDoc()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To read all the docs from a collection, pass reference to collection to &lt;code&gt;getDocs()&lt;/code&gt; and to read a single doc use &lt;code&gt;getDoc()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;We can also subscribe to a collection or document changes, by using &lt;code&gt;onSnapshot()&lt;/code&gt; and passing reference to it.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;query()&lt;/code&gt; to query over data source and use above methods to read data.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Deployment is also easily done by firebase hosting (refer above steps).&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  8️⃣ Conclusion
&lt;/h2&gt;

&lt;p&gt;Basically today we’ve played around with all types of data in firestore, with this knowledge you can build fullstack data centric applications from scratch using just firebase tools. Earlier if your project grows you needed to scale your servers and all manually but with firebase it all happens seamlessly. You can take up it’s blaze plan (pay as you go) which is also very cheap.&lt;/p&gt;

&lt;p&gt;Really excited to see what cool stuff you’re building with it. Let me know in comments down below. 😼&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I’m &lt;a href="https://twitter.com/thebuildguy" rel="noopener noreferrer"&gt;@thebuildguy&lt;/a&gt; on Twitter, shoot me a DM if you’ve got any questions!&lt;/em&gt; 👋&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>firebase</category>
      <category>vite</category>
      <category>react</category>
    </item>
    <item>
      <title>Working of Garbage Collection in JavaScript: Under the Hood ✨</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Thu, 21 Sep 2023 13:57:55 +0000</pubDate>
      <link>https://dev.to/thebuildguy/working-of-garbage-collection-in-javascript-under-the-hood-231e</link>
      <guid>https://dev.to/thebuildguy/working-of-garbage-collection-in-javascript-under-the-hood-231e</guid>
      <description>&lt;p&gt;JavaScript is a wonderful language. Even after using it for years, there are still processes that happen under the hood, that most people don’t know/care about. Garbage collection is one of them. It is one of the most important parts of the language, but as JS is a garbage-collected language (memory is managed by JS engine automatically) we often ignore such beautiful inner- workings of the language.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;What is garbage collection?&lt;/li&gt;
&lt;li&gt;Memory management in JavaScript&lt;/li&gt;
&lt;li&gt;Structure of memory space&lt;/li&gt;
&lt;li&gt;
Garbage collection algorithms in JS

&lt;ul&gt;
&lt;li&gt;Reference counting garbage collection&lt;/li&gt;
&lt;li&gt;Mark &amp;amp; Sweep algorithm&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Common leaks in Memory

&lt;ul&gt;
&lt;li&gt;Unexpected global variables&lt;/li&gt;
&lt;li&gt;Forgotten timers or callbacks&lt;/li&gt;
&lt;li&gt;Out of DOM reference&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Further Reading&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  🗑️ What is garbage collection? &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Every program runs with a certain memory which it uses to store its variables, function declarations etc. but at some point those entities might not be used anymore by the program and unnecessary storage of it causes memory consumption, which makes the app run slower. This is why we need, &lt;strong&gt;Garbage Collection.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Langauges like C exposes the properties like &lt;code&gt;malloc()&lt;/code&gt; and &lt;code&gt;free()&lt;/code&gt; to manually allocate and free up memory space from the program. But in JS it happens automatically, using algorithms we’re gonna see down below. Hence, &lt;strong&gt;JS&lt;/strong&gt; is known as a &lt;strong&gt;garbage collected language.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/5eFp76zhsq3uw/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/5eFp76zhsq3uw/giphy.gif" alt="Throwing computer in trash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Memory management in JS &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Basically, memory management is the process of managing memory in a program and it’s job is correctly manage all the entities in a program to it’s respective types of storage, in return helping the program run faster.&lt;/p&gt;

&lt;p&gt;The memory management has three steps in it’s lifecycle:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F36jr2z170yz7b8o39sxr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F36jr2z170yz7b8o39sxr.png" alt="Lifecycle of memory management"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In programs of every language, these three steps are taken in respect to memory management.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Allocate&lt;/strong&gt;: This allocates appropriate memory space to the respective entities. Manual memory managed languages like C and C++ do this manually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use:&lt;/strong&gt; This step denotes the usage of entities stored in memory space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Release:&lt;/strong&gt; It denotes the release of a memory space used by an entity, after the entity is no longer used or is terminated. This step is done by garbage collection algorithms in JS.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🗼 Structure of Memory Space &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Before looking for solutions on how to handle garbage collection of JS, we need to know where does JS store it’s entities and how?&lt;/p&gt;

&lt;p&gt;The JS engine is very smart in storing data. It segregates all of the entities in two types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Primitive data types&lt;/strong&gt; (string, boolean, number, undefined, null and symbols)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference data types&lt;/strong&gt; (objects, arrays and functions)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1br0s2l3zpuq9ycqljd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1br0s2l3zpuq9ycqljd.png" alt="Classification of data types"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They both are stored in their own unique ways. In JavaScript data is stored between &lt;strong&gt;Stack Storage&lt;/strong&gt; to store primitive values and &lt;strong&gt;Heap Storage&lt;/strong&gt; to store non-primitive or reference values.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧊 Stack Memory
&lt;/h3&gt;

&lt;p&gt;This contains the primitive data types like string, numbers, boolean, undefined and null. These are also called as static data, hence the process of its allocation is called, static memory allocation. These values have a fixed amount of memory hence it’s called static data and are stored in stack memory.&lt;/p&gt;

&lt;p&gt;Along with primitive values, stack memory also contains the reference to objects and functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8opzclb2uzhkygjtmxdt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8opzclb2uzhkygjtmxdt.png" alt="Representation of stack memory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🍃 Heap Memory
&lt;/h3&gt;

&lt;p&gt;This type of memory is allocated dynamically as per need requires, hence it’s called dynamic allocation. These are also called reference data types and can store large values of variables. The size of this variable is known at the run time only. It has no limit to how much data can be stored.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Pro tip:&lt;/strong&gt; This memory can also have a limit but depending upon various factors like browser, OS or particular engine limitations. But you can check your memory availability as such:&lt;/p&gt;

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

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsHeapSizeLimit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 4294705152&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The output might vary from person to person, for me it’s around 4.29GBs. But if you’re using something that big, there’s definitely a problem with your app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq945u9b81jek6p357ik.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxq945u9b81jek6p357ik.png" alt="Reference types code example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6kjuzwfhb3zdacqfj2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6kjuzwfhb3zdacqfj2r.png" alt="Storing variables in stack and heap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤖 Garbage Collection Algorithms in JavaScript &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;As we now know how the memory allocation in JavaScript takes place and where all the data is stored, we can now think of how to empty memory which is not used anymore for a program. This process is called &lt;strong&gt;Garbage Collection&lt;/strong&gt; and it’s done by a &lt;strong&gt;Garbage Collector.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In JavaScript it happens automatically using algorithms, hence it’s not always efficient depending on the type of algorithm and usecases, as we can’t always predict if some memory block is still in use in the runtime. &lt;/p&gt;

&lt;p&gt;However, we’ll discuss some of the most important ones below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reference counting garbage collection&lt;/li&gt;
&lt;li&gt;Mark &amp;amp; Sweep algorithm&lt;/li&gt;
&lt;li&gt;Generational collection&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  #️⃣ Reference Counting Garbage Collection &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is a very simplistic garbage collection algorithm. It looks through the code for objects references and when a particular object is not referenced to anyone anymore and is not used by any other part of code, hence the algorithm cleans them up, freeing up the memory they were occupying.&lt;/p&gt;

&lt;p&gt;We can understand it better from the below example.&lt;/p&gt;

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

&lt;span class="c1"&gt;// Create object variable&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;company1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mumbai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create references to same object&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;workplace1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;company1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Clean references&lt;/span&gt;
&lt;span class="nx"&gt;workplace1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;company1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, as we saw after assigning both &lt;code&gt;company1&lt;/code&gt; and &lt;code&gt;workplace1&lt;/code&gt; the value of &lt;code&gt;null&lt;/code&gt;, we don’t have any reference to object &lt;code&gt;{ location: "Mumbai" }&lt;/code&gt; hence, the reference to that object is lost and that memory is garbage collected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitations
&lt;/h3&gt;

&lt;p&gt;Despite of the benefits however, we’ve a limitation of this algorithm. This doesn’t work where there are cyclic references. Example:&lt;/p&gt;

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

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;wild&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tiger&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;domestic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create cyclic references&lt;/span&gt;
&lt;span class="nx"&gt;wild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;domestic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;domestic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;member&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wild&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Clean objects&lt;/span&gt;
&lt;span class="nx"&gt;wild&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="nx"&gt;domestic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;As in the above example, we used &lt;code&gt;member&lt;/code&gt; property inside both objects &lt;code&gt;wild&lt;/code&gt; and &lt;code&gt;domestic&lt;/code&gt; to reference each other, but at the end we declared both objects to null, which leaves their member property to reference to each other, which is not accessible anymore too. This is why Garbage collection becomes difficult with Reference Counting GC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If we declared &lt;code&gt;wild&lt;/code&gt; and &lt;code&gt;domestic&lt;/code&gt; variables with &lt;code&gt;const&lt;/code&gt; instead of &lt;code&gt;let&lt;/code&gt;, then we’d have difficulty cleaning up those variables afterwards. This is because, &lt;code&gt;const&lt;/code&gt; doesn’t allow us to modify the value of a variable after its creation, thus if you know that a variable should be garbage cleaned, then declare it with &lt;code&gt;let&lt;/code&gt; or &lt;code&gt;var&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This stackoverflow answer by YDKJS author, Kyle Simpson provides a better example of this (&lt;a href="https://stackoverflow.com/a/38318597" rel="noopener noreferrer"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  🧹 Mark and Sweep Algorithm &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;As we’ve seen the limitations of previous algorithm, we needed a solution to take care of Garbage Collection in cyclic dependencies. This is what Mark and Sweep Algorithm is good at.&lt;/p&gt;

&lt;p&gt;This algorithm checks if a particular entity is reachable from the root of the environment. Example: In case of browser it is &lt;code&gt;window&lt;/code&gt; and in case of NodeJS it’s &lt;code&gt;global&lt;/code&gt;. This basically marks the objects that aren’t reachable as garbage and sweeps them later, simple as the name suggests. However, it doesn’t clean up the root objects.&lt;/p&gt;

&lt;p&gt;According to MDN, all modern browser engines ship a version of mark-and-sweep garbage collector. Improvements have been made to this algorithm but not entire change of its idea.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/NV4cSrRYXXwfUcYnua/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/NV4cSrRYXXwfUcYnua/giphy.gif" alt="Tom cleaning floor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;p&gt;It resolves the problem with cyclic dependencies right away, as it marks every object starting from root and whatever's left unmarked, it sweeps (or cleans up) afterwards. Hence, there is never any unused values left eating up our memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Even though it handles memory management all by itself, but it doesn’t exactly understand which memory is needed in future or not, hence JS apps can consume more memory than they actually need.&lt;/li&gt;
&lt;li&gt;As the algorithm decides when to clean up the marked garbage, your app can be slow or even run out of memory in certain situations (although its very rare)&lt;/li&gt;
&lt;li&gt;Hence it’s a good practice to use lower level languages with manual memory management, if you want your application to be as memory efficient as possible.&lt;/li&gt;
&lt;li&gt;As we have no control over the algorithm, it can decide when it has to run which can consume our good compute power, hence leaving our apps slower at times.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚿 Common Leaks in Memory &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Memory leaks is an inherent issue with programming languages, where a certain piece of memory is not required by the application but not returned to the operating system or memory pool. This can cause serious issues ranging from: high latency, slow compute or even crashes. &lt;/p&gt;

&lt;p&gt;Certain programming languages provide features to manage memory manually but in JavaScript it happens automatically, so we’ve to avoid any situations where memory can be leaked to save us from excessive memory usage. Some of the most common leaks of memory are:&lt;/p&gt;

&lt;h3&gt;
  
  
  Unexpected global variables &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is the most easiest trap of leaking your memory. The garbage collector algorithm, parses through all the objects starting from the root in runtime. ie (&lt;code&gt;window&lt;/code&gt; in browser and &lt;code&gt;global&lt;/code&gt; in nodejs) and whatever references that are connected to the root object, will never be garbage cleaned. Hence we shall not put everything in global variables, especially if we don’t need to use it later.&lt;/p&gt;

&lt;p&gt;Example scenario.&lt;/p&gt;

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

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;placesToVisit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sites&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Agra&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Maldives&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alaska&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Los Angeles&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="c1"&gt;// window.sites = ["Agra", "Maldives", "Alaska", "Los Angeles"]&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In the above example, if you’d access &lt;code&gt;sites&lt;/code&gt; from the window variable, you get the array of sites. But we only need that inside &lt;code&gt;placesToVisit&lt;/code&gt; function. This is where memory can’t be cleaned even after termination of placesToVisit function, as sites is attached to window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NB:&lt;/strong&gt; If you want to prevent this, you can use &lt;code&gt;'use strict'&lt;/code&gt; at the beginning of your JS files, in this way your JS will strictly parse your files and prevent unexpected global variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Forgotten timers or callbacks &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;As we know there are various timers in JS, like &lt;code&gt;setTimeout&lt;/code&gt; or &lt;code&gt;setInterval&lt;/code&gt; that can keep running even after their desired work is over. Hence we need to handle those functions explicitly. &lt;/p&gt;

&lt;p&gt;For example you have a weather app, which constantly needs to fetch latest weather (lets say every 5 seconds). Hence you write a setInterval which runs once each 5 seconds to fetch data and update your UI. But in case, the user navigates from weather screen to lets say some other page (lets say about) but the &lt;code&gt;setInterval&lt;/code&gt; is still running, which is consuming your memory. This is a leakage of memory.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latestWeatherData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;home&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Update the UI with the latest weather data&lt;/span&gt;
        &lt;span class="nx"&gt;home&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latestWeatherData&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// runs every 5 secs&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In above example if home is removed from screen but the setInterval will still continue to run every 5 seconds, which is unnecessary. Hence to solve this and save memory, invocation of setInterval can be stopped using &lt;code&gt;clearInterval&lt;/code&gt;. &lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latestWeatherData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;checkWeather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;home&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Update the UI with the latest weather data&lt;/span&gt;
        &lt;span class="nx"&gt;home&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latestWeatherData&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// When home is unmounted&lt;/span&gt;
        &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkWeather&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// stops execution of setinterval&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// runs every 5 secs&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The same happens with DOM event listeners as well. As we write eventlisteners on some DOM element, it keeps on listening to that event forever. But what if the component is removed from UI, do we still need the listening? No right. In that case we need to remove the event listener to prevent memory leaks.&lt;/p&gt;

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

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementsByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;clickHandler&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textDecoration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;line-through&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// checks off todo&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clickHandler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clickHandler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// removes listener upon unmount&lt;/span&gt;

&lt;span class="c1"&gt;// User wants to delete this todo&lt;/span&gt;
&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here, when todo is unmounted from UI, the &lt;code&gt;clickHandler&lt;/code&gt; function also gets removed or garbage collected. In older browsers this used to be done as they couldn’t handle cyclic references well, but nowadays most browsers have this inbuilt feature to remove observers/event listeners by themselves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Out of DOM reference &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is a type of memory leak when we keep a reference to a DOM element inside a data structure in our program but later on that component is them unmounted from the UI. Even though the DOM element is deleted, its stored in our memory.&lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allCars&lt;/span&gt; &lt;span class="o"&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;cars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;#cars&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;allCars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;cars&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;removeElement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;allCars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&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="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In the above example, we remove all the cars from the UI, but we still have all the references to cars DOM inside &lt;code&gt;allCars&lt;/code&gt; array. This is where memory leak occurs. &lt;/p&gt;

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

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allCars&lt;/span&gt; &lt;span class="o"&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;cars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;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;#cars&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;allCars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;cars&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;removeElement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;allCars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&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="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;allCars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// removes car element from allCars at index&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Hence we should also clean up that array while removing DOM nodes in order to save leaked memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  📒  Further Reading &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Garbage collection is a vast concept in programming and due to the battle of performance these days, the algorithms keeps updating time to time. You can follow the blogs of different browsers engines to stay updated on their garbage collectors. Here are some of them that helped me clear my understanding while writing this in first place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://v8.dev/blog/trash-talk" rel="noopener noreferrer"&gt;Trash talk: the Orinoco garbage collector · V8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management" rel="noopener noreferrer"&gt;Memory management - JavaScript | MDN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jayconrod.com/posts/55/a-tour-of-v8-garbage-collection" rel="noopener noreferrer"&gt;A tour of V8: Garbage Collection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.info/garbage-collection" rel="noopener noreferrer"&gt;Garbage collection&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4qLf0FJMyf0" rel="noopener noreferrer"&gt;Video from Arpit Bhayani about Mark and Sweep GC&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4qLf0FJMyf0" rel="noopener noreferrer"&gt;Mark and Sweep Garbage Collection Algorithm&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgifdb.com%2Fimages%2Fhigh%2Fpatrick-star-aww-cute-reaction-59sv0me3f6z1jd1b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgifdb.com%2Fimages%2Fhigh%2Fpatrick-star-aww-cute-reaction-59sv0me3f6z1jd1b.gif" alt="Aww"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you liked this post, you might love what I share as well on &lt;a href="https://twitter.com/thebuildguy" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. Let's catch up!&lt;/em&gt; 💖&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Future of professional networking 🧙‍♂️</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Fri, 30 Sep 2022 16:49:56 +0000</pubDate>
      <link>https://dev.to/thebuildguy/future-of-professional-networking-15g</link>
      <guid>https://dev.to/thebuildguy/future-of-professional-networking-15g</guid>
      <description>&lt;p&gt;📸 Photo credit - &lt;a href="https://unsplash.com/@campaign_creators"&gt;Campaign creators&lt;/a&gt; on Unsplash!&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;What is professional networking?&lt;/li&gt;
&lt;li&gt;Why need professional networking?&lt;/li&gt;
&lt;li&gt;Benefits of professional networking&lt;/li&gt;
&lt;li&gt;Modern day solutions to professional networking&lt;/li&gt;
&lt;li&gt;Using social media for professional networking&lt;/li&gt;
&lt;li&gt;Why I love peerlist?

&lt;ul&gt;
&lt;li&gt;Things that could make it even more stand out&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Bonus tips for efficient networking&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 What is professional networking?
&lt;/h2&gt;

&lt;p&gt;Professional networking is the sheer &lt;strong&gt;act of making relationships or acquaintances with the people closely associated with your career&lt;/strong&gt; or in your professional domain. This has a lot of upsides given that we’re living in a social world and we’re all dependent on each other to grow as a community.&lt;/p&gt;

&lt;p&gt;You can think of it as making friends in your first day of school but specifically with people in your area of interest, which will help you grow mutually and learn from each other’s insights.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4a681dpj355rhjq0klr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4a681dpj355rhjq0klr.png" alt="People networking with each other" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤝 Why need a professional network?
&lt;/h2&gt;

&lt;p&gt;A network becomes a part of your life. You should not just network for sake of networking but rather see it as a means to build real deep connections and friendships that go a long way. But still if you’re not convinced to go out of your way to network, think about the countless benefits that can come as a result.&lt;/p&gt;

&lt;h2&gt;
  
  
  💼 Benefits of Professional Networking
&lt;/h2&gt;

&lt;p&gt;Well, in todays day and age every other person is connected to thousands online and they in turn multiply to millions and so on. Thus making your network more and more vast. Imagine hiring as a startup, if you’re networked with hundreds of skilled developers you can gather a team of best engineers with a mere tweet and they in turn can refer few great team workers too!!&lt;/p&gt;

&lt;p&gt;Plus as a human being, &lt;strong&gt;there’s always a need for fresh perspectives&lt;/strong&gt; on your work or in general which your network can play a great role in providing. You &lt;strong&gt;can always get help and share your expertise in your network&lt;/strong&gt; that makes you a better person too. Ultimately at any point of time, we all need advise on our career and lives in general, guess who’ll come to your help?&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Modern day solutions to Professional Networking
&lt;/h2&gt;

&lt;p&gt;I mention modern day, because there are innumerable ways to interact and network with others today. It’s not just one website or mass media, it’s everywhere you go. You can choose to join a professional community (like a meetup group in your area), attend networking events or community conferences (like &lt;a href="https://twitter.com/react_india"&gt;react_india&lt;/a&gt;) to gain more expertise in your domain.&lt;/p&gt;

&lt;p&gt;But provided all of them are high effort 😅 and you might have tendencies to procrastinate, there are solutions that you can use from the comfort of your home. These online social networking platforms were made for one purpose for you to connect with the world but not every social media can be used for professional networking. Thus we have mediums like, Peerlist and LinkedIn etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  📺 Using social media for professional networking
&lt;/h2&gt;

&lt;p&gt;We’ll you asked why this post was called, &lt;strong&gt;future of professional networking&lt;/strong&gt; this is it. Today’s mass communication mediums are not TV and newspaper, they are massive networks like LinkedIn and Twitter. These apps are although very good at too many things but over time have been turned into so much more that it almost feels betraying their primary purpose, connecting people.&lt;/p&gt;

&lt;p&gt;Almost every one reading this must have a LinkedIn at one point of time, but using that platform is a hurdle in itself. Their news feed is dying out of scarcity of legit posts and with no correction mechanism there are bazzilions of other unrelated to &lt;strong&gt;professional&lt;/strong&gt; posts which blows my head.&lt;/p&gt;

&lt;p&gt;A professional network should not only be useful to make connections but also remain ad-free and distraction free platform only meant to genuinely form connections. It should &lt;strong&gt;not only solve a problem of networking but also showcasing&lt;/strong&gt; specific skills that you have, rather than &lt;strong&gt;keeping it tightly knit inside your A4 sized sheet&lt;/strong&gt;. And I don’t have to explain how terrible it is to handover your resumes or links to all your social portfolios, everytime someone asks for it.&lt;/p&gt;

&lt;p&gt;A &lt;del&gt;social media&lt;/del&gt; professional network platform shall care for all of this.&lt;/p&gt;

&lt;h2&gt;
  
  
  💚 Why I love Peerlist?
&lt;/h2&gt;

&lt;p&gt;It is not just a method to connect with people on the internet. It is your homeplace on the internet that can serve as your digital portfolio. I recently signed up to Peerlist (only wishing to try out this brand new platform), but once I made my profile on it I was instantly attracted to its sleek portfolio and multitude of other features.&lt;/p&gt;

&lt;p&gt;After struggling to create my own portfolio and applying modifications a number of times I was convinced that it’s always gonna eat up my time to design and create a portfolio for my own (given that I’m a developer and weak-eyed at design). Nor is it easy to create portfolios that dynamically generates all your work across a dozen platforms like, Medium, Github, &lt;a href="http://Dev.to"&gt;Dev.to&lt;/a&gt; or Hashnode. &lt;/p&gt;

&lt;p&gt;This is why I’m planning to keep using Peerlist from now on and I’m actively sharing my peerlist profile as a resume links to recruiters. It’s all that a modern social network must have, to succeed. &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1570778429787885568-393" src="https://platform.twitter.com/embed/Tweet.html?id=1570778429787885568"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

&lt;p&gt;Wait, did I mention it also &lt;strong&gt;enables you to add people to your private lists&lt;/strong&gt; so you can keep track of whoever you’re connecting with? 🤩&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft1vozxqwmk3axenzfsmc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft1vozxqwmk3axenzfsmc.png" alt="Peerlist group lists feature" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is all the more reason to love this platform even though it’s relatively new to the market! Despite making connections you can interact with them on a &lt;strong&gt;daily scrolls&lt;/strong&gt; (which is a news feed like place) to help share information with others and also apply to &lt;strong&gt;Jobs,&lt;/strong&gt; in the jobs section of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚡ Things that could make it even more stand out
&lt;/h3&gt;

&lt;p&gt;There’s always room to grow and we’re getting aware of new usecases every day, thus there could be some things that could always be improved and will get it to perfection! 🚀&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One to one DMs&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This could help get in touch more personally with your networks. Especially because most parts of networking is just communicating efficiently. This needs to work also so that people can share work with their peers and get that community factor going (also scrolls are already great at this).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As for the most part, a network is build of groups of people and groups of people are gathered by the voice of a community. It’ll be awesome to have that community factor where everyone is motivating one another. This can be like a private group which will have it’s own scroll content (posted by fellow members) or a group chat which allows everyone to catch up on one another.&lt;/p&gt;

&lt;p&gt;Although this can’t be told as the primary necessity of a social network for professionals but, at the building of connections with great bunch of people can really be boosted by those.&lt;/p&gt;

&lt;h2&gt;
  
  
  💁🏻‍♂️ Bonus tips for efficient networking
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Give more than you get&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always be giving. As said by one of famous influencers, Gary Vee, &lt;strong&gt;give more than you get&lt;/strong&gt;. We sometimes get so focused on getting from others that we forget we also need to serve. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ask good questions and be a good listener&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Asking the well prepared questions can help you seek the right kind of information as well as a people need to know that you’re listening to what they’ve to say, else it’s a poor use of their time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep in touch with your network&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Networking is a group activity and a long project not an overnight homework that you complete by pulling in an all nighter. Firstly have patience, every good thing will take time to manifest and do follow up after a meetup is over or if you’ve connected with them long before.&lt;/p&gt;

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

&lt;p&gt;As our elders said, “Rome was not built in a day”, there is no need to worry if you don’t have a half a thousand followers by tomorrow, it’s all about playing the infinite game. If you keep showing up everyday and work towards a common goal, people will notice and start supporting you in due time. Remember build relationships, not connections, it’ll change the way you measure success.&lt;/p&gt;

&lt;p&gt;And with that enjoy your weekend everyone and keep building cool stuff!&lt;/p&gt;

&lt;p&gt;Say hi to me on &lt;a href="https://peerlist.io/heytulsiprasad"&gt;my Peerlist profile&lt;/a&gt;! 👋 Also if you’re interested in frontend development and more technical content, stay tuned at &lt;a href="https://twitter.com/heytulsiprasad"&gt;@heytulsiprasad&lt;/a&gt; on Twitter 🐦&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>career</category>
      <category>peerlist</category>
    </item>
    <item>
      <title>Time traveling with Git Reflog</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Wed, 22 Sep 2021 15:12:38 +0000</pubDate>
      <link>https://dev.to/thebuildguy/time-traveling-with-git-reflog-2f15</link>
      <guid>https://dev.to/thebuildguy/time-traveling-with-git-reflog-2f15</guid>
      <description>&lt;p&gt;It's 2021 and I still used to fear before running those pesky git commands, &lt;code&gt;git reset --hard&lt;/code&gt; yet another time. Each time I kept a copy of my local branch and even tried having two different projects to avoid silly shenanigans. But eventually, apart from adding tiring overhead, it made me type a bunch more keys than required which I was pretty OCD about.&lt;/p&gt;

&lt;p&gt;Then I discovered, &lt;a href="https://twitter.com/search?q=git%20reflog&amp;amp;src=typed_query&amp;amp;f=top" rel="noopener noreferrer"&gt;git reflog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Concept&lt;/li&gt;
&lt;li&gt;Usage&lt;/li&gt;
&lt;li&gt;
Advanced use cases

&lt;ul&gt;
&lt;li&gt;Access reflogs by time&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Aversing risk with Reflogs

&lt;ul&gt;
&lt;li&gt;Example&lt;/li&gt;
&lt;li&gt;Using Reflog to revive newer files&lt;/li&gt;
&lt;li&gt;Force pushing branches after rebase&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;For more references&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;/ul&gt;




&lt;h1&gt;
  
  
  Concept
&lt;/h1&gt;

&lt;p&gt;Git is very good at keeping track of changes that are happening to its HEAD. So each you do things commonly including, &lt;code&gt;git commit&lt;/code&gt;, &lt;code&gt;git merge&lt;/code&gt; or &lt;code&gt;git reset&lt;/code&gt; it tracks it using &lt;strong&gt;reference logs&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Every time your branch tip is updated, git automatically stores a ref of that information for you. But mind that, this is temporary storage. You can only reference your history up to a certain point (~3 months) so it's not always reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;It's as simple as it sounds. You can see your reflog using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git reflog

3844466 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; main, origin/main&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;: merge refs/remotes/origin/main: Fast-forward
f7acb57 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;: checkout: moving from feat-c to main
fc859f8 &lt;span class="o"&gt;(&lt;/span&gt;origin/feat-c, feat-c&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;: commit: Add c
f7acb57 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;3&lt;span class="o"&gt;}&lt;/span&gt;: checkout: moving from main to feat-c
f7acb57 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;4&lt;span class="o"&gt;}&lt;/span&gt;: pull: Fast-forward
6932227 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;5&lt;span class="o"&gt;}&lt;/span&gt;: checkout: moving from feat-b to main
07087ce &lt;span class="o"&gt;(&lt;/span&gt;origin/feat-b, feat-b&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;6&lt;span class="o"&gt;}&lt;/span&gt;: commit: add b
6932227 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;7&lt;span class="o"&gt;}&lt;/span&gt;: checkout: moving from main to feat-b
6932227 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;8&lt;span class="o"&gt;}&lt;/span&gt;: Branch: renamed refs/heads/master to refs/heads/main
6932227 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;10&lt;span class="o"&gt;}&lt;/span&gt;: commit &lt;span class="o"&gt;(&lt;/span&gt;initial&lt;span class="o"&gt;)&lt;/span&gt;: added a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: References are local to each user, it'll only contain changes that you make on your local copy of the repository&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see each ref has the commit ID, we can use this to see what the state was like at that point in time and if need be, can also jump to that specific point altogether.&lt;/p&gt;

&lt;p&gt;You can see constituents of a reference using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git show HEAD@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;

commit fc859f87f8af7e7eaea88280b8ff5c5406920581 &lt;span class="o"&gt;(&lt;/span&gt;origin/feat-c, feat-c&lt;span class="o"&gt;)&lt;/span&gt;
Author: Tulsi Prasad &amp;lt;heytulsiprasad@gmail.com&amp;gt;
Date:   Sat Sep 18 09:33:41 2021 +0530

    Add c

diff &lt;span class="nt"&gt;--git&lt;/span&gt; a/c.js b/c.js
new file mode 100644
index 0000000..76fbf09
&lt;span class="nt"&gt;---&lt;/span&gt; /dev/null
+++ b/c.js
@@ &lt;span class="nt"&gt;-0&lt;/span&gt;,0 +1 @@
+console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"c was here"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Alternatively, you can either use the commit ID or relative notations of HEAD too.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More on knowing various &lt;a href="https://medium.com/@gabicle/git-ancestry-references-explained-bd3a84a0b821" rel="noopener noreferrer"&gt;relative notations using HEAD&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced use cases
&lt;/h2&gt;

&lt;p&gt;Along with tips of HEADs, git also keeps track of stashes, other branches, tags, remotes via references too. But by default &lt;code&gt;git reflog&lt;/code&gt; only shows the reflog of HEAD ref. HEAD is always the tip of the current branch.&lt;/p&gt;

&lt;p&gt;Thus when you run, &lt;code&gt;git reflog&lt;/code&gt; it implicitly means &lt;code&gt;git reflog show HEAD&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;To see reflog of the entire project, use &lt;code&gt;git reflog --all&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can use reflogs for stash as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git reflog show stash

f0c040c &lt;span class="o"&gt;(&lt;/span&gt;refs/stash&lt;span class="o"&gt;)&lt;/span&gt; stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;: WIP on feat-e: f0082bb add d
29e2513 stash@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;: WIP on feat-e: f0082bb add d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: You have to have used git stash before in your project to see the reflogs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Similarly you can track the origin branches like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git reflog show origin/main

3844466 &lt;span class="o"&gt;(&lt;/span&gt;origin/main&lt;span class="o"&gt;)&lt;/span&gt; refs/remotes/origin/main@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;: fetch origin: fast-forward
f7acb57 refs/remotes/origin/main@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;: pull: fast-forward
6932227 refs/remotes/origin/main@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;: update by push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Access reflogs by time
&lt;/h3&gt;

&lt;p&gt;Reflogs also have a time of the executed command attached to it, so you can basically leverage this to see the difference in history between any two points. &lt;/p&gt;

&lt;p&gt;Some default time strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.minute.ago
1.hour.ago
1.day.ago or yesterday
1.week.ago
1.month.ago
1.year.ago
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using them to see the diff:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git diff HEAD@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;4.hours.ago&lt;span class="o"&gt;}&lt;/span&gt;

diff &lt;span class="nt"&gt;--git&lt;/span&gt; a/d.js b/d.js
deleted file mode 100644
index 81fe3ac..0000000
&lt;span class="nt"&gt;---&lt;/span&gt; a/d.js
+++ /dev/null
@@ &lt;span class="nt"&gt;-1&lt;/span&gt; +0,0 @@
&lt;span class="nt"&gt;-console&lt;/span&gt;.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"d was here"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="se"&gt;\ &lt;/span&gt;No newline at end of file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So this implies as reflogs keep track of all your changes to the tip, like merge, rebase, reset, etc thus all your commits are safely kept inside reflog even after you get rid of them. Although this by default stores for (~90 days), you can manually update that.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aversing risk with Reflogs
&lt;/h1&gt;

&lt;p&gt;Now that you've known much already about conventions of reflog, now we can discuss how you can make it your safety net and use Git super-confidently all the time.&lt;/p&gt;

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

&lt;p&gt;Git Reset has been the bermuda triangle of commits for me, especially when I used to copy-paste commands from StackOverflow (please don't do that). &lt;/p&gt;

&lt;p&gt;Let's say this is my log at one point in time and for some reason I decided to go back where I had just a as only file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;

&lt;span class="k"&gt;*&lt;/span&gt; 724281a &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; add d
&lt;span class="k"&gt;*&lt;/span&gt; cf20425 add c
&lt;span class="k"&gt;*&lt;/span&gt; e1f07f6 add b
&lt;span class="k"&gt;*&lt;/span&gt; 4037ca4 add a

&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; 4037ca4
HEAD is now at 4037ca4 add a

&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt; 4037ca4 add a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Using Reflog to revive newer files&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git reflog

4037ca4 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;: reset: moving to 4037ca4
724281a HEAD@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;: commit: add d
cf20425 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;: commit: add c
e1f07f6 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;3&lt;span class="o"&gt;}&lt;/span&gt;: commit: add b
4037ca4 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;4&lt;span class="o"&gt;}&lt;/span&gt;: commit &lt;span class="o"&gt;(&lt;/span&gt;initial&lt;span class="o"&gt;)&lt;/span&gt;: add a

&lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;
HEAD is now at 724281a add d

&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;

&lt;span class="k"&gt;*&lt;/span&gt; 724281a &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; master&lt;span class="o"&gt;)&lt;/span&gt; add d
&lt;span class="k"&gt;*&lt;/span&gt; cf20425 add c
&lt;span class="k"&gt;*&lt;/span&gt; e1f07f6 add b
&lt;span class="k"&gt;*&lt;/span&gt; 4037ca4 add a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As simple as that. 🤷‍♂️&lt;/p&gt;

&lt;h3&gt;
  
  
  Force pushing branches after rebase
&lt;/h3&gt;

&lt;p&gt;A few days back there was a tweet on why you should keep your branch's backup before rebasing and I instantly knew what can be done, as I was halfway through the post lol 🤣. So here's a common use case you can avoid with reflog.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1438869955517186052-513" src="https://platform.twitter.com/embed/Tweet.html?id=1438869955517186052"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

&lt;p&gt;Ideally, force pushes are not recommended but when you rewrite your history (knowingly), this leaves us with this only option. However, in case this leads to breaking changes and you want your previous state of repo back, you know where I'm going with this.&lt;/p&gt;

&lt;p&gt;Hopefully, you don't need to read anymore, if you've come all the way. I'd like you to continue when you've thought of a solution in your head.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/dev/git-ref &lt;span class="o"&gt;(&lt;/span&gt;ijkl&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
e4719d6 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; ijkl, origin/ijkl&lt;span class="o"&gt;)&lt;/span&gt; add l
87552ac add k
63841dc add j
0446b52 add i
724281a &lt;span class="o"&gt;(&lt;/span&gt;origin/master, master&lt;span class="o"&gt;)&lt;/span&gt; add d
cf20425 add c
e1f07f6 add b
4037ca4 add a

~/Desktop/dev/git-ref &lt;span class="o"&gt;(&lt;/span&gt;ijkl&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~4
hint: Waiting &lt;span class="k"&gt;for &lt;/span&gt;your editor to close the file... 
hint: Waiting &lt;span class="k"&gt;for &lt;/span&gt;your editor to close the file... 
&lt;span class="o"&gt;[&lt;/span&gt;detached HEAD 1c7df0b] add ijkl
 Date: Sun Sep 19 16:56:54 2021 +0530
 3 files changed, 3 insertions&lt;span class="o"&gt;(&lt;/span&gt;+&lt;span class="o"&gt;)&lt;/span&gt;
 create mode 100644 i.txt
 create mode 100644 j.txt
 create mode 100644 l.txt
Successfully rebased and updated refs/heads/ijkl.

~/Desktop/dev/git-ref &lt;span class="o"&gt;(&lt;/span&gt;ijkl&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git push &lt;span class="nt"&gt;-f&lt;/span&gt;
Enumerating objects: 6, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Counting objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;6/6&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Delta compression using up to 8 threads
Compressing objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;2/2&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Writing objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;5/5&lt;span class="o"&gt;)&lt;/span&gt;, 423 bytes | 423.00 KiB/s, &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
Total 5 &lt;span class="o"&gt;(&lt;/span&gt;delta 0&lt;span class="o"&gt;)&lt;/span&gt;, reused 0 &lt;span class="o"&gt;(&lt;/span&gt;delta 0&lt;span class="o"&gt;)&lt;/span&gt;, pack-reused 0
To https://github.com/heytulsiprasad/git-ref.git
 + e4719d6...1c7df0b ijkl -&amp;gt; ijkl &lt;span class="o"&gt;(&lt;/span&gt;forced update&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See above, I created four commits and rebased them to squash them into one before making the PR. But I accidentally dropped a commit &lt;code&gt;add k&lt;/code&gt; which had &lt;code&gt;k.txt&lt;/code&gt; file in it. But I've already force-pushed the commits to remote.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/dev/git-ref &lt;span class="o"&gt;(&lt;/span&gt;ijkl&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--name-status&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
commit 1c7df0b3fbeb46dfafb19fb5740ecac19f1a470a &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; ijkl, origin/ijkl&lt;span class="o"&gt;)&lt;/span&gt;
Author: Tulsi Prasad &amp;lt;tulsi.prasad50@gmail.com&amp;gt;
Date:   Sun Sep 19 16:56:54 2021 +0530

    add ijkl

A       i.txt
A       j.txt
A       l.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's do some disaster management.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/Desktop/dev/git-ref &lt;span class="o"&gt;(&lt;/span&gt;ijkl&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git reflog
1c7df0b &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; ijkl, origin/ijkl&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;: rebase &lt;span class="o"&gt;(&lt;/span&gt;finish&lt;span class="o"&gt;)&lt;/span&gt;: returning to refs/heads/ijkl
1c7df0b &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; ijkl, origin/ijkl&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;1&lt;span class="o"&gt;}&lt;/span&gt;: rebase &lt;span class="o"&gt;(&lt;/span&gt;squash&lt;span class="o"&gt;)&lt;/span&gt;: add ijkl
cb62728 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;: rebase &lt;span class="o"&gt;(&lt;/span&gt;squash&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="c"&gt;# This is a combination of 2 commits.&lt;/span&gt;
0446b52 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;3&lt;span class="o"&gt;}&lt;/span&gt;: rebase &lt;span class="o"&gt;(&lt;/span&gt;start&lt;span class="o"&gt;)&lt;/span&gt;: checkout HEAD~4
e4719d6 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;4&lt;span class="o"&gt;}&lt;/span&gt;: commit: add l
87552ac HEAD@&lt;span class="o"&gt;{&lt;/span&gt;5&lt;span class="o"&gt;}&lt;/span&gt;: commit: add k
63841dc HEAD@&lt;span class="o"&gt;{&lt;/span&gt;6&lt;span class="o"&gt;}&lt;/span&gt;: commit: add j
0446b52 HEAD@&lt;span class="o"&gt;{&lt;/span&gt;7&lt;span class="o"&gt;}&lt;/span&gt;: commit: add i
724281a &lt;span class="o"&gt;(&lt;/span&gt;origin/master, master&lt;span class="o"&gt;)&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;8&lt;span class="o"&gt;}&lt;/span&gt;: checkout: moving from master to ijkl

~/Desktop/dev/git-ref &lt;span class="o"&gt;(&lt;/span&gt;ijkl&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; HEAD@&lt;span class="o"&gt;{&lt;/span&gt;4&lt;span class="o"&gt;}&lt;/span&gt;
HEAD is now at e4719d6 add l

~/Desktop/dev/git-ref &lt;span class="o"&gt;(&lt;/span&gt;ijkl&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
e4719d6 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; ijkl&lt;span class="o"&gt;)&lt;/span&gt; add l
87552ac add k
63841dc add j
0446b52 add i
724281a &lt;span class="o"&gt;(&lt;/span&gt;origin/master, master&lt;span class="o"&gt;)&lt;/span&gt; add d
cf20425 add c
e1f07f6 add b
4037ca4 add a
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how you can get your most important &lt;code&gt;k.txt&lt;/code&gt; file back and leave work each day like an absolute winner. 😅&lt;/p&gt;

&lt;h1&gt;
  
  
  For more references
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;For more tragic &lt;a href="https://ohshitgit.com/" rel="noopener noreferrer"&gt;fuckups&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Atlassian has a nice article on &lt;a href="https://www.atlassian.com/git/tutorials/rewriting-history/git-reflog" rel="noopener noreferrer"&gt;reflog&lt;/a&gt; too&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Not all disasters can be avoided but knowing the ones that can is better than nothing. This reminds me of a quote from Picasso, “Learn the rules like a pro, so you can break them like an artist”. Tweet me your favorite git tricks that saved your day for real. You'll find me &lt;a href="https://twitter.com/thebuildguy/" rel="noopener noreferrer"&gt;@thebuildguy&lt;/a&gt; on Twitter.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Huge thanks to &lt;a href="https://twitter.com/_SreetamDas" rel="noopener noreferrer"&gt;Sreetam Das&lt;/a&gt;, &lt;a href="https://twitter.com/PrathamKrishna3" rel="noopener noreferrer"&gt;Pratham Krishna&lt;/a&gt;, and &lt;a href="https://twitter.com/ExplorerAadi" rel="noopener noreferrer"&gt;Aditya Raj&lt;/a&gt; for reviewing this post beforehand, it really helped to make this post better.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Making your console log statements stand out</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Thu, 15 Jul 2021 16:20:31 +0000</pubDate>
      <link>https://dev.to/thebuildguy/making-your-console-log-statements-stand-out-449n</link>
      <guid>https://dev.to/thebuildguy/making-your-console-log-statements-stand-out-449n</guid>
      <description>&lt;p&gt;Yes, the above image is from the console and you can customize the text however you like. To know how keep reading till the end.&lt;/p&gt;

&lt;p&gt;It's been a while since my last post, it's because I got into learning some interesting stuff and undoubtedly writer's block was back. But recently, while working on a large repository that had a lot of stuff logged in the console I wanted a way to clear all the clutter and make my console statements stand out from the rest.&lt;/p&gt;

&lt;p&gt;Here is how I was able to do that and how you could too.&lt;/p&gt;

&lt;p&gt;So these are the possible options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using different console methods&lt;/li&gt;
&lt;li&gt;Using various format specifiers (believe me, this is magic ✨)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using different console methods
&lt;/h2&gt;

&lt;p&gt;You might already know some of the basic ones, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;console.log&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;console.info&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;console.error&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;console.warn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But some of the more cool ones, are:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;console.table&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This can be used to log large nested objects or arrays so you don't have to go through expanding each key to view the whole thing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;peoples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Richard Hendricks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Berkely&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4254-024-8162&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Christiansen Frederikke&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Madras&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4987-024-2562&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;34&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;California&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3143-344-342&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;peoples&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftck0mbsrmu9efvob7nn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftck0mbsrmu9efvob7nn9.png" alt="Logging arrays into console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also log objects as such:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjax2iox28dz6bw95t2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwjax2iox28dz6bw95t2r.png" alt="Logging objects into console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;console.group&lt;/code&gt; and &lt;code&gt;console.groupEnd&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;You can group a set of console logs having a particular meaning apart from the rest using this method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Me and my boys&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;peoples&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Weather is very beautiful today ☁&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Don't fall for the beautiful weather&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what it'll return:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzu88z9mqt2rwli2626se.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzu88z9mqt2rwli2626se.png" alt="Demostration of console group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Use &lt;code&gt;console.groupCollapsed()&lt;/code&gt; to have the logs closed by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;console.time()&lt;/code&gt; and &lt;code&gt;console.timeEnd()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If at all you're ever interested to know how much time a particular block of code takes to run, you can achieve this using &lt;code&gt;console.time()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Zzzz!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeEnd&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4t21ckmdkx3t51bn1s26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4t21ckmdkx3t51bn1s26.png" alt="Demonstration of console time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;console.count(label)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;It logs incrementing counter values starting from 0. You can use &lt;code&gt;label&lt;/code&gt; to distinguish between different counters. To stop one from counting above, you've to use &lt;code&gt;console.countReset(label)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awesome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Awesome: 1&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awesome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Awesome: 2&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awesome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Awesome: 3&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awesome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Awesome: 4&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;countReset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awesome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awesome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Awesome: 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using format specifiers
&lt;/h2&gt;

&lt;p&gt;Believe it or not, console logs can be more than just simple messages. You can include an eye-catching message or something more convincing as your favorite dog image.&lt;/p&gt;

&lt;p&gt;All because you can use format specifiers inside them. How?&lt;/p&gt;

&lt;h3&gt;
  
  
  List of available format specifiers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;%s ⇒ Formats as string&lt;/li&gt;
&lt;li&gt;%i ⇒ Formats as integer&lt;/li&gt;
&lt;li&gt;%f ⇒ Formats as float&lt;/li&gt;
&lt;li&gt;%O ⇒ Formats as object (yes that's capital O as in Oregano)&lt;/li&gt;
&lt;li&gt;%o ⇒ Formats as DOM element&lt;/li&gt;
&lt;li&gt;%c ⇒ Formats as CSS ✨&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Formats as string, integer, float
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%s, told me that we're going to mall today with %s&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mike&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Alan, told me that we're going to mall today with Mike&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;We had %i mangoes today&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;56&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// We had 56 mangoes today&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Did you know, Tesla Model S can reach 0 to 60 mph in %f seconds?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mf"&gt;2.3&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Did you know, Tesla Model S can reach 0 to 60 mph in 2.3 seconds?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Formats as Object
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F529hqaizkr2632k82cy2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F529hqaizkr2632k82cy2.png" alt="Demonstration of using %O format specifier in console logs for objects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Formats as DOM Element
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bisb43uebsjsdivfdx2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bisb43uebsjsdivfdx2.png" alt="Demonstration of using %o format specifier in console logs for DOM elements"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Formats as CSS
&lt;/h3&gt;

&lt;p&gt;Adding your CSS to the second argument of console log by separating each of them with &lt;code&gt;;&lt;/code&gt; does the trick.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cThis is actually very interesting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color: yellow; font-size: 35px; background-color: red;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57xn436h7iu2q774v9j8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57xn436h7iu2q774v9j8.png" alt="Demonstration of using styles in console log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also add multiple styles in the same log by using multiple %c specifiers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cThis is actually %cvery interesting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color: blue; font-size: 55px; background-color: yellow;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size: 55px; background-color: blue; color: yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2ek1vlonsr015xizlwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2ek1vlonsr015xizlwa.png" alt="Demonstration of using multiple style format specifer in single log"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If that looks a bit messy and you have a lot of styles to give you can put the styles in a separate array and use them wisely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;blackBackground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size: 50px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-color: black&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color: white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; ;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;whiteBackground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size: 50px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-color: white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color: black&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; ;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cAwesome stuff is %ccoming your way&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;blackBackground&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;whiteBackground&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmbamval6j5486j885gh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmbamval6j5486j885gh.png" alt="Demonstration of using multi styles with join helper in console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not the least, a picture says a thousand words.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;backgroundImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-image: url(https://source.unsplash.com/random/1200x800)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-size: cover&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color: hotpink&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;padding: 100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-weight: bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size: 25px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; ;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cPicture says a thousand words&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;backgroundImage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3meg1y1mfhpi1c7k1yi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3meg1y1mfhpi1c7k1yi.png" alt="Demonstration of console log with text on image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can do all sorts of manipulation and get more creative with the power of CSS, it's up to you.&lt;/p&gt;

&lt;p&gt;If you're still wondering how the above banner was made, well here's that code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;backgroundImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-image: url(https://i.pinimg.com/originals/5b/43/02/5b4302c2f6413454c782aeec866143cf.gif)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background-size: cover&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;color: black&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;padding: 100px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-weight: bolder&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size: 40px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-webkit-text-stroke-width: 1px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-webkit-text-stroke-color: yellow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-transform: uppercase&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-align: center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;letter-spacing: 1px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; ;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;%cMay the force be with you&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;backgroundImage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;That's it, super easy! 😃&lt;/p&gt;

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

&lt;p&gt;For me, all that mattered was for the logs to stand out and be more catchy on pursuit of which I found out a ton of more cool stuff we can do, hope this gives you more clarity on the gem of a function, that console is.&lt;/p&gt;

&lt;p&gt;Catch more updates on &lt;a href="https://twitter.com/heytulsiprasad" rel="noopener noreferrer"&gt;@heytulsiprasad&lt;/a&gt; 👋&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>I made a chrome extension that helps you slack off in your Google Meet meetings</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Mon, 12 Oct 2020 07:49:43 +0000</pubDate>
      <link>https://dev.to/thebuildguy/i-made-a-chrome-extension-that-helps-you-slack-off-in-your-google-meet-meetings-2gb2</link>
      <guid>https://dev.to/thebuildguy/i-made-a-chrome-extension-that-helps-you-slack-off-in-your-google-meet-meetings-2gb2</guid>
      <description>&lt;h1&gt;
  
  
  🎉 Alert Me for Google Meet
&lt;/h1&gt;

&lt;p&gt;A Chrome Extension that notifies people when certain words are being spoken in a Google Meet Meeting opened in Chrome browser. You can set the alert words yourself with your name or any word you want to be notified for. Use it to your own advantage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This doesn't recognize the voice in the meeting by itself, that's done by Google when you turn your captions on, so if it doesn't work as shown here, try checking if your voice is recognized by Google&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://camo.githubusercontent.com/db2bb800c1156fc9ff5f656a40c32550980b2855/68747470733a2f2f692e696d6775722e636f6d2f37456a446375522e706e67" class="article-body-image-wrapper"&gt;&lt;img src="https://camo.githubusercontent.com/db2bb800c1156fc9ff5f656a40c32550980b2855/68747470733a2f2f692e696d6775722e636f6d2f37456a446375522e706e67" alt="Alert Me Popup Home"&gt;&lt;/a&gt;&lt;/p&gt;
Popup interface to add/remove alert words



&lt;p&gt;&lt;a href="https://camo.githubusercontent.com/5dcb613cb8691e3b0a66eda8433e935afe3f997c/68747470733a2f2f692e696d6775722e636f6d2f6c3634517847482e706e67" class="article-body-image-wrapper"&gt;&lt;img src="https://camo.githubusercontent.com/5dcb613cb8691e3b0a66eda8433e935afe3f997c/68747470733a2f2f692e696d6775722e636f6d2f6c3634517847482e706e67" alt="Notifications as they appear"&gt;&lt;/a&gt;&lt;/p&gt;
Notifications appear when those words are spoken in meeting



&lt;h1&gt;
  
  
  Motivation (User Story)
&lt;/h1&gt;

&lt;p&gt;This is a pet project I made to know how Chrome extensions work (which proved to be very valuable 😅). You can use it at your own risk, as if you get caught while slacking off at work meetings, I won't be held responsible.&lt;/p&gt;

&lt;h1&gt;
  
  
  Instructions
&lt;/h1&gt;

&lt;p&gt;It's pretty simple, feel free to follow below steps if you get stuck:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Join a Google Meet call&lt;/li&gt;
&lt;li&gt;Add/remove alert words through the popup&lt;/li&gt;
&lt;li&gt;Make sure to &lt;strong&gt;Turn on your captions&lt;/strong&gt; for extension to know when words are spoken&lt;/li&gt;
&lt;li&gt;You'll get a notification when someone speaks your alert words&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  URLs
&lt;/h1&gt;

&lt;p&gt;This extension isn't live on Chrome Web store yet (coz my card isn't accepted by it for paying of the registration amount). So you can download latest release from GitHub itself. Follow the README.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub
&lt;/h2&gt;

&lt;p&gt;Do ⭐ the repository!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/heytulsiprasad" rel="noopener noreferrer"&gt;
        heytulsiprasad
      &lt;/a&gt; / &lt;a href="https://github.com/heytulsiprasad/alert-me-google-meet" rel="noopener noreferrer"&gt;
        alert-me-google-meet
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Detects live captioning in Google Meet conference to notify you when specific words are spoken
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Alert Me - Google Meet&lt;/h1&gt;
&lt;/div&gt;
&lt;a href="https://github.com/heytulsiprasad/alert-me-google-meet/issues" rel="noopener noreferrer"&gt;
  &lt;img alt="Issues" src="https://camo.githubusercontent.com/3471f4fc5cec10e22063316cfc9ea8d48144710ec5bfb11f5ffa5319b463b56c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f68657974756c73697072617361642f616c6572742d6d652d676f6f676c652d6d6565743f636f6c6f723d303038386666"&gt;
&lt;/a&gt;
&lt;a href="https://github.com/heytulsiprasad/alert-me-google-meet/issues" rel="noopener noreferrer"&gt;
  &lt;img alt="Contributions" src="https://camo.githubusercontent.com/b20f68f697b27055937e1f8238eec47e2cb37f5fc74960da5dfbfe40e04af19a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6e747269627574696f6e732d77656c636f6d652d627269676874677265656e2e737667"&gt;
&lt;/a&gt;
&lt;a href="https://www.gnu.org/licenses/gpl-3.0" rel="nofollow noopener noreferrer"&gt;
  &lt;img alt="License" src="https://camo.githubusercontent.com/8a398fc9fbf479a323d2d91b9fcb6fb9c6b4d08e96dbb544488ccbed312115fc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c76332d626c75652e737667"&gt;
&lt;/a&gt;
&lt;br&gt;
&lt;p&gt;A Chrome Extension that notifies people when certain words are being spoken in a Google Meet Meeting opened in Chrome browser. You can set the alert words yourself with your name or any word you want to be notified for. Use it to your own advantage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This doesn't recognize the voice in the meeting by itself, that's done by Google when you turn your captions on, so if it doesn't work as shown here, try checking if your voice is recognized by Google&lt;/strong&gt;.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/405d7411b8d709a4f2ab6ba928359a643404fe8fff44c30e3485cbb384a53cf2/68747470733a2f2f692e696d6775722e636f6d2f37456a446375522e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/405d7411b8d709a4f2ab6ba928359a643404fe8fff44c30e3485cbb384a53cf2/68747470733a2f2f692e696d6775722e636f6d2f37456a446375522e706e67" alt="Success Home Popup"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Popup interface to add/remove alert words&lt;/p&gt;



&lt;p&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/500650dbb9b05458977b56e8fd5076511bb0e8176912fa684a11ed9d0f05827e/68747470733a2f2f692e696d6775722e636f6d2f6c3634517847482e706e67"&gt;&lt;img src="https://camo.githubusercontent.com/500650dbb9b05458977b56e8fd5076511bb0e8176912fa684a11ed9d0f05827e/68747470733a2f2f692e696d6775722e636f6d2f6c3634517847482e706e67" alt="Notifications in Windows"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Notifications appear when those words are spoken in meeting&lt;/p&gt;



&lt;p&gt;⚠️ The app is in pre-release now, so feel free test it and create some issues so we can make it bulletproof before publishing on the chrome store.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Motivation (User Story)&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;This is a pet project I made to know how Chrome extensions work (which proved…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/heytulsiprasad/alert-me-google-meet" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h2&gt;
  
  
  Twitter
&lt;/h2&gt;

&lt;p&gt;Don't forget to share it with your Twitter fam! 🕺🏻&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1314541624068722688-413" src="https://platform.twitter.com/embed/Tweet.html?id=1314541624068722688"&gt;
&lt;/iframe&gt;

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



&lt;/p&gt;

&lt;p&gt;Thanks for reading! &lt;strong&gt;Let me know your thoughts in comments.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have a nice day and take care! 💙&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>chrome</category>
      <category>javascript</category>
      <category>extension</category>
    </item>
    <item>
      <title>Uploading media assets from React using Cloudinary</title>
      <dc:creator>Tulsi Prasad</dc:creator>
      <pubDate>Sun, 04 Oct 2020 14:25:30 +0000</pubDate>
      <link>https://dev.to/thebuildguy/uploading-media-assets-from-react-using-cloudinary-4n4o</link>
      <guid>https://dev.to/thebuildguy/uploading-media-assets-from-react-using-cloudinary-4n4o</guid>
      <description>&lt;p&gt;Hey everyone! In today's standards, it's not uncommon to see every other website has some kind of visual content by themselves or for the user to upload. And keeping factors such as performance, rich image optimization it becomes even difficult to handle all of it using built in techniques. That's the problem &lt;a href="https://cloudinary.com/"&gt;Cloudinary&lt;/a&gt; solves almost perfectly, thus we'll see how to implement it in our React app ecosystem.&lt;/p&gt;

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

&lt;p&gt;I usually don't like making examples just for blogs (as they're time consuming) but I like showing real projects that I worked on and how I implemented it in my project.&lt;/p&gt;

&lt;p&gt;Speaking of, last week I made &lt;a href="https://talk-to.vercel.app/"&gt;this app&lt;/a&gt; to learn about authentication, where you can create your account (OAuth/Local) and edit your info, like image and name, so I liked to try out Cloudinary. You can tap &lt;em&gt;Change Photo&lt;/em&gt; (on edit page) to add your photos, this is handled by Cloudinary in React itself. You can find it on my GitHub. (&lt;a href="https://github.com/heytulsiprasad/talkto-frontend"&gt;talkto-frontend&lt;/a&gt; and &lt;a href="https://github.com/heytulsiprasad/talkto-backend"&gt;talkto-backend&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8w20nskthzdtzy70ryvz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8w20nskthzdtzy70ryvz.png" alt="Home page of Talk to" width="800" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftxhjusbp7z2tr0oovhuf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftxhjusbp7z2tr0oovhuf.png" alt="Edit page of Talk to" width="800" height="710"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Do you have a Cloudinary Account?
&lt;/h1&gt;

&lt;p&gt;You can create a free account on Cloudinary, &lt;a href="https://cloudinary.com/users/register/free"&gt;here&lt;/a&gt;. I'll show how to setup your project on there with screenshots below.&lt;/p&gt;

&lt;h1&gt;
  
  
  Creating the Markup
&lt;/h1&gt;

&lt;p&gt;So to upload any file from the frontend, we need to have an &lt;code&gt;input&lt;/code&gt; tag with type equals to &lt;code&gt;file&lt;/code&gt;. Then we'll pass the file inside a &lt;code&gt;FormData&lt;/code&gt; object and make the post request to our Cloudinary endpoint (we'll see how to get one below).&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;InputFieldImage&lt;/code&gt; is a child (presentational) component which contains our &lt;code&gt;input&lt;/code&gt; tags and all the values are passed to it from its stateful parent component. &lt;a href="https://github.com/heytulsiprasad/talkto-frontend/blob/master/src/components/Profile/InputFieldImage.jsx#L62-L67"&gt;Link to source.&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;InputFieldImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FieldContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ImageFieldContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"upload-image"&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Person Profile"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"material-icons input-icon"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;camera_alt&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt; &lt;span class="na"&gt;htmlFor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ImageFieldContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;FieldContainer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the how &lt;code&gt;InputFieldImage&lt;/code&gt; is called from its stateful parent component. &lt;a href="https://github.com/heytulsiprasad/talkto-frontend/blob/master/src/components/Profile/EditInfo.jsx#L138-L145"&gt;Link to source.&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InputFieldImage&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Change Photo"&lt;/span&gt;
  &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"upload-photo"&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;
  &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"image/png, image/jpeg"&lt;/span&gt;
  &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageChangeHandler&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now all we need to care about is that onChange handler, &lt;code&gt;imageChangeHandler&lt;/code&gt;, which goes like this. You can display beautiful toasts using the &lt;code&gt;imageError&lt;/code&gt; dialogs we've provided, to increase user experience. &lt;a href="https://github.com/heytulsiprasad/talkto-frontend/blob/master/src/components/Profile/EditInfo.jsx#L90-L113"&gt;Link to source.&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;imageChangeHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;imageFile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;imageError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please select image. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;imageFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;jpg|jpeg|png|gif&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;imageError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please select a valid image.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Utils function&lt;/span&gt;
  &lt;span class="nf"&gt;imageUpload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;imageUpload&lt;/code&gt; is an utils function that handles the post request work to Cloudinary and then runs our &lt;code&gt;this.setState&lt;/code&gt; inside its callback which then passes the fetched image url as a prop to &lt;code&gt;InputFieldImage&lt;/code&gt; component. This is how our image is displayed on the box after its uploaded.&lt;/p&gt;

&lt;h1&gt;
  
  
  Getting the Cloudinary Endpoint
&lt;/h1&gt;

&lt;p&gt;Once you logged in, this is how you're dashboard will look like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhy5n4ub6x8bh4x7bdwlj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhy5n4ub6x8bh4x7bdwlj.png" alt="Cloudinary Dashboard" width="800" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And your endpoint will be something in terms of this: &lt;a href="https://api.cloudinary.com/v1_1/:cloud_name/:action"&gt;&lt;code&gt;https://api.cloudinary.com/v1_1/:cloud_name/:action&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our action here would be &lt;code&gt;/image/upload&lt;/code&gt; as we're uploading images and cloud name will be as shown in your dashboard.&lt;/p&gt;

&lt;p&gt;One last thing we need is an upload preset, which we'll pass with our &lt;code&gt;FormData&lt;/code&gt; object, it'll define default behavior of your uploads. You can create/get one inside &lt;strong&gt;Settings →&lt;/strong&gt; &lt;strong&gt;Upload&lt;/strong&gt; then scroll down to upload presets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxy4doov3si1gw7w8n0u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxy4doov3si1gw7w8n0u2.png" alt="Upload Preset screenshot" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're creating one, you can select signing mode as &lt;strong&gt;Unsigned&lt;/strong&gt;. This will allow you to perform uploads directly from the browser without going through your servers. Once it's done, hit save and you're preset name will appear as shown above.&lt;/p&gt;

&lt;h1&gt;
  
  
  Making the upload request
&lt;/h1&gt;

&lt;p&gt;As discussed, we need to create our &lt;code&gt;imageUpload&lt;/code&gt; utils function now. &lt;a href="https://github.com/heytulsiprasad/talkto-frontend/blob/master/src/utils/imageUpload.js"&gt;Link to Source&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;axios&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;imageUpload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imageFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;upload_preset&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_CLOUDINARY_UPLOAD_PRESET&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;axios&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;`https://api.cloudinary.com/v1_1/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_CLOUDINARY_CLOUD_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/image/upload`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;formData&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secure_url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;imageUpload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function takes, &lt;code&gt;imageFile&lt;/code&gt; from our component and the &lt;code&gt;upload_preset&lt;/code&gt; we get above, then appends it to the FormData object which is then passed along with the post request to our endpoint. We also pass a &lt;code&gt;callback&lt;/code&gt; function that is called after the image link is obtained, where the state is changed and new image link is passed on as prop to &lt;code&gt;InputFieldImage&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cloudinary Upload Widget
&lt;/h1&gt;

&lt;p&gt;This is a great feature that you can take advantage of. It shows an upload widget which allows you to upload files from various sources, like Dropbox or Google Drive. You can also add it to your project according to requirements. You can refer &lt;a href="https://cloudinary.com/documentation/upload_widget"&gt;the official docs&lt;/a&gt; or &lt;a href="https://medium.com/@jordanmmartin/quickstart-guide-to-using-cloudinary-upload-widget-v2-in-react-4c4d9041d55e"&gt;this blog&lt;/a&gt; for clarification with React.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuor0madxtim71memz7ch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuor0madxtim71memz7ch.png" alt="Cloudinary Image Upload Widget" width="800" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although I haven't used any transformations in my example, but you can absolutely use them if you want to crop or do some fancy edits, all you have to do is add your transformation to end of your request endpoint. Or if you want the edits to happen by default you can do so while setting your upload preset.&lt;/p&gt;

&lt;p&gt;This is what an endpoint will look like if you want to crop an image. &lt;a href="https://cloudinary.com/documentation/image_transformations"&gt;Refer docs for more.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/demo/image/upload/w_200,h_150,c_crop,g_north_west/sample.jpg"&gt;&lt;code&gt;https://res.cloudinary.com/demo/image/upload/w_200,h_150,c_crop/sample.jpg&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Cloudinary provides many more powerful features like video compressing for fast loading and robust transformations. It also has a wide range of integrations for use with any platform of your choice. You can have all information on their &lt;a href="https://cloudinary.com/"&gt;homepage&lt;/a&gt;. It's free account gives 25 credits which allows for approx 1GB of storage (&lt;a href="https://cloudinary.com/pricing"&gt;check pricing&lt;/a&gt;). You can see all your uploads inside &lt;strong&gt;Media Library.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have a great day :)&lt;/p&gt;

</description>
      <category>react</category>
      <category>cloudinary</category>
    </item>
  </channel>
</rss>
