<?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: Tapas Adhikary</title>
    <description>The latest articles on DEV Community by Tapas Adhikary (@atapas).</description>
    <link>https://dev.to/atapas</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%2F167280%2F6fa79d16-5e73-40a1-ba93-336079d49cf9.jpeg</url>
      <title>DEV Community: Tapas Adhikary</title>
      <link>https://dev.to/atapas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/atapas"/>
    <language>en</language>
    <item>
      <title>I Spent 40 Hours Writing Tests That Broke in 2 Weeks — A Confession Story</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Thu, 17 Jul 2025 10:51:57 +0000</pubDate>
      <link>https://dev.to/atapas/i-spent-40-hours-writing-tests-that-broke-in-2-weeks-a-confession-story-5a3o</link>
      <guid>https://dev.to/atapas/i-spent-40-hours-writing-tests-that-broke-in-2-weeks-a-confession-story-5a3o</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Some stories are worth sharing, even if they start with humongous setbacks! Here goes my recent tech battle tale, and key learnings from it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prologue
&lt;/h2&gt;

&lt;p&gt;Our team had just finished a major sprint refactor, and I, a product lead, volunteered to take charge of improving our end-to-end (E2E) test coverage. &lt;/p&gt;

&lt;p&gt;The goal was to boost confidence in our regression suite and reduce bugs leaking into production. With the set of testing tools out there today to help with E2E testing, test case generation, test coverage, and test report creation, I had assumed it would be a cake walk!&lt;/p&gt;

&lt;p&gt;What followed was a frustrating lesson, false positives, surprises, and how testing can either support or sabotage your development cycle, depending on how it’s approached.&lt;/p&gt;

&lt;p&gt;By the way, this is not a post to blame or criticise testing — it's quite the opposite. It’s a confession about what went wrong when I did everything “following the rules” and still watched 40 hours of test automation crumble in under two weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Intent and A Grand Start
&lt;/h2&gt;

&lt;p&gt;We had a React-based web application with moderate unit test coverage but with very little E2E coverage. The few Cypress tests we had were outdated and flaky. Developers were increasingly hesitant to trust automation. My goal was to build a robust suite that would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validate user flows across authentication, dashboard, and profile update features.&lt;/li&gt;
&lt;li&gt;Catch regressions before they reach QA or production.&lt;/li&gt;
&lt;li&gt;Run reliably as part of CI/CD.&lt;/li&gt;
&lt;li&gt;Serve as living documentation for critical workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was the man with the mission. So I updated our Cypress version, established folder structure conventions, and began building out test specs with clear naming, reusable helpers, tags, and test data.&lt;/p&gt;

&lt;p&gt;I wrote 20+ scenarios. I created custom commands for login/logout, seeded test data via API, and even used &lt;code&gt;data-test&lt;/code&gt; IDs to avoid weak selectors.&lt;/p&gt;

&lt;p&gt;Everything worked like a charm, all passed locally. Next, Everything passed on CI, too. I was the proudest guy in the team meeting for a couple of weeks!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Battle Part
&lt;/h2&gt;

&lt;p&gt;The dream run started to slow down as I figured out that my hard work may have to be redone once again! &lt;/p&gt;

&lt;p&gt;These were the reasons:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;User Interfaces never settle down&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The product team planned and launched a user interface refresh with a brand new UX. Some of the changes were not even that major, like a button changed from "Submit" to "Save Changes", a few class names were refactored, and one modal now loads dynamically instead of rendering in the DOM.&lt;/p&gt;

&lt;p&gt;So, what happened?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My button click tests failed due to text changes. &lt;/li&gt;
&lt;li&gt;Modal tests couldn’t locate elements that now only appeared conditionally.&lt;/li&gt;
&lt;li&gt;Navigation flows were slightly different, causing tests to hang or timeout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What did I learn?&lt;/p&gt;

&lt;p&gt;UI-based E2E tests are fragile by nature. Even small, intentional changes break everything downstream(sigh).&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Data dependencies could be costly&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I depended on backend APIs to seed realistic test data. But these APIs changed silently, breaking assumptions about user roles and default field values.&lt;/p&gt;

&lt;p&gt;What did I learn?&lt;/p&gt;

&lt;p&gt;If your tests depend on mutable data or APIs you don’t have control over, your suite is only as stable as its weakest API contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Weak Selectors and Timing Hell&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Even though I used &lt;code&gt;data-test&lt;/code&gt; attributes, dynamic rendering introduced some race conditions. Animations and lazy-loaded modals caused selectors to intermittently fail.&lt;/p&gt;

&lt;p&gt;What did I learn?&lt;/p&gt;

&lt;p&gt;Intermittent test failures create trust issues. Once a test fails intermittently, no one believes it anymore, even when it’s right.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Time
&lt;/h2&gt;

&lt;p&gt;I didn’t want to throw away my work. So I went into research mode. I started exploring tools, techniques, and approaches to strengthen the suite.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools Evaluated
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. &lt;a href="https://playwright.dev/" rel="noopener noreferrer"&gt;Playwright&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fts03poksb6mpcb9pj4m2.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%2Fts03poksb6mpcb9pj4m2.png" alt="Playwright" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is Faster and more reliable in async-heavy apps.&lt;/li&gt;
&lt;li&gt;Supports smart selectors and auto-waiting.&lt;/li&gt;
&lt;li&gt;Has the Cross-Browser Support Out of the Box.&lt;/li&gt;
&lt;li&gt;Provides powerful Context Isolations.&lt;/li&gt;
&lt;li&gt;Has a built-in Parallel Execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verdict: Loved it, but too late in the game to rewrite 20+ Cypress tests mid-sprint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. &lt;a href="https://nightwatchjs.org/" rel="noopener noreferrer"&gt;Nightwatch&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgzgsv6veef31a5dfs5jc.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%2Fgzgsv6veef31a5dfs5jc.png" alt="Nightwatch" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is an all-in-one test framework.&lt;/li&gt;
&lt;li&gt;Has the Selenium and webdriver2 support.&lt;/li&gt;
&lt;li&gt;Supports simple syntax and Page Object Model.&lt;/li&gt;
&lt;li&gt;Provides Cross-Browser and mobile device testing.&lt;/li&gt;
&lt;li&gt;Got a strong community and long-term stability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verdict: Nightwatch is solid if you’re in a legacy Selenium ecosystem or need WebDriver compatibility. In my case, the dilemma of rewriting the existing test cases was still a big reason to stay away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. &lt;a href="https://bug0.com/" rel="noopener noreferrer"&gt;Bug0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklctn6pcffi1zzc4lzf3.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%2Fklctn6pcffi1zzc4lzf3.png" alt="Bug0" width="800" height="638"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A fully managed AI-powered QA platform.&lt;/li&gt;
&lt;li&gt;A platform with zero setup needed, no codebase access needed, and works just by providing a staging URL.&lt;/li&gt;
&lt;li&gt;Excellent test compatibility matrix with rich test reporting capability.&lt;/li&gt;
&lt;li&gt;OOTB CI/CD, notification, and real-time reporting integrations.&lt;/li&gt;
&lt;li&gt;Self-Healing support that helps tests to automatically adapt when UI changes occur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verdict: The &lt;code&gt;Self-Healing&lt;/code&gt; feature was the turning point for me. Just when I was considering scrapping and rewriting the entire test suite, &lt;code&gt;Bug0&lt;/code&gt; came up with a lot of promise!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. &lt;a href="https://www.browserstack.com/" rel="noopener noreferrer"&gt;BrowserStack&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5zg10q13p3cuvwwe60gp.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%2F5zg10q13p3cuvwwe60gp.png" alt="Browserstack" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A popular DIY testing tool.&lt;/li&gt;
&lt;li&gt;You can test your apps on a massive grid of real browsers and OS combinations.&lt;/li&gt;
&lt;li&gt;Getting access to logs, video recordings, and screenshots makes it easy to debug.&lt;/li&gt;
&lt;li&gt;Support major frameworks like Sypress, Playwright, Selenium, Nightwatch&lt;/li&gt;
&lt;li&gt;You can plug seamlessly with CI/CD.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verdict: BrowserStack is great when it comes to ensuring the real-world compatibility coverage without breaking head for your own infrastructure. But still, it requires manual set-up, maintenance, and the effort to write and update tests.&lt;/p&gt;

&lt;p&gt;I didn't stop my research with these three alone. I went ahead and looked into two more possibilities:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. &lt;a href="https://mswjs.io/" rel="noopener noreferrer"&gt;Mock Service Worker (MSW)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intercept network calls and return mock data
&lt;/li&gt;
&lt;li&gt;Helped decouple tests from backend flakiness
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verdict: A true lifesaver. Tests became stable and deterministic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Low-Code Platforms (Testim, Reflect.run)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Great for quick UI test creation
&lt;/li&gt;
&lt;li&gt;Non-technical folks could contribute
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verdict: Useful, but lacked control and flexibility for our edge cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Final Selection
&lt;/h2&gt;

&lt;p&gt;I’ll be honest here, I was sceptical. I’ve used “AI-powered” tools before, and most were just keyword detection with a fancy UI. But I found &lt;a href="https://bug0.com/ai" rel="noopener noreferrer"&gt;Bug0&lt;/a&gt; different in three major ways:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Self-Healing Tests That Actually Worked
&lt;/h3&gt;

&lt;p&gt;When a button label changed or a DOM structure was slightly refactored, Bug0’s test runner intelligently adapted using visual cues and context, not just selectors. I could see in the logs where it adjusted and why.&lt;/p&gt;

&lt;p&gt;This alone reduced maintenance time by at least 60%.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Dynamic Test Validation and Real-time Reporting
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Bug0&lt;/code&gt; allowed me to run tests against two app versions (before and after refactors) and generated real-time reports. The report contains checks with drill-down facilities:&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%2Feur35cp4hfejahrrssu7.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%2Feur35cp4hfejahrrssu7.png" alt="Bug0 Reports" width="800" height="1053"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On drilling down, I could get all the test status and also detailed video capturing the failures.&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%2Fwloz2lif0ypkbtgq7s37.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%2Fwloz2lif0ypkbtgq7s37.png" alt="Bug0 Report Drill Down" width="800" height="921"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I didn’t have to manually figure out what UI or data changes broke my tests — it told me. This was a huge timesaver during sprints, where design tweaks were common.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.CI/CD Integration
&lt;/h3&gt;

&lt;p&gt;The last, but not the least, is about the CI/CD integration and compatibility. I had the option to integrate a CI/CD pipeline with GitHub, GitLab, or Bitbucket. I had the requirement for GitHub, and it was a perfect marriage!&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%2F4zdjp7g1rs58px8tkttb.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%2F4zdjp7g1rs58px8tkttb.png" alt="Bug0 CI/CD" width="800" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the test suite is ready, Bug0 plug it into the CI/CD workflow using their GitHub/GitLab/BitBucket App. The set-up was super fast(within a minute), triggered the test on every pull request, and ran silently in the background on every change.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Overall Learning
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Traditional Tools are Great, But...
&lt;/h3&gt;

&lt;p&gt;With my research on evaluating tools, frameworks, and platforms, I found that most of the traditional DIY testing tools, like BrowserStack, Playwright, and Nightwatch, are great and solve real problems. &lt;/p&gt;

&lt;p&gt;However, they are not easy to maintain in the long run. Your QA platform/tool selection should consider future maintenance costs, dedicated QA effort, and manual ways of managing test cases. &lt;/p&gt;

&lt;p&gt;It's been a decade since the world has moved towards automation from manual testing efforts. If you are wondering about the current trends, A 2025 &lt;a href="https://www.forrester.com/blogs/the-evolution-from-continuous-automation-testing-platforms-to-autonomous-testing-platforms-a-new-era-in-software-testing/" rel="noopener noreferrer"&gt;Forrester study&lt;/a&gt; found that &lt;strong&gt;55% of organizations&lt;/strong&gt; already use AI in their testing workflows, with &lt;strong&gt;70% of mature DevOps teams&lt;/strong&gt; relying on AI-powered tools to maintain speed and coverage. &lt;/p&gt;

&lt;p&gt;Yes! The agentic AI, human-in-the-loop QA, and continuous quality systems are not a dream or fairy tales. They are the &lt;a href="https://testguild.com/automation-testing-trends/" rel="noopener noreferrer"&gt;"new reality"&lt;/a&gt; to make us much more productive and efficient.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Testing Layers
&lt;/h3&gt;

&lt;p&gt;I am from a developer background. I had as limited knowledge about the testing layers as a QA might have about a complex design pattern(no offence!). &lt;/p&gt;

&lt;p&gt;The choice you need to make about learning these layers and differences between them, so that your test strategies sound reliable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit Tests&lt;/strong&gt;: For logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component Tests&lt;/strong&gt;: For User Interfaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal E2E Tests&lt;/strong&gt;: Only the highest-value flows, stabilized via Bug0 + MSW.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use decoupling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replaced flaky backend setups with mocks.&lt;/li&gt;
&lt;li&gt;Used fixture versioning to avoid silent data shifts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ownership &amp;amp; Documentation
&lt;/h3&gt;

&lt;p&gt;Even with an AI-powered platform that help you with a bunch of automation with test case writing and executions, you still need to care for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pushing Test guides in the repository.&lt;/li&gt;
&lt;li&gt;Slack(Or, any other tool you use) alerts for flaky failures.&lt;/li&gt;
&lt;li&gt;Devs knew how to debug and contribute further.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;I spent 40 hours building a test suite that broke in 2 weeks. It taught me how to get smarter at it with my research and usage of the right tool at the right time.&lt;/p&gt;

&lt;p&gt;A few words of empathy: If you’re struggling with test stability, ever-changing UIs, and time-consuming maintenance, you’re not alone. The testing pyramid is real for a reason. &lt;/p&gt;

&lt;p&gt;Tools like MSW and platforms like Bug0 won’t magically fix bad practices, but they will amplify good ones. Testing is part of the development experience. It's time to embrace it with equal importance to every other layer of product development and delivery.&lt;/p&gt;




&lt;p&gt;I hope my story did not bore you, and you found it insightful. I would love to know if it resonates with you and your experience in setting up automation testing strategies for your team.&lt;/p&gt;

&lt;p&gt;That's all for now. Let’s connect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Subscribe to my &lt;a href="https://www.youtube.com/tapasadhikary?sub_confirmation=1" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow on &lt;a href="https://www.linkedin.com/in/tapasadhikary/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; if you don't want to miss the daily dose of up-skilling tips.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check out and follow my open-source work on &lt;a href="https://github.com/atapas" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>testing</category>
      <category>qa</category>
      <category>automation</category>
      <category>ai</category>
    </item>
    <item>
      <title>Tidbit 05: WeakMap in JavaScript – The Secret Keeper You Didn’t Know You Needed!</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Thu, 19 Jun 2025 13:27:00 +0000</pubDate>
      <link>https://dev.to/atapas/tidbit-05-weakmap-in-javascript-the-secret-keeper-you-didnt-know-you-needed-1li5</link>
      <guid>https://dev.to/atapas/tidbit-05-weakmap-in-javascript-the-secret-keeper-you-didnt-know-you-needed-1li5</guid>
      <description>&lt;h2&gt;
  
  
  What is a WeakMap?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;&lt;code&gt;WeakMap&lt;/code&gt;&lt;/strong&gt; is like a regular &lt;code&gt;Map&lt;/code&gt;, but with one juicy twist:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Its keys must be &lt;strong&gt;objects&lt;/strong&gt;, and it holds them &lt;strong&gt;weakly&lt;/strong&gt; — meaning it &lt;em&gt;won’t stop them from being garbage collected&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think of &lt;code&gt;WeakMap&lt;/code&gt; as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;A magic box that only an object can open and take things from it. When the object leaves, the magic box also disappears.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When Should You Use WeakMap?
&lt;/h2&gt;

&lt;p&gt;Use &lt;code&gt;WeakMap&lt;/code&gt; when you want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Associate &lt;strong&gt;truly private data&lt;/strong&gt; with an object.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid memory leaks&lt;/strong&gt; with temporary objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hide implementation details&lt;/strong&gt; from external code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is especially helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you don’t want to expose internal states or metadata directly.&lt;/li&gt;
&lt;li&gt;When you want data to vanish when the object is no longer used.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Real World Example
&lt;/h2&gt;

&lt;p&gt;Imagine you’re building a UI where you want to track the last time each DOM element was clicked. You want to accomplish it without storing the data directly on the element or risking &lt;code&gt;memory leaks&lt;/code&gt; when elements are removed from the DOM. This is where WeakMap shines.&lt;/p&gt;

&lt;p&gt;Why Use WeakMap Here?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want to store data related to a DOM node.&lt;/li&gt;
&lt;li&gt;You don’t want to manually delete it when the node is removed.&lt;/li&gt;
&lt;li&gt;WeakMap allows automatic cleanup when the node is gone from memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let us assume an HTML code snippet with two DIVs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"box1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click Me!&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"box2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Click Me Too!&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us now create a WeakMap &lt;code&gt;clickTimestamps&lt;/code&gt; to store the click metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;box1&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;box1&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;box2&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;box2&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 a WeakMap to store click metadata&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clickTimestamps&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;WeakMap&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;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&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;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;clickTimestamps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;now&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="s2"&gt;`Element clicked at: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;clickTimestamps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleTimeString&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="nx"&gt;box1&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;handleClick&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;box2&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;handleClick&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What Happens Behind the Scenes?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The WeakMap stores the timestamp associated with each DOM element.&lt;/li&gt;
&lt;li&gt;You don’t pollute the DOM element with extra properties.&lt;/li&gt;
&lt;li&gt;When the element (say box2) is removed from the DOM and garbage collected, its associated timestamp in WeakMap is automatically cleaned up. No leaks!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How’s It Different from a Map?
&lt;/h2&gt;

&lt;p&gt;As we know about the WeakMap, here is a comparison table of WeakMap vs. Map:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLIJrr73KDmRw2Fwwjt6cPC_tk5vcSICCu" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21mygtp8jkfj9k0iqc18.png" alt="map vs weekmap" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WeakMap&lt;/code&gt; is &lt;strong&gt;non-enumerable&lt;/strong&gt; and &lt;strong&gt;non-inspectable&lt;/strong&gt; — perfect for &lt;em&gt;hiding things&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pitfalls to Watch Out For
&lt;/h2&gt;

&lt;p&gt;A few pitfalls you need to be aware of when using a WeakMap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can’t loop through a WeakMap.&lt;/li&gt;
&lt;li&gt;You can’t check its size.&lt;/li&gt;
&lt;li&gt;You can’t see what’s inside it (on purpose!).&lt;/li&gt;
&lt;li&gt;If the object key disappears, so does the value—it’s gone forever.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just like WeakMap, we also have &lt;code&gt;WeakSet&lt;/code&gt; serves a similar purpose. However, it is a collection of unique elements, not a map. I wish to cover it in a future tidbit.&lt;/p&gt;

&lt;p&gt;That's all for now. Found this helpful? Please snap a like, and feel free to comment below.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn further?
&lt;/h2&gt;

&lt;p&gt;Check out the session on JavaScript Collections: Map, Set, WeakMap, and WeakSet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=kzuvppEWm88" rel="noopener noreferrer"&gt;Day 33: JavaScript Map, Set, WeakMap, WeakSet - When &amp;amp; Why to Use Them! 🤩&lt;/a&gt; - In this session, we take a deep dive into JavaScript Collections—Map, Set, WeakMap, and WeakSet. Whether you’re a beginner or brushing up on advanced JavaScript, this session will help you understand when to use each, their key differences, and real-world use cases with clear examples.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>dsa</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Tidbit 04: JavaScript Promise Chain vs No-Chain</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Tue, 10 Jun 2025 12:01:00 +0000</pubDate>
      <link>https://dev.to/atapas/tidbit-04-javascript-promise-chain-vs-no-chain-339p</link>
      <guid>https://dev.to/atapas/tidbit-04-javascript-promise-chain-vs-no-chain-339p</guid>
      <description>&lt;h2&gt;
  
  
  Promise Chain vs. No-Chain
&lt;/h2&gt;

&lt;p&gt;A promise chain is formed when we append multiple promise handler functions(like, .then() or .catch()) to handle results and errors. However, at times you could be mistaken that you need to prefix the promise everytime you want to form a chain.&lt;/p&gt;

&lt;p&gt;Let's understand it with the following examples:&lt;/p&gt;

&lt;p&gt;First, here is a simple promise created with the Promise() constructor function. The promise resolves immidiately with a result value of 10.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ten&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;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;Now, to form a Promise Chain, let us chain a bunch of .then() handler functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Promise Chain&lt;/span&gt;

&lt;span class="nx"&gt;ten&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;result&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;// returns 20&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// returns 200&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// returns 190&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// logs 190 in console&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;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It has formed a perfect Promise Chain to pass the result from one handler function to another, and finaly print the end result into the console. The final result output is a number, i.e, 190.&lt;/p&gt;

&lt;p&gt;Now, let us change the above code to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// No Chain&lt;/span&gt;

&lt;span class="nx"&gt;ten&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;result&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;// returns 20&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;ten&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;result&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;// returns 100&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;ten&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;result&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;// returns 0&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;ten&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;result&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;// logs 10 in the console.&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;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you notice, we have now prefixed the promise ten every time before the .then() handler function. It is not a chain because, we are handling the promise freshly every time with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ten&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;result&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;// DO SOMETHING...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are not passing the resolved result of the previous promise to the next one. Hence the output will be, 10. It is a common mistake developers make with JavaScript Promises.&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%2Fv9enapt8nkgikdnf5mtb.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%2Fv9enapt8nkgikdnf5mtb.png" alt="Chain vs. No Chain" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn further?
&lt;/h2&gt;

&lt;p&gt;Learn about other common mistakes developers make in handling JavaScript Promises.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=c_zcXUz1neo" rel="noopener noreferrer"&gt;Day 26: 6 Common Mistakes with JavaScript Promises &amp;amp; Async Code 🤩&lt;/a&gt; - In this session, we’ll break down 6 common mistakes developers make while working with Promises and async code — and most importantly, how to avoid them! Whether you’re just learning or brushing up, this video will help you write cleaner, bug-free asynchronous code.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Tidbit 03: innerText vs textContent in JavaScript – Not Twins, Just Cousins!</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Mon, 09 Jun 2025 14:17:00 +0000</pubDate>
      <link>https://dev.to/atapas/tidbit-03-innertext-vs-textcontent-in-javascript-not-twins-just-cousins-3i4a</link>
      <guid>https://dev.to/atapas/tidbit-03-innertext-vs-textcontent-in-javascript-not-twins-just-cousins-3i4a</guid>
      <description>&lt;p&gt;In JavaScript DOM, both innerText and textContent seem to give you the text inside an HTML element. But under the hood, they work quite differently.&lt;/p&gt;

&lt;p&gt;Let’s explore what they are, how they differ, and when to use which—with real-world examples!&lt;/p&gt;

&lt;h2&gt;
  
  
  The textContent — The Raw Texter
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Returns all the text in the element, including hidden elements.&lt;/li&gt;
&lt;li&gt;Ignores CSS and layout.&lt;/li&gt;
&lt;li&gt;Faster because there are no layout calculations.&lt;/li&gt;
&lt;li&gt;Great for getting raw data or sanitizing content.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's create a hidden text on the UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Hello &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:none"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;World&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you use the &lt;code&gt;textContent&lt;/code&gt; property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;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;info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Output: "Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get &lt;code&gt;"Hello World"&lt;/code&gt; even though &lt;code&gt;“World”&lt;/code&gt; is hidden.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;textContent&lt;/code&gt; when you need all content, regardless of visibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  The innerText — The Visible Speaker
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Returns only the visible (rendered) text.&lt;/li&gt;
&lt;li&gt;Respects CSS like display: none, visibility: hidden, etc.&lt;/li&gt;
&lt;li&gt;Slower (causes layout reflow).&lt;/li&gt;
&lt;li&gt;Ideal for mimicking what users actually see on screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For, the same HTML above, if you use the &lt;code&gt;innerText&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;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;info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Output: "Hello"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will only get the &lt;code&gt;“Hello”&lt;/code&gt;. The hidden &lt;code&gt;“World”&lt;/code&gt; is ignored.&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;innerText&lt;/code&gt; when you want screen-accurate content (what the user sees).&lt;/p&gt;

&lt;p&gt;You can learn about DOM Manipulations in JavaScript with examples and projects &lt;a href="https://www.youtube.com/watch?v=BoYgn_Mf0hA" rel="noopener noreferrer"&gt;from this session&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Often developers use the &lt;code&gt;innerText&lt;/code&gt; and &lt;code&gt;textContent&lt;/code&gt; interchangibly without understanding their real purposes. Please note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re reading or saving data, go for textContent.&lt;/li&gt;
&lt;li&gt;If you’re testing, displaying, or analyzing visible UI, use innerText.&lt;/li&gt;
&lt;li&gt;They’re not interchangeable—choose wisely based on context!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Join 40 Days of JavaScript for FREE
&lt;/h2&gt;

&lt;p&gt;There are 101 ways of learning something. But, nothing can beat the “structured” and “progressive” learning methodologies. I have designed this FREE task-based Course for you to stay structured and motivated. Sounds great? Please take a look:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLIJrr73KDmRw2Fwwjt6cPC_tk5vcSICCu" rel="noopener noreferrer"&gt;Join 40 Days of JavaScript Course for FREE&lt;/a&gt; - Do not miss the chance to learn JavaScript in-depth with practical projects and assignments. JavaScript is omnipresent and learning the language well will help you get a better grip on many other libraries and frameworks like ReactJS, Angular, Next.js, Node.js, Remix, and many more. So, make sure to join the 40 Days of JavaScript initiative and master the language.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Tidbit 02: Abstraction in JavaScript: Washing Machine Style!"</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Fri, 06 Jun 2025 13:50:00 +0000</pubDate>
      <link>https://dev.to/atapas/abstraction-in-javascript-washing-machine-style-5cc2</link>
      <guid>https://dev.to/atapas/abstraction-in-javascript-washing-machine-style-5cc2</guid>
      <description>&lt;h2&gt;
  
  
  What is Abstraction?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Abstraction&lt;/code&gt; is an Object-Oriented Programming (OOP) principle that means hiding internal details(or complexities) and exposing only essential parts to the end users. Think of it like using a TV remote — you press a button to switch channels, but you don’t need to understand the circuitry behind it.&lt;/p&gt;

&lt;p&gt;In code, abstraction helps keep things clean, maintainable, and secure. Users interact with simple methods, while complex logic stays away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is Abstraction Important?
&lt;/h2&gt;

&lt;p&gt;Abstraction is one of the four pillars of OOP, along with Encapsulation, Inheritance, and Polymorphism. It helps with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: It hides unnecessary complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt;: Sensitive logic or data can be kept private.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability&lt;/strong&gt;: Internal changes don’t affect users of the class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusability&lt;/strong&gt;: You can reuse the same interface across different implementations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can implement Abstraction in JavaScript with Constructor Functions or the Classes feature introduced in ES6. Let us now implement one with ES6 Classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are ES6 Classes?
&lt;/h2&gt;

&lt;p&gt;ES6 introduced the class syntax in JavaScript to make OOP-style coding easier and more familiar. It’s just syntactic sugar over JavaScript’s existing prototype-based inheritance but makes your code cleaner and more intuitive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hello, &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;name&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;Classes can have public/private fields and methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public fields/methods&lt;/strong&gt;: Accessible from outside the class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private fields/methods&lt;/strong&gt;: Start with #, and are accessible only within the class.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sample&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;publicField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I'm public&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;privateField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I'm private&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;showFields&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicField&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Can be accessed&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;privateField&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Can be accessed&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;s&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;Sample&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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicField&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// Can be accessed&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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;privateField&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// SyntaxError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can learn about ES6 Classes with examples &lt;a href="https://www.youtube.com/watch?v=kG5t34ciG9w" rel="noopener noreferrer"&gt;from this session&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Washing Machine Example: Real-World Abstraction
&lt;/h2&gt;

&lt;p&gt;When you run a Washing Machine, you worry about starting and stopping the Washing Machine. When you press a button to start the Washing Machine, a few things happen at the background. For example, the Washing Machine checks the power status, fill water, spin the drum, drain the water after wash, and stops.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLIJrr73KDmRw2Fwwjt6cPC_tk5vcSICCu" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkofjqthvyals4z3pfft2.png" alt="day-30" width="800" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All these complex electrical and mechanical activities are abstracted away from the customers by the Washing Machine vendors. The customers/end users just press the start button, and all that takes place at the background!&lt;/p&gt;

&lt;p&gt;Now, if we model Washing Machine as a Class in the JavaScript world, we can think of &lt;code&gt;start()&lt;/code&gt; and &lt;code&gt;stop()&lt;/code&gt; as the only public methods to expose to the users. Whereas, all other actions like spin, drain, etc., should be handled as private methods. That's how we achieve abstraction.&lt;/p&gt;

&lt;p&gt;Here is an implementation of &lt;code&gt;Abstraction&lt;/code&gt; with the Washing Machine example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WashingMachine&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// public&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;powerStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// private&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;currentCycle&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="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;brand&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;brand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// public&lt;/span&gt;
  &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cycle&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;powerStatus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;currentCycle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cycle&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="s2"&gt;`Starting &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cycle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; cycle...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;fillWater&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;spin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;drain&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;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// public&lt;/span&gt;
  &lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Washing machine stopped.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;turnOff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// private&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;powerStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&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;Power ON&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;// private&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;turnOff&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;powerStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;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;Power OFF&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;// private&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;fillWater&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Filling Water...&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;Water Filled.&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;// private&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;spin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Spinning...&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;// private&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;drain&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Draining...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What’s Abstracted?
&lt;/h3&gt;

&lt;p&gt;The user of the class only needs to call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lgWasher&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;WashingMachine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;LG&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;lgWasher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Quick Wash&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;They don’t need to worry about how the machine turns on, spins, or drains—those are abstracted away using private methods like &lt;code&gt;#turnOn()&lt;/code&gt; and &lt;code&gt;#drain()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Trying to access internal workings like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;lgWasher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;powerStatus&lt;/span&gt;  &lt;span class="c1"&gt;// Error&lt;/span&gt;
&lt;span class="nx"&gt;lgWasher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;     &lt;span class="c1"&gt;// Error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It throws an error. That’s true abstraction in JavaScript, thanks to ES6 private fields and methods.&lt;/p&gt;

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

&lt;p&gt;Abstraction helps you focus on what matters while the complexities stay behind the curtain. With Classes, JavaScript finally gives you the tools (like &lt;code&gt;#private&lt;/code&gt; fields introduced in ECMAScript 2022) to implement this cleanly—just like your Washing Machine, which works wonders with a single &lt;code&gt;start()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join 40 Days of JavaScript for FREE
&lt;/h2&gt;

&lt;p&gt;There are 101 ways of learning something. But, nothing can beat the “structured” and “progressive” learning methodologies. I have designed this FREE task-based Course for you to stay structured and motivated. Sounds great? Please take a look:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLIJrr73KDmRw2Fwwjt6cPC_tk5vcSICCu" rel="noopener noreferrer"&gt;Join 40 Days of JavaScript Course for FREE&lt;/a&gt; - Do not miss the chance to learn JavaScript in-depth with practical projects and assignments. JavaScript is omnipresent and learning the language well will help you get a better grip on many other libraries and frameworks like ReactJS, Angular, Next.js, Node.js, Remix, and many more. So, make sure to join the 40 Days of JavaScript initiative and master the language.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Tidbit 01: How Does Event Loop Handle Promises?</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Thu, 05 Jun 2025 11:46:00 +0000</pubDate>
      <link>https://dev.to/atapas/how-does-event-loop-handle-promises-ever-thought-57df</link>
      <guid>https://dev.to/atapas/how-does-event-loop-handle-promises-ever-thought-57df</guid>
      <description>&lt;p&gt;Ever wondered how JavaScript knows when to run your &lt;code&gt;.then()&lt;/code&gt; block? Or why your &lt;code&gt;console.log("done")&lt;/code&gt; appears before a resolved promise result? Let’s break it down in this quick TidBit!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Promise?
&lt;/h2&gt;

&lt;p&gt;A Promise is JavaScript’s way of saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I’ll give you a value… eventually!”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s a placeholder for a result that’s either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Fulfilled (Success)&lt;/li&gt;
&lt;li&gt;  Rejected (Failure)&lt;/li&gt;
&lt;li&gt;  Or still Pending
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&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;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&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;resolve&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 loaded!&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;promise&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;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When resolve("Data loaded!") is called, the &lt;code&gt;.then()&lt;/code&gt; block waits to execute — but where does it go meanwhile?&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Event Loop?
&lt;/h2&gt;

&lt;p&gt;JavaScript is single-threaded. That means it can do one thing at a time. So how does it handle waiting, timers, and promises without freezing the app?&lt;/p&gt;

&lt;p&gt;Enter the Event Loop.&lt;/p&gt;

&lt;p&gt;It’s like a traffic controller — coordinating between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Call Stack (where code runs)&lt;/li&gt;
&lt;li&gt;  Web APIs (like setTimeout, DOM)&lt;/li&gt;
&lt;li&gt;  Callback Queue&lt;/li&gt;
&lt;li&gt;  Microtask Queue (where .then() of Promises go)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How Event Loop Manages Promises?
&lt;/h2&gt;

&lt;p&gt;Let’s see the order of execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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;Start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Resolved&lt;/span&gt;&lt;span class="dl"&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;msg&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;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;msg&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;End&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;Output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;But, Why?&lt;/p&gt;

&lt;p&gt;Here’s how it plays out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  console.log("Start") ➝ runs immediately (Call Stack)&lt;/li&gt;
&lt;li&gt;  Promise.resolve(...).then(...) ➝ .then() is scheduled (Microtask Queue)&lt;/li&gt;
&lt;li&gt;  console.log("End") ➝ also runs immediately&lt;/li&gt;
&lt;li&gt;  After current stack is empty, Event Loop picks microtasks → .then() runs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why Resolved appears after End, even though the promise is already resolved!&lt;/p&gt;

&lt;p&gt;Let’s spice it up with a setTimeout:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="nf"&gt;setTimeout&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;From setTimeout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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="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;From Promise&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;End&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;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Start
End
From Promise
From setTimeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, Microtasks (Promises) are given priority over macrotasks (setTimeout, etc.).&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Recap
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Promises don’t run instantly — their .then() goes to the microtask queue.&lt;/li&gt;
&lt;li&gt;  The Event Loop picks microtasks before other callbacks once the call stack is clear.&lt;/li&gt;
&lt;li&gt;  Even a setTimeout(..., 0) will wait behind a resolved Promise!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So next time your Promise resolves “later,” remember — it’s not late. It’s just politely waiting its turn in the queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to learn further?
&lt;/h2&gt;

&lt;p&gt;Learn about Event Loop along with JavaScript Promises, Call Stack, Task Queue Visually.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4IYcwOfW3BM" rel="noopener noreferrer"&gt;Day 27: How Your Async Code Works | JavaScript Event Loop Simplified! 🤩&lt;/a&gt; - In this session, we’ll learn about how JavaScript executes code internally. This session uses visualizations to demonstrate the working of Call Stack, Event Loop, Promises, Web APIs, and more. Let's learn.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Why the with() method of JavaScript Array is a gem?</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Wed, 29 Jan 2025 13:40:32 +0000</pubDate>
      <link>https://dev.to/atapas/why-the-with-method-of-javascript-array-is-a-gem-391c</link>
      <guid>https://dev.to/atapas/why-the-with-method-of-javascript-array-is-a-gem-391c</guid>
      <description>&lt;p&gt;JavaScript array methods offer plenty to web developers already. The methods like &lt;code&gt;map()&lt;/code&gt;, &lt;code&gt;reduce()&lt;/code&gt;, &lt;code&gt;filter()&lt;/code&gt; , &lt;code&gt;some()&lt;/code&gt;, &lt;code&gt;every()&lt;/code&gt;, and many more have helped build our &lt;a href="https://blog.greenroots.info/build-your-javascript-muscles-with-map-reduce-filter-and-other-array-iterators" rel="noopener noreferrer"&gt;JavaScript muscles&lt;/a&gt; for better logic and algorithms.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;with()&lt;/code&gt; method is a relatively new inclusion to the JavaScript array method list, and its only intention is to change the value of a given index in an array in the "immutable" way. A big deal? Yes! Let's learn.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Btw, please do not confuse the &lt;code&gt;with()&lt;/code&gt; method from the JavaScript Array with the &lt;code&gt;with&lt;/code&gt; statement from the language. The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with" rel="noopener noreferrer"&gt;with statement has been deprecated&lt;/a&gt; whereas, the with() method is a new inclusion to the language. People say JavaScript is weird, naming things is possibly a reason for it!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article is also available as a video tutorial now. You can check it out here:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  The traditional way to seek and change
&lt;/h2&gt;

&lt;p&gt;Let us consider an array of numbers,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How would you change the element of an array for a given index? Suppose you need to change the element &lt;code&gt;3&lt;/code&gt; which is at the index &lt;code&gt;2&lt;/code&gt;(remember, the array index in JavaScript starts with 0) with a new element, say, &lt;code&gt;6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The usual instinct would be to do this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&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;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;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 6, 4, 5];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works! However, there is a problem. We have mutated(aka, permanently changed) the original array. When you deal with data in your application, a data structure like an array should hold the original(unchanged) data as a "source of truth". You wouldn't want it to be modified by any functions and logic to achieve better predictability in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Immutability is a great tool
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Immutability&lt;/code&gt; is a mechanism to ensure that we can not change something(an array, object, etc). However, if we need a modified version of it, we need to first create a copy of the original and then make modifications to the copied version. This ensures that the original data is never changed by anything in the application, knowingly or unknowingly.&lt;/p&gt;

&lt;p&gt;So, how about changing the element of an array at a given index, in an immutable way? It means every time we change an element in an array, we do not mutate the original array, rather we get back a new copy of the original array with the change applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  The with() method and immutability
&lt;/h2&gt;

&lt;p&gt;ECMAScript 2023 introduced a new method called &lt;code&gt;with()&lt;/code&gt; to solve this problem of mutability and achieve immutability while changing an element of an array. So now, instead of using a given index on the array directly, we can use the &lt;code&gt;with()&lt;/code&gt; method to change the element value.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;with()&lt;/code&gt; method takes two parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;index&lt;/code&gt; - An index value which can start from &lt;code&gt;0&lt;/code&gt;, and also can be a negative number. The negative index counts backwards from the end of the array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;value&lt;/code&gt; - The value to change at a given index.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let us now apply the &lt;code&gt;with()&lt;/code&gt; method on the same array to change the element at a given index,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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;newArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&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;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;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Unchanged =&amp;gt; [1, 2, 3, 4, 5];&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;newArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Changed(A new copy) =&amp;gt; [1, 2, 6, 4, 5];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you see, the &lt;code&gt;with()&lt;/code&gt; method produces a new copy of the original array with the change applied. The original array is unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  The with() method and the negative index
&lt;/h2&gt;

&lt;p&gt;One more drawback of the direct index-based element seeking to get an element at a given index is that you can not use the negative number as an index value. Try something like the code snippet below, you will get an &lt;code&gt;undefined&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, trying to set a value on a negative index will have unexpected results,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&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;numbers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 3, 4, 5, -2: 8]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did you see that? You have ended up adding something completely different than what you anticipated. But, using the &lt;code&gt;with()&lt;/code&gt; method, you can change an element of an array at a negative index. The negative index starts from the end of the array with an index value of &lt;code&gt;-1&lt;/code&gt; and move backwards.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;2&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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;anotherArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&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;anotherArray&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 3, 8, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we have changed the second element of an array from the end. Hence the element &lt;code&gt;4&lt;/code&gt; in the array is replaced with the element &lt;code&gt;8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can use the &lt;a href="https://blog.greenroots.info/why-do-you-need-to-know-about-the-javascript-array-at-method" rel="noopener noreferrer"&gt;at() method&lt;/a&gt; of JavaScript array to read an element using a negative index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;anotherArray&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Method chaining
&lt;/h2&gt;

&lt;p&gt;As the &lt;code&gt;with()&lt;/code&gt; method returns an array, you can chain the output of the &lt;code&gt;with()&lt;/code&gt; method along with other array methods, like map(), filter(), reduce(), etc.&lt;/p&gt;

&lt;p&gt;In the code snippet below, we replace the second element of the &lt;code&gt;ages&lt;/code&gt; array with a new element, and then map the output array to multiply each element by four.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;23&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mappedAges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with&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="mi"&gt;32&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="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&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;mappedAges&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [48, 128, 224]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Can you please give a real-life use case of the with() method?
&lt;/h2&gt;

&lt;p&gt;Sure! When I published a &lt;a href="https://www.youtube.com/watch?v=TFsria_3sw8" rel="noopener noreferrer"&gt;YouTube video&lt;/a&gt; on this topic, I got a question about the real-life use case of the &lt;code&gt;with()&lt;/code&gt; method. The exciting thing is, that I discovered the with() method when I was building a use case that needs the feature it offers. The image below provides a summary of the use case.&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%2Fpli9wk9jnjd95ooca3h3.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%2Fpli9wk9jnjd95ooca3h3.png" alt="JavaScript Array with() method use case" width="800" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;That's all for now. I hope you agree with me that the &lt;code&gt;with()&lt;/code&gt; method is a true gem providing us immutability and negative index accessibility with JavaScript Arrays. You can check out these articles to learn more about JavaScript arrays and their unique use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.greenroots.info/build-your-javascript-muscles-with-map-reduce-filter-and-other-array-iterators" rel="noopener noreferrer"&gt;Build your JavaScript Muscles with map, reduce, filter and other array iterators&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.greenroots.info/5-ways-to-merge-arrays-in-javascript-and-their-differences" rel="noopener noreferrer"&gt;5 ways to merge arrays in JavaScript and their differences&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.greenroots.info/why-do-you-need-to-know-about-array-like-objects" rel="noopener noreferrer"&gt;Why do you need to know about Array-like Objects?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://blog.greenroots.info/why-do-you-need-to-know-about-the-javascript-array-at-method" rel="noopener noreferrer"&gt;Why do you need to know about the JavaScript Array at() method?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Liked it? Please let me know with your comments and likes. ❤️&lt;/p&gt;

&lt;p&gt;Let's connect. I share knowledge on web development, content creation, Open Source, and careers on these platforms.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/tapasadhikary?sub_confirmation=1" rel="noopener noreferrer"&gt;&lt;strong&gt;tapaScript on YouTube&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/tapasadhikary" rel="noopener noreferrer"&gt;&lt;strong&gt;X(Twitter)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/in/tapasadhikary/" rel="noopener noreferrer"&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/atapas" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Next.js and Next-Auth V5: Guide to Social Logins(OAuth)</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Thu, 23 Jan 2025 11:33:00 +0000</pubDate>
      <link>https://dev.to/atapas/nextjs-and-next-auth-v5-guide-to-social-loginsoauth-4236</link>
      <guid>https://dev.to/atapas/nextjs-and-next-auth-v5-guide-to-social-loginsoauth-4236</guid>
      <description>&lt;p&gt;&lt;code&gt;Authentication&lt;/code&gt; and &lt;code&gt;Authorization&lt;/code&gt; are the implicit needs for any user-facing application. Using authentication users let the application and underlying services know who they are, and if they are the legitimate people to get access to the system. There are various ways of authenticating like credential-based authentication, OTP-based authentication, magic links, biometrics, and more.&lt;/p&gt;

&lt;p&gt;While authentication is the way to tell someone who you are, authorization is how to provide access to resources they are supposed to have. There are role-based, policy-based authorization models that ensure the right access to resources when users try accessing them after authentication.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You will find &lt;a href="https://blog.greenroots.info/what-is-authentication-and-authorization" rel="noopener noreferrer"&gt;this article&lt;/a&gt; helpful if you are looking for a guide to learning about &lt;code&gt;Authentication and Authorization&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this step-by-step tutorial, we will focus on setting up authentication using OAuth providers like Google and Github with a &lt;code&gt;Next.js&lt;/code&gt; application. We will use &lt;code&gt;Auth.js&lt;/code&gt; or &lt;code&gt;Next-Auth V5&lt;/code&gt;, an open-source authentication tool for the web to get the auth set-up done.&lt;/p&gt;

&lt;p&gt;Let's get started 🚀&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: It would be great if you code as you follow along the sections of this article. The source code used in this article is publicly available on GitHub for you to access and use. You can find the link to it at the bottom of this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Create a Next.js App Router Project
&lt;/h2&gt;

&lt;p&gt;First, create a Next.js app using the command below from your terminal/command prompt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Make sure you have the latest &lt;a href="https://nodejs.org/en/download/package-manager" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; installed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The prompt will guide you to create a Next.js app with a name of your choice, a target tech stack (JavaScript or TypeScript), and a few more configurations. In my case, I went ahead with the following choices:&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%2F7oomtsvwd8b8uxnuq9ed.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%2F7oomtsvwd8b8uxnuq9ed.png" alt="Create a Next.js project" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note, that I have selected JavaScript, TailwindCSS, and most importantly, the &lt;code&gt;App Router&lt;/code&gt;. After the project completion, change the directory to the project directory and start the local server using the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn dev &lt;span class="c"&gt;# Or its npm, pnpm, bun equivalent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, the local server will run on &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; by default.&lt;/p&gt;
&lt;h2&gt;
  
  
  Auth.js , aka Next-Auth(Version 5)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://authjs.dev/" rel="noopener noreferrer"&gt;Auth.js&lt;/a&gt; is an open-source authentication library that integrates with modern JavaScript frameworks like Next.js, Svelte, and Express. Previously the project was available only for Next.js and thus it used to be called Next-Auth. Today, a portion of Auth.js is still supports &lt;code&gt;Next-Auth&lt;/code&gt;, but along with it, there are &lt;code&gt;SvelteKitAuth&lt;/code&gt;, and &lt;code&gt;ExpressAuth&lt;/code&gt; available too.&lt;/p&gt;
&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;We will use Next-Auth Version 5 which is in its beta while writing this article. Open a terminal and install &lt;code&gt;next-auth&lt;/code&gt; with the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add next-auth@beta

&lt;span class="c"&gt;# Or&lt;/span&gt;
&lt;span class="c"&gt;# npm install next-auth@beta&lt;/span&gt;
&lt;span class="c"&gt;# pnpm add next-auth@beta&lt;/span&gt;
&lt;span class="c"&gt;# bun add next-auth@beta &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Setting up environment
&lt;/h3&gt;

&lt;p&gt;Create a file called &lt;code&gt;.env.local&lt;/code&gt; at the root of your project folder. We need to add a key called &lt;code&gt;AUTH_SECRET&lt;/code&gt; with a value. You can generate the secret by using the following command from your terminal or command prompt:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx auth secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You should see an output like below which prompts you to copy the key-value pair and paste it into the &lt;code&gt;.env.local&lt;/code&gt; file.&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%2F87xgqn3w3ocu1t21ozem.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%2F87xgqn3w3ocu1t21ozem.png" alt="Auth Secret" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, if you are on a Linux / Mac OS X system, you can use the following command to generate the auth secret:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl rand &lt;span class="nt"&gt;-base64&lt;/span&gt; 33
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In whatever ways you generate the secret, please ensure to copy-paste and create a key-value pair in the .env.local file like this:&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%2Fonms3tzdivwzzm4oyd2d.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%2Fonms3tzdivwzzm4oyd2d.png" alt="VS Code - Auth Secret" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Configurations: The &lt;code&gt;auth.js&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;Next, create a &lt;code&gt;auth.js&lt;/code&gt; file at the root of the project folder with the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NextAuth&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;next-auth&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;POST&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;signIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NextAuth&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="c1"&gt;// WE WILL ADD THINGS HERE SHORTLY&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 we have created a minimalistic configuration of the Next-Auth to avail functionalities like &lt;code&gt;signIn&lt;/code&gt;, &lt;code&gt;signOut&lt;/code&gt;, along with an &lt;code&gt;auth&lt;/code&gt; object that can provide us with all information about the session and the logged-in user in the session. The &lt;code&gt;GET&lt;/code&gt;, and &lt;code&gt;POST&lt;/code&gt; handlers will be used in a route handler that we will learn about soon.&lt;/p&gt;

&lt;p&gt;At this point, the only configuration we pass to the &lt;code&gt;NextAuth&lt;/code&gt; is an empty &lt;code&gt;providers&lt;/code&gt; array. However, do not worry much about it, as we will be filling it soon.&lt;/p&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;callback&lt;/code&gt; route
&lt;/h2&gt;

&lt;p&gt;Now we will create a route handler specially for Next-Auth. This route handler will be used as a callback route from the OAuth providers when we configure them after a while.&lt;/p&gt;

&lt;p&gt;Create a folder hierarchy called &lt;code&gt;api/auth/[...nextauth]/&lt;/code&gt; under the &lt;code&gt;app/&lt;/code&gt; folder. The &lt;code&gt;[...nextauth]&lt;/code&gt; directory creates a &lt;a href="https://blog.greenroots.info/dynamic-routes-nextjs-app-router" rel="noopener noreferrer"&gt;dynamic route&lt;/a&gt;. Now create a file called &lt;code&gt;route.js&lt;/code&gt; under this hierarchy as follows: &lt;code&gt;/app/api/auth/[...nextauth]/route.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Copy and paste the following code snippet inside the route.js file.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Here the GET and POST is being imported&lt;/span&gt;
&lt;span class="c1"&gt;// from the auth.js file before we export&lt;/span&gt;
&lt;span class="c1"&gt;// them from here.&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;POST&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;@/auth&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;That's it. We are done with the installation, set-up, and basic configurations of Next-Auth. Let us now shift our focus to building the user interface(UI) needed for the authentication.&lt;/p&gt;
&lt;h2&gt;
  
  
  Create Login Form
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;components&lt;/code&gt; folder at the root of your project folder and create a file called &lt;code&gt;LoginForm.jsx&lt;/code&gt; under it with the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;doSocialLogin&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;@/app/actions&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;LoginForm&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;doSocialLogin&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-pink-400 text-white p-1 rounded-md m-1 text-lg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
                &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
                &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;action&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
                &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&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="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Sign&lt;/span&gt; &lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="nx"&gt;With&lt;/span&gt; &lt;span class="nx"&gt;Google&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-black text-white p-1 rounded-md m-1 text-lg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
                &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
                &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;action&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
                &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;github&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Sign&lt;/span&gt; &lt;span class="nx"&gt;In&lt;/span&gt; &lt;span class="nx"&gt;With&lt;/span&gt; &lt;span class="nx"&gt;GitHub&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A few things to note here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We have created a login form with two submit buttons to sign in with Google and GitHub respectively.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We have imported a server action called &lt;code&gt;doSicialLogin&lt;/code&gt; and using it as the form action so that the function gets invoked when the user submits the form by clicking on either button. The server action function doesn't exist yet, we will create it soon.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each of the submit buttons has the same name attribute value called &lt;code&gt;action&lt;/code&gt;. It is helpful to identify the button that triggers the form submission inside the server action.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Home Page
&lt;/h2&gt;

&lt;p&gt;Now, open the &lt;code&gt;page.js&lt;/code&gt; file under the &lt;code&gt;app/&lt;/code&gt; folder and replace its content with the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LoginForm&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;@/components/LoginForm&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex flex-col justify-center items-center m-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl my-3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;Sign&lt;/span&gt; &lt;span class="nx"&gt;In&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;LoginForm&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It is a simple component that imports the &lt;code&gt;LoginForm&lt;/code&gt; we created above and used it in the JSX. If you try to access the app now, you will get an error due to the non-existence of the &lt;code&gt;doSocialLogin&lt;/code&gt; server action used in the login form. Let's fix that.&lt;/p&gt;
&lt;h2&gt;
  
  
  Next.js Server Actions: Log in and out
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Server Action&lt;/code&gt; in Next.js are built on &lt;code&gt;React Actions&lt;/code&gt; that you can define in server components and/or calls from client components. Server actions are JavaScript &lt;code&gt;async&lt;/code&gt; functions that run on the server by the user interactions with the client.&lt;/p&gt;

&lt;p&gt;It helps to build a data mutation technique more often when you want to submit a form to create, update, or delete data on the server. It can also be useful to perform isolated server-side actions like sending emails, processing payments, user login, logout, and many more use cases.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Read &lt;a href="https://blog.greenroots.info/understanding-nextjs-server-actions-with-examples" rel="noopener noreferrer"&gt;this article&lt;/a&gt; to understand the usages and use cases of Server Actions in-depth.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create a folder called &lt;code&gt;actions/&lt;/code&gt; under the &lt;code&gt;app/&lt;/code&gt; folder. Now, create a file called &lt;code&gt;index.js&lt;/code&gt; under the &lt;code&gt;app/actions/&lt;/code&gt; with the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use server&lt;/span&gt;&lt;span class="dl"&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;signIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signOut&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;@/auth&lt;/span&gt;&lt;span class="dl"&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doSocialLogin&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;action&lt;/span&gt;&lt;span class="dl"&gt;'&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;signIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;redirectTo&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doLogout&lt;/span&gt;&lt;span class="p"&gt;()&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="na"&gt;redirectTo&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let us understand what is happening there.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We used a directive called &lt;code&gt;'use server'&lt;/code&gt; at the top of the file to inform Next.js that this file contains server actions and they must be executed on the server side.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then, we have defined two server actions, &lt;code&gt;doSocialLogin()&lt;/code&gt; and &lt;code&gt;doLogout()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Earlier, the action &lt;code&gt;doSocialLogin()&lt;/code&gt; we have imported into the &lt;code&gt;LoginForm&lt;/code&gt; component to invoke it when the login form is submitted. Hence it receives a formData object containing the information of the submitted form fields. In our case, the login form doesn't have any other fields than two submit buttons sharing the same name value, &lt;code&gt;action&lt;/code&gt;. Hence we retrieve the button value using the &lt;code&gt;action&lt;/code&gt; name to see whether users have clicked on the Google or GitHub buttons to submit the form.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside the &lt;code&gt;doSocialLogin()&lt;/code&gt; function we call the &lt;code&gt;signIn()&lt;/code&gt; from the &lt;code&gt;auth.js&lt;/code&gt; by passing a couple of arguments. The first argument is to tell the &lt;code&gt;Next-Auth&lt;/code&gt; about the provider to use to sign in. In our case, it will be either &lt;code&gt;google&lt;/code&gt; or &lt;code&gt;github&lt;/code&gt;. The second parameter is a configuration object informing auth.js about the redirection page after login. It says, redirect to the home page(/home route) once authenticated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;doLogout()&lt;/code&gt; action invokes the &lt;code&gt;signOut()&lt;/code&gt; function from auth.js and redirect to the root route(/) on log out.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now access the app, you should see it running and showing you the user interface like the image below. Clicking on either of the buttons will not do much as we haven't configured the providers yet, and the great news is, that we will be doing it next.&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%2Fsgj3vvakaqh95heevf65.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%2Fsgj3vvakaqh95heevf65.png" alt="Login Form" width="622" height="420"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Social Login With Google Oauth
&lt;/h2&gt;

&lt;p&gt;Let us make the sign-in with Google work first. This is a multi-step procedure. First, we need to create a client ID and client secret from Google Cloud Console. Once we have them, we need to configure the Google Provider in the &lt;code&gt;auth.js&lt;/code&gt; file,&lt;/p&gt;
&lt;h3&gt;
  
  
  Client ID and Secret from Google
&lt;/h3&gt;

&lt;p&gt;Go to &lt;a href="https://console.cloud.google.com/apis/credentials" rel="noopener noreferrer"&gt;Google Cloud Console&lt;/a&gt; and follow these steps to generate a client ID and secret. You can also use an existing client ID and client secret.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Log in to the Google Cloud console and click on the &lt;code&gt;Credentials&lt;/code&gt; option from the left menu. Then click on the &lt;code&gt;+ CREATE CREDENTIALS&lt;/code&gt; drop down from the top and select the &lt;code&gt;OAuth client ID&lt;/code&gt; option as shown in the image below.&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%2Fa8nzvcsq4b3sp49w4cvm.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%2Fa8nzvcsq4b3sp49w4cvm.png" alt="GCP" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the next screen, select &lt;code&gt;Web application&lt;/code&gt; as an application type, give a suitable name for the OAuth 2.0 client. I preferred to keep it the same as my project name. Then provide &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; as the authorized JavaScript origin URL. It will make sure that the client and secrets can not be used from elsewhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, provide the URL &lt;a href="http://localhost:3000/api/auth/callback/google" rel="noopener noreferrer"&gt;&lt;code&gt;http://localhost:3000/api/auth/callback/google&lt;/code&gt;&lt;/a&gt; as the value of the authorized redirect URI. Does this URI ring a bell 🔔? Yes, this is the same route pattern we created earlier with the &lt;code&gt;route.js&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Finally, click on the &lt;code&gt;CREATE&lt;/code&gt; button.&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%2Fpxkat1n4jma6091ehun9.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%2Fpxkat1n4jma6091ehun9.png" alt="Create OAuth Client ID and Secret" width="697" height="1235"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now you will see a modal dialog with the OAuth client ID and secret created. Make sure you copy them, and optionally you can download them in a JSON file to use later.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on &lt;code&gt;OK&lt;/code&gt; to close the modal.&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%2Fntynatdtuwnmc1pzo10y.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%2Fntynatdtuwnmc1pzo10y.png" alt="Auth Client Created" width="643" height="712"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Set Up Environment
&lt;/h3&gt;

&lt;p&gt;In the &lt;code&gt;.env.local&lt;/code&gt; file add two entries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Key &lt;code&gt;GOOGLE_CLIENT_ID&lt;/code&gt;, and the value will be the client ID we created above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Key &lt;code&gt;GOOGLE_CLIENT_SECRET&lt;/code&gt;, and the value will be the client secret we created above.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Fvymjhsk7mhx8qrre0qsy.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%2Fvymjhsk7mhx8qrre0qsy.png" alt="Google Client ID and Secret" width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Configure the Google Provider for Next-Auth
&lt;/h3&gt;

&lt;p&gt;Open the &lt;code&gt;auth.js&lt;/code&gt; file and import &lt;code&gt;GoogleProvider&lt;/code&gt; as shown below. Also, add the &lt;code&gt;GoogleProvider&lt;/code&gt; configuration in the &lt;code&gt;providers&lt;/code&gt; array as mentioned in the code below.&lt;/p&gt;

&lt;p&gt;Please note,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We are using the client ID and secret from the environment variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We also configured to provide a consent UI for our users to provide their consent to use their Google auth every time they authenticate.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NextAuth&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;next-auth&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="nx"&gt;GoogleProvider&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;next-auth/providers/google&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;POST&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;signIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NextAuth&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;GoogleProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;clientId&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;GOOGLE_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;clientSecret&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;GOOGLE_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;access_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;response_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Test it out from the UI
&lt;/h2&gt;

&lt;p&gt;Now, it's time to test out the &lt;code&gt;Sign in with Google&lt;/code&gt; flow. So, go to the app and click on the button to log in with Google. You will see a redirection to select an account to authenticate. If you have multiple Google accounts, please select the one you want to authenticate with.&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%2F97tjnr2y27tye4vv2bqc.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%2F97tjnr2y27tye4vv2bqc.png" alt="Select an Account - Google" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step will be a consent screen where you have to click on the &lt;code&gt;Continue&lt;/code&gt; button to log in.&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%2F8wgornaya100ycgqyr1s.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%2F8wgornaya100ycgqyr1s.png" alt="Consent Screen - Google" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, you will be redirected to a route called &lt;code&gt;/home&lt;/code&gt; because that's how we have configured the &lt;code&gt;signIn()&lt;/code&gt; function above. You will see a 404-page not found error because we have not created the route yet. However, the best part is, that our authentication is successful.&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%2Fa8dl1jrs466pc7613n5s.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%2Fa8dl1jrs466pc7613n5s.png" alt="Home page 404" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To validate the cookie created for the session token, open up the browser dev tools and move to the &lt;code&gt;Application&lt;/code&gt; tab. In the left panel, expand the &lt;code&gt;Cookies&lt;/code&gt; options and click on the &lt;code&gt;http://localhost:3000&lt;/code&gt;. You should find the &lt;code&gt;authjs.session-token&lt;/code&gt; cookie with the token value at the bottom.&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%2Fvs996n1t9fr657gpedhu.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%2Fvs996n1t9fr657gpedhu.png" alt="Google Auth Cookie" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Show LoggedIn User's Details
&lt;/h3&gt;

&lt;p&gt;It's time to fix the &lt;code&gt;/home&lt;/code&gt; route and show something other than a 404 error. How about showing the logged-in user's details like name and profile image? We can also show a logout option to sign out from the app when the user is already logged in.&lt;/p&gt;

&lt;p&gt;Create a folder called &lt;code&gt;home/&lt;/code&gt; under the &lt;code&gt;app/&lt;/code&gt; folder, and create a &lt;code&gt;page.js&lt;/code&gt; file under the &lt;code&gt;app/home/&lt;/code&gt; with the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&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;next/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;import&lt;/span&gt; &lt;span class="nx"&gt;Logout&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;@/components/Logout&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;auth&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;@/auth&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;redirect&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;next/navigation&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;HomePage&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;session&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;auth&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;session&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="nf"&gt;redirect&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex flex-col items-center m-4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl my-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;session&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;
                &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;session&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;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;session&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rounded-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Logout&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;HomePage&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;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We have created a static route called &lt;code&gt;/home&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We imported the &lt;code&gt;Logout&lt;/code&gt; component. We haven't created the Logout component yet, will do that next.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then we imported &lt;code&gt;auth&lt;/code&gt; from the auth.js. The &lt;code&gt;auth&lt;/code&gt; is an async function that returns us with the session information, including the logged-in user's details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We retrieved the session information and checked if the logged-in user information was available. If not, we redirected the user to the root route where we have the login form. So this way, we can protect a specific route at the page level.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the JSX, we displayed the logged-in user's name and image and the Logout component. Let's create the Logout component.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Add Sign Out(Logout) Functionality
&lt;/h2&gt;

&lt;p&gt;Create a file called &lt;code&gt;Logout.jsx&lt;/code&gt; under the &lt;code&gt;components&lt;/code&gt; folder with the following code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;doLogout&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;@/app/actions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Logout&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;doLogout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; 
            &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bg-blue-400 my-2 text-white p-1 rounded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
            &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nx"&gt;Logout&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Logout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It is a simple React component with a form and a submit button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With the click of a button, we submit the form and invoke the &lt;code&gt;doLogout()&lt;/code&gt; server action we have created already!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. Time for a final test. Perform the login with Google as before. Wait, do you get an error like this instead of seeing the logged-in user's details?&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%2Fwrs53jsttc6sygqk9jzy.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%2Fwrs53jsttc6sygqk9jzy.png" alt="next-image-error" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't worry. It is because we haven't informed Next.js about the source of the profile image coming from Google. Open the &lt;code&gt;next.config.mjs&lt;/code&gt; file and replace the content with the following configuration:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @type {import('next').NextConfig} */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;remotePatterns&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;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lh3.googleusercontent.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;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;nextConfig&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 code above, we have provided the trusted hostname as the image source. The hostname was mentioned in the error as a suggestion for us to configure.&lt;/p&gt;

&lt;p&gt;Now refresh the UI. You should see the home page up and running with the logged-in user's name, image, and a Logout button. Clicking on the Logout button will log you out of the app and take you to the login form.&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%2F6j9zeqfv5c3j37cudh4b.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%2F6j9zeqfv5c3j37cudh4b.png" alt="Successful Home Page" width="614" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, You can also check the cookies like the last time. You will not find the session token cookie when you log out.&lt;/p&gt;

&lt;p&gt;Wow! Finally, we are here after implementing the social login using Google by using Next-Auth/Auth.js.&lt;/p&gt;

&lt;p&gt;Let's finish the configurations for GitHub as well.&lt;/p&gt;
&lt;h2&gt;
  
  
  Social Login With GitHub OAuth
&lt;/h2&gt;

&lt;p&gt;We will be re-using a lot of things done so far. First, let us create the client ID and client secret for a GitHub OAuth app.&lt;/p&gt;
&lt;h3&gt;
  
  
  Client ID and Secret from GitHub
&lt;/h3&gt;

&lt;p&gt;Log in to your GitHub account and go to the developer settings following &lt;a href="https://github.com/settings/developers" rel="noopener noreferrer"&gt;this URL&lt;/a&gt;. Under the &lt;code&gt;OAuth Apps&lt;/code&gt; section, you will find your existing Oauth Apps, if any. Now, create a new OAuth app by clicking the button at the top-right corner of the page.&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%2F4yln5rz5a4uz7arna0yh.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%2F4yln5rz5a4uz7arna0yh.png" alt="Imahe 8" width="800" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you need to fill up a few details like we did for Google. Give a suitable application name, home page URL as &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;, and the authorized callback URL. Please provide &lt;a href="http://localhost:3000/api/auth/callback/github" rel="noopener noreferrer"&gt;&lt;code&gt;http://localhost:3000/api/auth/callback/github&lt;/code&gt;&lt;/a&gt; as the value of the authorized callback URL. Then, register the application.&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%2Fe3ev0cq6xykuchilluqk.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%2Fe3ev0cq6xykuchilluqk.png" alt="Image 1" width="800" height="871"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see a client ID generated. Please copy and keep it safe somewhere. Now, click on the &lt;code&gt;Generate a new client secret&lt;/code&gt; button to create a client secret.&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%2Fskabzuaci716lp3koigd.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%2Fskabzuaci716lp3koigd.png" alt="Image 2" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A new client secret will be generated for you. Please copy and keep this one safe, too.&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%2F108m4rakvminneibfxjp.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%2F108m4rakvminneibfxjp.png" alt="Image 3" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Set Up Environment
&lt;/h3&gt;

&lt;p&gt;Create two new more environment variables &lt;code&gt;GITHUB_CLIENT_ID&lt;/code&gt; and &lt;code&gt;GITHUB_CLIENT_SECRET&lt;/code&gt; and assign the respective values we have created.&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%2Fruw1m9trjymsu7ngw6xf.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%2Fruw1m9trjymsu7ngw6xf.png" alt="Image 4" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Configure GitHub Provider From Next-Auth
&lt;/h3&gt;

&lt;p&gt;The last thing remaining is to configure the GitHub provider. Open the &lt;code&gt;auth.js&lt;/code&gt; file and import the &lt;code&gt;GitHubProvider&lt;/code&gt; as shown below. Then, add the GitHubProvider object in the &lt;code&gt;providers&lt;/code&gt; array.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NextAuth&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;next-auth&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="nx"&gt;GoogleProvider&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;next-auth/providers/google&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="nx"&gt;GitHubProvider&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;next-auth/providers/github&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;POST&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;signIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;signOut&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NextAuth&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nc"&gt;GoogleProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;clientId&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;GOOGLE_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;clientSecret&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;GOOGLE_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;access_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;response_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
        &lt;span class="nc"&gt;GitHubProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;clientId&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;GITHUB_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;clientSecret&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;GITHUB_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;access_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;response_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it. Go back to UI and Sign in with GitHub. You should get a screen to Authorize the Oauth app. Click on the Authorize button.&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%2Fr20xydm6ff9svc713h72.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%2Fr20xydm6ff9svc713h72.png" alt="Image 5" width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Boom! 💥&lt;/p&gt;

&lt;p&gt;The same error as before, but you know how to fix it.&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%2F103q2r7hwayvr2w9g2ts.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%2F103q2r7hwayvr2w9g2ts.png" alt="Image 6" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;next.config.mjs&lt;/code&gt; file and add another entry to the &lt;code&gt;remotePatterns&lt;/code&gt; array for GitHub images.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** @type {import('next').NextConfig} */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;remotePatterns&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;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lh3.googleusercontent.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;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;avatars.githubusercontent.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;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;nextConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now refresh the screen and you should see the logged-in user's name, image, and the Logout button.&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%2Fykuwkg8wxi8cmm0wrnd2.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%2Fykuwkg8wxi8cmm0wrnd2.png" alt="Image 7" width="671" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Incredible! We have learned to set up and code both Google and GitHub Oauth login using Next-Auth/Auth.js with Next.js App Router. It feels amazing!&lt;/p&gt;
&lt;h2&gt;
  
  
  Source Code &amp;amp; Resources
&lt;/h2&gt;

&lt;p&gt;All the source code you have written so far as you explored this article can be found in this repository(under the branch 02-integrate-github-provider).&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/tapascript" rel="noopener noreferrer"&gt;
        tapascript
      &lt;/a&gt; / &lt;a href="https://github.com/tapascript/learn-next-auth" rel="noopener noreferrer"&gt;
        learn-next-auth
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Learn Next-Auth(V5)/Auth.js with plenty of examples, projects, and video tutorials
    &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;Learn Next Auth(Version 5)&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;This repository contains the source code for the educational video on the &lt;a href="https://www.youtube.com/tapasadhikary" rel="nofollow noopener noreferrer"&gt;tapaScript YouTube Channel&lt;/a&gt;. You will find various Next-Auth implementation details and the source code in this repository.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;SUBSCRIBE TO &lt;a href="https://www.youtube.com/@tapasadhikary" rel="nofollow noopener noreferrer"&gt;tapaScript&lt;/a&gt; and support me ❤️ 🙏 ☺️&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The Implementations:&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/tapascript/learn-next-auth/tree/01-integrate-google-provider" rel="noopener noreferrer"&gt;Integrate Google OAUTH&lt;/a&gt; =&amp;gt; &lt;a href="https://www.youtube.com/watch?v=O8Ae6MC5bf4" rel="nofollow noopener noreferrer"&gt;Watch the Video Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tapascript/learn-next-auth/tree/02-integrate-github-provider" rel="noopener noreferrer"&gt;Integrate GitHub OAUTH&lt;/a&gt; =&amp;gt; &lt;a href="https://www.youtube.com/watch?v=O8Ae6MC5bf4" rel="nofollow noopener noreferrer"&gt;Watch the Video Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tapascript/learn-next-auth/tree/03-credential-auth" rel="noopener noreferrer"&gt;Next-Auth Credential Provider&lt;/a&gt; =&amp;gt; &lt;a href="https://www.youtube.com/watch?v=4m7u7zGbdTI" rel="nofollow noopener noreferrer"&gt;Watch the Video Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tapascript/learn-next-auth/tree/04-persist-auth-mongo" rel="noopener noreferrer"&gt;Next.js Authentication || Register User To MongoDB With Next-Auth V5&lt;/a&gt; =&amp;gt; &lt;a href="https://www.youtube.com/watch?v=5kmZAqc2Jeg" rel="nofollow noopener noreferrer"&gt;Watch the Video Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tapascript/learn-next-auth/tree/05-middleware" rel="noopener noreferrer"&gt;Next.js Middleware Crash Course || App Router Protected Routes&lt;/a&gt; =&amp;gt; &lt;a href="https://www.youtube.com/watch?v=jHrjnZM26i4" rel="nofollow noopener noreferrer"&gt;Watch the Video Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tapascript/learn-next-auth/tree/06-token-management" rel="noopener noreferrer"&gt;Refresh Token Rotation With Next-Auth V5 || Managing Tokens&lt;/a&gt; =&amp;gt; &lt;a href="https://youtu.be/95fuP8jpWlk" rel="nofollow noopener noreferrer"&gt;Watch the Video Tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Liked my work? You can show your support with a STAR(⭐).&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Many Thanks to all the &lt;code&gt;Stargazers&lt;/code&gt; who have supported this project with stars(⭐)&lt;/h3&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/tapascript/learn-next-auth/stargazers" rel="noopener noreferrer"&gt;Thanks to all stargazers&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🙏 Please Sponsor My Work&lt;/h2&gt;

&lt;/div&gt;


&lt;blockquote&gt;

&lt;p&gt;I am an…&lt;/p&gt;


&lt;/blockquote&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/tapascript/learn-next-auth" 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;If you like the work, do not forget to encourage me with a star ⭐.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Learning
&lt;/h2&gt;

&lt;p&gt;If you enjoyed this article and developing the app, you may also like to explore a few more related topics on Next.js and Auth.js. Here are the links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4m7u7zGbdTI" rel="noopener noreferrer"&gt;&lt;strong&gt;Next.js Authentication With Next-Auth V5 Credential Provider&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=5kmZAqc2Jeg" rel="noopener noreferrer"&gt;&lt;strong&gt;Next.js Authentication - Register User To MongoDB With Next-Auth V5&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=jHrjnZM26i4" rel="noopener noreferrer"&gt;&lt;strong&gt;Next.js Middleware Crash Course &amp;amp; Protected Routes&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Check out the Complete Next-Auth(V5) Course for FREE
&lt;/h2&gt;

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




&lt;p&gt;Liked it? Please let me know with your comments and likes. ❤️&lt;/p&gt;

&lt;p&gt;Let's connect. I share knowledge on web development, content creation, Open Source, and careers on these platforms.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/tapasadhikary?sub_confirmation=1" rel="noopener noreferrer"&gt;&lt;strong&gt;tapaScript on YouTube&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/tapasadhikary" rel="noopener noreferrer"&gt;&lt;strong&gt;X(Twitter)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/in/tapasadhikary/" rel="noopener noreferrer"&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/atapas" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>authenticaton</category>
      <category>react</category>
      <category>beginners</category>
    </item>
    <item>
      <title>CreoConnect 2024 - From the Founder's Book</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Thu, 19 Dec 2024 13:56:23 +0000</pubDate>
      <link>https://dev.to/creowistech/creoconnect-2024-from-the-founders-book-4fb9</link>
      <guid>https://dev.to/creowistech/creoconnect-2024-from-the-founders-book-4fb9</guid>
      <description>&lt;p&gt;Indeed we love discussing technical matters and are encouraged to share our tech knowledge, but this one has to be different. Yes! let’s talk about our most celebrated event that we have concluded recently, &lt;code&gt;CreoConnect&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is it important to talk about CreoConnect?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;CreoWis&lt;/code&gt; being a startup in its infancy is as curious as any other human baby. It looks up to things with surprise, excitement, emotion, and enthusiasm to explore the new. Be it a service we provide to our customers, or a product that we incubate, the curiosity quotient always remains high.&lt;/p&gt;

&lt;p&gt;Needless to say(but, still essential to mention), any organization, be it a small startup, midscale, or a big MNC is the collective of its people. Each skilled individual works with others in the organization to make it grow. For a remote company like CreoWis, we must not miss out on the opportunities to celebrate those individuals who are helping it to grow. Hence &lt;code&gt;CreoConnect&lt;/code&gt; - an annual event to connect in person to know each other better, gain more trust, have fun, and understand what it takes to get things done together.&lt;/p&gt;

&lt;p&gt;So, it is essential to talk about CreoConnect and get some insights on what went on to make it happen and how it might help us to do better in the future. If you are also a startup like us or with an entrepreneurial mindset, our learning may help you in doing something similar, or even bigger.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dream from Day One
&lt;/h2&gt;

&lt;p&gt;In mid-2023 when my co-founder and I were digesting the fact that we will have a remote software company together, we were already dreaming about many other possibilities! One of them was celebrating work.&lt;/p&gt;

&lt;p&gt;We didn’t have much idea of how much we would grow in a year, how big the team was going to be, and how many customers we would deal with. However, we were clear that we would have an annual event to celebrate our people, work, and achievements - that’s pretty much what CreoConnect is today. The first instalment of CreoConnect also marks the one-year completion of CreoWis with almost the same set of folks it had started with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before the event
&lt;/h2&gt;

&lt;p&gt;The first thing we needed was a name for the event with a wish that we could repeat it on every occurrence. If you think, what’s in a name? I would say a lot. You start sinking into it, start liking it, living it. It may also create a brand for you. So, choose wisely!&lt;/p&gt;

&lt;p&gt;In our case, it was a bit straightforward. We said, let’s poll, and we got &lt;code&gt;CreoConnect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljf2iztcn3ebkzu4vmra.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%2Fljf2iztcn3ebkzu4vmra.png" alt="CreoConnect Poll" width="800" height="1187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An event like CreoConnect needs solid planning. You need to plan travels, stay, food, activities, logistics, itinerary, and many more tiny things that fulfil it. We, the founders, started the planning almost 3-4 months before to sketch out the timeline, budget, and necessities. A lot of research went into understanding what would be the “best” for all of us, or what most of us would be so proud about. Must say, we have thoroughly enjoyed the process of getting the dream closer to reality.&lt;/p&gt;

&lt;p&gt;A month before the event, we announced it to the team on a Discord call. The outburst of happiness and excitement was sky-high. The team took the charge of making the event even more memorable. A daily dose of countdown on the CreoWis Discord server used to act like a positive catalyst, and was enough to create the adrenaline rush among us every morning.&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%2Fzxpi5ezs630kfsapm1me.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%2Fzxpi5ezs630kfsapm1me.png" alt="Countdown on Discord" width="800" height="786"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the day was coming near, we got the idea of shooting a video capturing what CreWis means to each of us, in our vision where do we want to see the company in a few years, and what are we expecting from the CreoConnect 2024? It was truly amazing to see each of us getting involved and bringing the best points out about those.&lt;/p&gt;

&lt;p&gt;If you are interested, go over this 6-minute video, hoping you will enjoy it.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  CreoConnect 2024 - The annual company event
&lt;/h2&gt;

&lt;p&gt;Finally, it was the time. &lt;code&gt;CreoConnect 2024&lt;/code&gt; was a 3-day in-person event between the 6th to 8th December 2024. On the 6th, all our employees from the different parts of the geo gathered together in Bangalore, India to celebrate. For most of us, it was the first time when we had seen each other in person and got the warmth and the instant bonding we anticipated.&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%2Flom72iz9ofaibab958yc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flom72iz9ofaibab958yc.jpeg" alt="CreoWis Folks Meeting first time" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not miss this one(with audio ON): &lt;a href="https://www.youtube.com/shorts/jVmhIK1h0bU" rel="noopener noreferrer"&gt;https://www.youtube.com/shorts/jVmhIK1h0bU&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first day was fun-filled with catching up with each other, sharing positive vibes, and spending a fantastic time together at the dinner. We connected so well there that it felt like we were meeting each other in person every day. A long walk together after the dinner had made things even more special.&lt;/p&gt;

&lt;p&gt;The second day started with our team meeting called, &lt;code&gt;Creo-Catchup&lt;/code&gt;. It is our monthly sync-up with company updates, but this time it was a bit different. We covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CreoWis formation history&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Last 1 year&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The future projections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Service Award&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Star Award&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A couple of minutes of short speech from everyone&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Right after the meeting, it was a fun time. We caught up with a bunch of group activities, photos, food, games, and networking.&lt;/p&gt;

&lt;p&gt;The last day was for us to return home. But before that, we spent a great time talking to each other, snapping some special moments, and making a point that the upcoming CreoConnect event is going to be even bigger.&lt;/p&gt;

&lt;p&gt;Here are some moments we cherish together, hope you like them, too.&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%2Fcs3tiuyc6lzbpv0upz8q.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcs3tiuyc6lzbpv0upz8q.jpeg" alt="CreoConnect 2024 Collage" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also catch up more about the event on our &lt;a href="https://www.instagram.com/creowis/" rel="noopener noreferrer"&gt;Instagram Page&lt;/a&gt; and &lt;a href="https://www.youtube.com/@creowis" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;We have some key takeaways from the event that we believe going to strengthen our core values.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We work together best as friends, people, and humans, rather than resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The culture of a company may not be built in a day, but it gets seeded very early. The more we nurture it with the right ingredients, the better it blossoms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you are a team, behave like a team. Transparency is the key. Be open with your thoughts and articulation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Treat others the way you want to be treated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Last, but not least, the feeling of belongingness and ownership. This place is for me, I make it better. If things are not going well at times, I need to step up and fix them.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am extremely proud of our team at CreoWis. I hope to write a bigger sequel of this post sometime in 2025 with some more faces getting added. Until then, Keep going.&lt;/p&gt;




&lt;p&gt;If you have read so far, thanks! It means you care. Please feel free to share this article in your social circle. We at &lt;a href="https://creowis.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;CreoWis&lt;/strong&gt;&lt;/a&gt; believe in sharing knowledge publicly to help the developer community grow. Let’s collaborate, ideate, and craft passion to deliver awe-inspiring software services &amp;amp; product experiences.&lt;/p&gt;

&lt;p&gt;Want to work with us? Let’s connect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://wa.me/c/918904501731" rel="noopener noreferrer"&gt;Call/Message us&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="//mailto:hello@creowis.com"&gt;E-mail us&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/creowistech" rel="noopener noreferrer"&gt;Follow us on X/Twitter&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/company/creowis" rel="noopener noreferrer"&gt;Follow us LinkedIn&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.creowis.com/" rel="noopener noreferrer"&gt;Check out our offerings&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This article is crafted by &lt;strong&gt;Tapas Adhikary&lt;/strong&gt;, Co-Founder at CreoWis. You can reach out to him on &lt;a href="https://x.com/tapasadhikary" rel="noopener noreferrer"&gt;&lt;strong&gt;X/Twitter&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/tapasadhikary/" rel="noopener noreferrer"&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;,&lt;/strong&gt; and follow his work on the &lt;a href="https://github.com/atapas" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://youtube.com/@tapasadhikary" rel="noopener noreferrer"&gt;&lt;strong&gt;YouTube&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>workplace</category>
      <category>startup</category>
      <category>tutorial</category>
      <category>career</category>
    </item>
    <item>
      <title>Build a custom image uploader with ReactJS</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Mon, 11 Mar 2024 06:37:44 +0000</pubDate>
      <link>https://dev.to/atapas/build-a-custom-image-uploader-with-reactjs-4m8b</link>
      <guid>https://dev.to/atapas/build-a-custom-image-uploader-with-reactjs-4m8b</guid>
      <description>&lt;p&gt;Uploading and previewing images are fundamental requirements in any modern user-centric application. Be it Facebook, Instagram, WhatsApp, Twitter, LinkedIn, whatever you name, you have it there.&lt;/p&gt;

&lt;p&gt;In this article, we will learn how to handle image upload and preview in a ReactJS application. Just a callout, we will not use any external(3rd-party) library for this. Rather, we will build it from scratch to understand what happens under the hood. With me? Let's get started with the setup.&lt;/p&gt;

&lt;p&gt;If you want to learn from the video content, this article is available as a video tutorial. Please take a look. 🙂&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/nOqsd8LoUYs"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  Setup a ReactJS app with Vite and TailwindCSS
&lt;/h2&gt;

&lt;p&gt;We will use TailwindCSS with React and by tradition, let us create a React project scaffolding with Vite. The good news is, that you do not have to do all the installation and configurations from scratch. You can use &lt;a href="https://github.com/atapas/vite-tailwind-react" rel="noopener noreferrer"&gt;this template repository&lt;/a&gt; to create your project repository with Vite and TailwindCSS configured with React.&lt;/p&gt;

&lt;p&gt;Click on the &lt;code&gt;Use this template&lt;/code&gt; button at the top-right corner of the template repository. It will take you to the next page to provide the new repository details.&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%2Feiqmhn13o8h0nhm30dsw.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%2Feiqmhn13o8h0nhm30dsw.png" alt="Template Repository" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next page, provide the new repository name, and a suitable description, and create the repository. Let us call the new repository as &lt;code&gt;image-uploader&lt;/code&gt; in this article.&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%2Frdk2sdilnxo7xa4no4sh.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%2Frdk2sdilnxo7xa4no4sh.png" alt="Create Repository with details" width="800" height="735"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, clone the new repository to get the project folder locally. Change the directory to the project folder and install the required dependencies using npm/yarn/pnpm.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make sure you have Node.js version 18 or above installed. You can try the command &lt;code&gt;node -v&lt;/code&gt; to find out the version installed. If you want to install or upgrade to the required version of Node.js, please do it from &lt;a href="https://nodejs.org/en/download" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;## With NPM&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;## With Yarn&lt;/span&gt;
yarn &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;## With PNPM&lt;/span&gt;
pnpm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can run the project locally 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="c"&gt;## With NPM&lt;/span&gt;
npm run dev

&lt;span class="c"&gt;## With Yarn&lt;/span&gt;
yarn dev

&lt;span class="c"&gt;## With PNPM&lt;/span&gt;
pnpm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application will be available to access on the URL &lt;a href="http://localhost:5173/" rel="noopener noreferrer"&gt;&lt;code&gt;http://localhost:5173/&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5q74qxprxuisfu2ras3m.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%2F5q74qxprxuisfu2ras3m.png" alt="Initial UI" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great, we have got the initial setup done. You can import the project into your favourite code editor. Let us now create the image uploader component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete the uploader structure
&lt;/h2&gt;

&lt;p&gt;Create a &lt;code&gt;components&lt;/code&gt; directory under the &lt;code&gt;src&lt;/code&gt; directory. Now, create a file called &lt;code&gt;ImageUpload.jsx&lt;/code&gt; under the &lt;code&gt;src/components&lt;/code&gt;. This file will contain the React component to upload and preview images.&lt;/p&gt;

&lt;p&gt;Before we start writing the code for the image uploader, we need a few things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;code&gt;default image&lt;/code&gt; to tell our users about the image uploader.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An &lt;code&gt;edit icon&lt;/code&gt; to invoke the file browser to select an image.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;code&gt;loading gif&lt;/code&gt; file we will use as a placeholder when the file upload is in progress.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please copy the image files &lt;a href="https://github.com/atapas/youtube/tree/main/react/28-react-image-uploader/src/assets" rel="noopener noreferrer"&gt;from here&lt;/a&gt; to your project's &lt;code&gt;src/assets&lt;/code&gt; directory. Now, go back to the &lt;code&gt;ImageUpload.jsx&lt;/code&gt; file and start coding the component.&lt;/p&gt;

&lt;p&gt;First, import the images we just copied. We will also need the &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useRef&lt;/code&gt; hooks from React. So, copy and paste the following import statements at the top of the component file,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DefaultImage&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;../assets/upload-photo-here.png&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="nx"&gt;EditIcon&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;../assets/edit.svg&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="nx"&gt;UploadingAnimation&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;../assets/uploading.gif&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's create the component function right below the import statements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// --- Import statements as belore&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="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;avatarURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAvatarURL&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="nx"&gt;DefaultImage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative h-96 w-96 m-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; 
                &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;avatarURL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Avatar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h-96 w-96 rounded-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;

              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;encType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;multipart/form-data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;
                  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
                  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex-center absolute bottom-12 right-14 h-9 w-9 rounded-full&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;
                    &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;EditIcon&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object-cover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&amp;gt; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;         &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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;Let's understand the above code snippet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We have created a functional react component(called, &lt;code&gt;ImageUpload&lt;/code&gt;). The component has a state called &lt;code&gt;avatarURL&lt;/code&gt; which is set with an initial value, the default image. We did this to ensure that the page is not blunt and blank, and we show an upload message to our users with that default image.&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%2Fr9yu7ivpgdw2lbdbxi42.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%2Fr9yu7ivpgdw2lbdbxi42.png" alt="The Default Image" width="692" height="649"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will change the value of the state later programmatically when the user starts uploading an image and when the image upload completes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, we have a fairly simple JSX that shows this default image using the &lt;code&gt;avatarURL&lt;/code&gt; state value. We also have a form with a button and an edit icon underneath. We are introducing this form early so that we can handle the file input in a while.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, we exported the &lt;code&gt;ImageUpload&lt;/code&gt; component so that we can import it into the &lt;code&gt;App.jsx&lt;/code&gt; file for rendering.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please open the &lt;code&gt;App.jsx&lt;/code&gt; file and replace its content with the following code snippet,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ImageUpload&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;./components/ImageUpload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ImageUpload&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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;Here we have imported the &lt;code&gt;ImageUpload&lt;/code&gt; component and used it in the JSX of the App component. We have surrounded it with a DIV to align it better on the page.&lt;/p&gt;

&lt;p&gt;Next, optionally you can change a few things in the &lt;code&gt;index.html&lt;/code&gt; file. We have changed the app's title. You can make the change in the &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; tag under the &lt;code&gt;&amp;lt;head&amp;gt;...&amp;lt;/head&amp;gt;&lt;/code&gt;. Also, we have provided a few classes to the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; to get a darker background(most folks love dark mode these days!).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"icon"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"image/svg+xml"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/vite.svg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;React Image Uploader&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-black bg-opacity-90"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/src/main.jsx"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us go over the browser and see the app.&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%2F5yudc8yms0071rvolhx2.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%2F5yudc8yms0071rvolhx2.png" alt="The Uploader with a placeholder image and edit icon" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see a yellow rounded image with the &lt;code&gt;Upload&lt;/code&gt; text and a &lt;code&gt;hand icon&lt;/code&gt; pointing towards an &lt;code&gt;edit icon&lt;/code&gt; indicating that you can click on the edit icon to start the uploading process. Cool, huh?&lt;/p&gt;

&lt;p&gt;Let us now handle the input file type to select an image for uploading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling the file chooser
&lt;/h2&gt;

&lt;p&gt;Now we need to add a file chooser to our component. We will be using HTML's input element with the type &lt;code&gt;file&lt;/code&gt;. Please add the input type file inside the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element in the JSX as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ImageUpload&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;// --- All code like before&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;{&lt;/span&gt;&lt;span class="cm"&gt;/* --- All code like before */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;encType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;multipart/form-data&lt;/span&gt;&lt;span class="dl"&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="cm"&gt;/* --- The Button code like before */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; 
              &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&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="nx"&gt;id&lt;/span&gt;&lt;span class="o"&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="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we go to the UI now, we will see a file chooser with an option to &lt;code&gt;Choose file&lt;/code&gt;. You can click on it to select files. It works but it doesn't look great. Also, we do not want our users to click on that button to choose files, rather, they should perform the same operation by clicking on the edit icon we added before.&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%2Fif4v8nhjtgzj1azv3vux.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%2Fif4v8nhjtgzj1azv3vux.png" alt="input type file in its raw format" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing the uploader with reference(useRef)
&lt;/h2&gt;

&lt;p&gt;let's fix that. We have to do two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hide the input file type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refer to the input file type from the edit icon such that, when we click on the edit icon, it simulates the click on the &lt;code&gt;Choose file&lt;/code&gt; button of the file input type(yes, even when it is hidden!).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;React provides us with a standard hook called &lt;code&gt;useRef&lt;/code&gt; which allows one to refer to a DOM element and get access to its properties. It means we can create a reference to the file input type using the &lt;code&gt;useRef&lt;/code&gt; hook and use that reference to simulate a click action on the edit icon click. Does it sound promising yet confusing? Don't worry, let's see the code and understand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are looking for an in-depth understanding of the useRef hook, I have a foundational &lt;a href="https://www.youtube.com/watch?v=LNwEpMLLFTw" rel="noopener noreferrer"&gt;video here&lt;/a&gt;. Please check it out.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, hide the file input by adding a &lt;code&gt;hidden&lt;/code&gt; property to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
   &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;
   &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;
   &lt;span class="err"&gt;hidden&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a reference using the &lt;code&gt;useRef&lt;/code&gt; hook at the top of your component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ImageUpload&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;avatarURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAvatarURL&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="nx"&gt;DefaultImage&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;fileUploadRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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="c1"&gt;// --- Rest of the code as is below&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this &lt;code&gt;fileUploadRef&lt;/code&gt; as the value of the &lt;code&gt;ref&lt;/code&gt; attribute to the file input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt; &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
    &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{fileUploadRef}&lt;/span&gt;
    &lt;span class="err"&gt;hidden&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So. from now on, the &lt;code&gt;fileUploadRef.current&lt;/code&gt; will refer to the file input element. We will use it to simulate a click event.&lt;/p&gt;

&lt;p&gt;Add an &lt;code&gt;onClick&lt;/code&gt; property to the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; inside the form, and add an event handler function called &lt;code&gt;handleImageUpload&lt;/code&gt; as a value of it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt; &lt;span class="na"&gt;encType=&lt;/span&gt;&lt;span class="s"&gt;'multipart/form-data'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
        &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;'submit'&lt;/span&gt;
        &lt;span class="na"&gt;onClick=&lt;/span&gt;&lt;span class="s"&gt;{handleImageUpload}&lt;/span&gt;
        &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;'flex-center absolute bottom-12 right-14 h-9 w-9 rounded-full'&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt;
                &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;{EditIcon}&lt;/span&gt;
                &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Edit"&lt;/span&gt;
                &lt;span class="na"&gt;className=&lt;/span&gt;&lt;span class="s"&gt;'object-cover'&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing that remains is to defile the &lt;code&gt;handleImageUpload&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleImageUpload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&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 you see in the code above, we now invoke the &lt;code&gt;click()&lt;/code&gt; function using the &lt;code&gt;fileUploadRef.current&lt;/code&gt;. It means, the click on the file input will occur and we will see the file chooser opens up when someone clicks on the edit icon.&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%2Fu5ycyp2vo1uzpe7ubpnx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5ycyp2vo1uzpe7ubpnx.gif" alt="Clicking on Edit icon opens up the file chooser." width="720" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this stage, the code of the &lt;code&gt;ImageUpload&lt;/code&gt; component will be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&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&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="nx"&gt;DefaultImage&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;../assets/upload-photo-here.png&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="nx"&gt;EditIcon&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;../assets/edit.svg&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="nx"&gt;UploadingAnimation&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;../assets/uploading.gif&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="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;avatarURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAvatarURL&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="nx"&gt;DefaultImage&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;fileUploadRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;handleImageUpload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative h-96 w-96 m-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; 
        &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;avatarURL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
        &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Avatar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
        &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h-96 w-96 rounded-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;encType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;multipart/form-data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleImageUpload&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex-center absolute bottom-12 right-14 h-9 w-9 rounded-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; 
            &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;EditIcon&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
            &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
            &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object-cover&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; 
            &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&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="nx"&gt;id&lt;/span&gt;&lt;span class="o"&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="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
            &lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="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;All these are great, but, have you noticed that nothing really happens when you select an image and click on the &lt;code&gt;Open&lt;/code&gt; button from the file chooser? Let's handle that part now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling the file change event
&lt;/h2&gt;

&lt;p&gt;To capture the selected file and its information, we need to add a change handler on the file input. Please add an &lt;code&gt;onChange&lt;/code&gt; property to the file input along with a change handler function &lt;code&gt;uploadImageDisplay&lt;/code&gt; as a value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
    &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;
    &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;
    &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;{fileUploadRef}&lt;/span&gt;
    &lt;span class="na"&gt;onChange=&lt;/span&gt;&lt;span class="s"&gt;{uploadImageDisplay}&lt;/span&gt;
    &lt;span class="err"&gt;hidden&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's define the &lt;code&gt;uploadImageDisplay&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadImageDisplay&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;uploadedFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cachedURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;uploadedFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setAvatarURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cachedURL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things happening here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We read the uploaded file information from the &lt;code&gt;files[0]&lt;/code&gt; property. The &lt;code&gt;files&lt;/code&gt; array contains information about all the files selected using the file chooser. As we are supporting(or rather concerned) about only one image file at a time, we can assume the first element of the &lt;code&gt;files&lt;/code&gt; array will get us that information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, we use the &lt;code&gt;URL.createObjectURL&lt;/code&gt; to get the cached path of the uploaded file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, we set that file path as a value to the state variable we have been maintaining to show the default and uploaded image.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Previewing the uploaded image from the browser cache
&lt;/h2&gt;

&lt;p&gt;Now, if you select an image from the file chooser and click on the &lt;code&gt;Open&lt;/code&gt; button at the bottom,&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%2Fqu2n3mqtnh6wlj154w7q.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%2Fqu2n3mqtnh6wlj154w7q.png" alt="File Browser" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see the image got uploaded and it previewed immediately.&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%2Ffdknm2vtng3qfz2ci0jf.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%2Ffdknm2vtng3qfz2ci0jf.png" alt="File Preview From Client Cache" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is great! But, it would be even fantastic if we could upload this image to a server and get a link as a response to preview it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Uploading the image to the server
&lt;/h2&gt;

&lt;p&gt;I have found &lt;a href="https://api.escuelajs.co/api/v1/files/upload" rel="noopener noreferrer"&gt;this public API&lt;/a&gt; that supports file upload on a server. So now, we will make a POST call to this API with the selected file as a payload. Let us change the &lt;code&gt;uploadImageDisplay&lt;/code&gt; function to make it happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadImageDisplay&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setAvatarURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UploadingAnimation&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;uploadedFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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="c1"&gt;// const cachedURL = URL.createObjectURL(uploadedFile);&lt;/span&gt;
      &lt;span class="c1"&gt;// setAvatarURL(cachedURL);&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;uploadedFile&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;response&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;fetch&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://api.escuelajs.co/api/v1/files/upload&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;setAvatarURL&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;location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setAvatarURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DefaultImage&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;Let us understand the function above:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initially, we set the &lt;code&gt;avatarURL&lt;/code&gt; state value with the loading image.&lt;/li&gt;
&lt;/ul&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%2Fw6p8eqnni9ao133rf6cp.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%2Fw6p8eqnni9ao133rf6cp.png" alt="The Loading State" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We have commented out the code to show the image from the browser cache.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We created a form data with the key &lt;code&gt;file&lt;/code&gt; as the API expects it this way.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then we used the &lt;code&gt;fetch&lt;/code&gt; Web API to make a POST call with the form data as the payload.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On receiving the response, we check if the status code is &lt;code&gt;201&lt;/code&gt;, which means the file has been uploaded successfully. We read the response data and get the uploaded image URL from the &lt;code&gt;data?.location&lt;/code&gt;. We set that as the updated state value. Hence, the loading image will be replaced with the uploaded image.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2F7p62qrenicp9da1gcgvd.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%2F7p62qrenicp9da1gcgvd.png" alt="Image Preview From the Response" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If there is an error, we set the state value to the default image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations!!! You have done it.&lt;/p&gt;

&lt;p&gt;Here is the complete code of the &lt;code&gt;ImageUpload&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DefaultImage&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;../assets/upload-photo-here.png&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="nx"&gt;EditIcon&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;../assets/edit.svg&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="nx"&gt;UploadingAnimation&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;../assets/uploading.gif&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="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;avatarURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAvatarURL&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="nx"&gt;DefaultImage&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;fileUploadRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;handleImageUpload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&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;uploadImageDisplay&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setAvatarURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UploadingAnimation&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;uploadedFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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="c1"&gt;// const cachedURL = URL.createObjectURL(uploadedFile);&lt;/span&gt;
      &lt;span class="c1"&gt;// setAvatarURL(cachedURL);&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;uploadedFile&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;response&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;fetch&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://api.escuelajs.co/api/v1/files/upload&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;body&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nf"&gt;setAvatarURL&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;location&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;setAvatarURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DefaultImage&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative h-96 w-96 m-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; 
        &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;avatarURL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;alt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Avatar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h-96 w-96 rounded-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;encType&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;multipart/form-data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleImageUpload&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex-center absolute bottom-12 right-14 h-9 w-9 rounded-full&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;
            &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;EditIcon&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Edit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object-cover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; 
          &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&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="nx"&gt;id&lt;/span&gt;&lt;span class="o"&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="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;fileUploadRef&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;uploadImageDisplay&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&amp;gt; &lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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;h2&gt;
  
  
  A couple of tasks for you!
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed learning from this article and it helped you to understand the concept. All the source code used in this article can be found on my GitHub.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/atapas/youtube/tree/main/react/28-react-image-uploader" rel="noopener noreferrer"&gt;https://github.com/atapas/youtube/tree/main/react/28-react-image-uploader&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before we end, I would like to give you a couple of tasks to implement on top of whatever we have done so far:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Right now, the file chooser accepts all sorts of file types. Can you restrict it to accept only the image type files, i.e., .png, .jpg, .svg, etc?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Right now, the file chooser appears when we click the edit icon. Can you make the code changes to make it appear when you click on anywhere on the image?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you happen to do these, please let me know. My socials are mentioned below. You can also join &lt;a href="https://discord.gg/BAQbwKASDJ" rel="noopener noreferrer"&gt;tapaScript discord&lt;/a&gt; where we learn and share things.&lt;/p&gt;




&lt;p&gt;Let's connect. I share knowledge on web development, content creation, Open Source, and careers on these platforms.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/tapasadhikary?sub_confirmation=1" rel="noopener noreferrer"&gt;&lt;strong&gt;tapaScript on YouTube&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/tapasadhikary" rel="noopener noreferrer"&gt;&lt;strong&gt;X(eka Twitter)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/in/tapasadhikary/" rel="noopener noreferrer"&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/atapas" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>10 Git stash commands every developer should know</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Fri, 08 Dec 2023 05:10:52 +0000</pubDate>
      <link>https://dev.to/atapas/10-git-stash-commands-every-developer-should-know-96d</link>
      <guid>https://dev.to/atapas/10-git-stash-commands-every-developer-should-know-96d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Git Stash is an extremely useful tool for developers. Learn the usage of the git stash commands to become a productive developer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Developers are agile. Their work environments are also rapid and fast-moving to keep them on their toes most of the time. I can imagine a situation like this would be quite normal at your workplace:&lt;/p&gt;

&lt;p&gt;You are working on a feature and, in between, making some changes that are still too unstable to commit. Now, your boss(they say the boss is always right!) comes over with a rush and informs you that a valued customer is facing the deadliest issue in production. You must take care of it RIGHT NOW.&lt;/p&gt;

&lt;p&gt;You don't want to commit unstable changes to your current branch, but you have to switch to another branch and fix the issue to make your customer(and, of course, the boss) happy. However, &lt;code&gt;git&lt;/code&gt; doesn't allow you to switch branches without your current changes for the tracked files being committed to the current branch. Wow, what a chicken and egg problem!&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%2Fkzd0r8c6yeirr4jhjj58.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%2Fkzd0r8c6yeirr4jhjj58.png" alt="Chicken-Egg Problem" width="750" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't worry, we have &lt;code&gt;git stash&lt;/code&gt; to rescue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Welcome to Git stash
&lt;/h2&gt;

&lt;p&gt;The word &lt;code&gt;stash&lt;/code&gt; means storing something safely in a hidden and secret place. In the world of git, it tracks your files and folders for changes for everyone's visibility, and with &lt;code&gt;git stash&lt;/code&gt;, it also provides a way to secretly put some changes that are only known to you so that you can hide them and again bring them back when required.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;git stash&lt;/code&gt; command allows you to save the uncommitted changes locally, switch the branch to do other things, and return to your unfinished work along with the stashed changes. The workflow goes like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You are in branch &lt;strong&gt;feature/A-branch&lt;/strong&gt; where you have uncommitted changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You stash the changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You then switch to another branch &lt;strong&gt;feature/B-branch&lt;/strong&gt; to finish the work. You commit(and push) the changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You switched back to the &lt;strong&gt;feature/A-branch&lt;/strong&gt; branch, applied your stashed changes, and continued your work.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The command that you use to stash your changes is:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We will learn the usages for 10 commands related to the &lt;code&gt;git stash&lt;/code&gt; in this article. If you are a beginner to git and want to know its fundamentals along with frequently used commands, here is a read for you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  &lt;a href="https://blog.greenroots.info/top-10-git-commands-every-developer-should-know" rel="noopener noreferrer"&gt;Top 10 Git Commands Every Developer Should Know&lt;/a&gt;
&lt;/h1&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ✅ Stash your changes
&lt;/h2&gt;

&lt;p&gt;You can have two types of uncommitted changes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The staged changes that git is tracking. It means you have used the &lt;code&gt;git add&lt;/code&gt; command to stage them but haven't committed them yet using the &lt;code&gt;git commit&lt;/code&gt; command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The unstaged changes that git is not tracking. It is a file that you haven't staged using the &lt;code&gt;git add&lt;/code&gt; command.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the following command to stash a staged change:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="c"&gt;# You can also use `git stash save &amp;lt;description&amp;gt;` command to &lt;/span&gt;
&lt;span class="c"&gt;# save a stash with a description.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will create a stash in the stack with a unique reference ID.&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%2Fbabao1sdxya75droim3u.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%2Fbabao1sdxya75droim3u.png" alt="git stash" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to stash an unstaged change, use the &lt;code&gt;-u&lt;/code&gt; switch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash &lt;span class="nt"&gt;-u&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it will add one more entry to the stash stack.&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%2Ftbvdor61yphor5pva6qu.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%2Ftbvdor61yphor5pva6qu.png" alt="stash untracked" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use the &lt;code&gt;git stash -a&lt;/code&gt; command to stash all the files, including the hidden files.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ List all the stashes
&lt;/h2&gt;

&lt;p&gt;You can list all the stashes from the stash stack using this command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It will list all the stashes in a stack, meaning the latest stash will be at the top. Also, notice the format of the stash reference IDs. They are in the format &lt;code&gt;stash@{0}&lt;/code&gt;. The number in the curly braces shows their position in the stash stack, &lt;code&gt;0&lt;/code&gt; being the top.&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%2Fx2ej7bdznc071d6ias93.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%2Fx2ej7bdznc071d6ias93.png" alt="list stash" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Create a stash without a reference log entry
&lt;/h2&gt;

&lt;p&gt;So far, we have created all the stashes with a reference ID. We have seen the &lt;code&gt;git stash list&lt;/code&gt; command show them in the reflog. However, you can create a stash without logging it's reference to the stash reflog.&lt;/p&gt;

&lt;p&gt;To do that, use the &lt;code&gt;create&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash create &lt;span class="s2"&gt;"valid stash"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will create a stash with a description and unique ID, but nothing will be stored anywhere in the ref namespace. This stash creation method is mostly used for scripts.&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%2F63ig27mvtimf0xm440oy.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%2F63ig27mvtimf0xm440oy.png" alt="without reflog" width="750" height="100"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To add this stash entry into the reflog later, you can use the &lt;code&gt;git stash store&lt;/code&gt; command 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;git stash store &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"adding to reflog"&lt;/span&gt; &lt;span class="s2"&gt;"98c7181a7a3621139a4899be71e93ec7ceb18afa"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output,&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%2Fs3fjevrp5snno5g9sn1l.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%2Fs3fjevrp5snno5g9sn1l.png" alt="with reflog" width="750" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Show the latest stash information
&lt;/h2&gt;

&lt;p&gt;Use the &lt;code&gt;git stash show&lt;/code&gt; command to see the information of the latest stash in the stack. By default, it shows the status information of the file stashed and the number of insertions and deletions in the files.&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%2Fx2pjc1h0vku2ql2zz7g3.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%2Fx2pjc1h0vku2ql2zz7g3.png" alt="latest stash info" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to see a verbose stash output, you can use the &lt;code&gt;-p&lt;/code&gt; switch with the above command to see the stash information in the patch view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash show &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output,&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%2Fazlyt2edkvtwybillgbi.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%2Fazlyt2edkvtwybillgbi.png" alt="stash info output" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The patch view shows the exact diff between the commits.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Show the information of a particular stash
&lt;/h2&gt;

&lt;p&gt;What if you want to see the information of a particular stash? Remember the stash reference ID? We can refer to a specific stash and get its information using the &lt;code&gt;show&lt;/code&gt; command we learned above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash show shash@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are interested in seeing the information on the third stash in the stack. The output,&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%2Fr6vjl5kk8x9on331ceoi.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%2Fr6vjl5kk8x9on331ceoi.png" alt="info of a particular stash" width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Apply and remove a stash
&lt;/h2&gt;

&lt;p&gt;The stashes stay in the stash stack. You can pop(take out) a stash from the stack and apply it to the current branch. Use the following command to pop a stash:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It will pop the latest stash(one at the top of the stack) and apply it to the current branch. Also, the applied stash will be dropped(removed) from the stash stack.&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%2F8mgu0hexhqmhud65t56v.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%2F8mgu0hexhqmhud65t56v.png" alt="pop stash" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Apply a stash without removing it
&lt;/h2&gt;

&lt;p&gt;What if you want to apply a stash without dropping it from the stack? You can use the following command for that:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The apply command will apply the latest stash from the stack without removing it from the stack.&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%2F3n44cmcyudhqetany0k1.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%2F3n44cmcyudhqetany0k1.png" alt="apply stash" width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, if you want to apply a specific stash from the stack, you can use the stash reference ID 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;git stash apply stash@&lt;span class="o"&gt;{&lt;/span&gt;2&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Remove a stash without applying it
&lt;/h2&gt;

&lt;p&gt;You can also drop the latest stash from the stack without applying it. To do that, use the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You can also drop a specific stash without applying it using the reference ID of the stash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash drop stash@&lt;span class="o"&gt;{&lt;/span&gt;3&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Clear all the stash
&lt;/h2&gt;

&lt;p&gt;Sometimes, you may not need the stashes and want to clear them all. Use this command to clear all the stashes from the stack:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  ✅ Create a new branch from the stash
&lt;/h2&gt;

&lt;p&gt;You can create a branch from the commits in the stash using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash branch fix/resolve-conflicts-checkout stash@&lt;span class="o"&gt;{&lt;/span&gt;0&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will create a new branch and switch to the new branch.&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%2Favqh0u2yn5zcztpcv3t2.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%2Favqh0u2yn5zcztpcv3t2.png" alt="create branch" width="750" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check the newly created branch using the &lt;code&gt;git branch&lt;/code&gt; command.&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%2F2486qschi3s41it3s3id.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%2F2486qschi3s41it3s3id.png" alt="branch list" width="550" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all for now. Do you know any other usages of the &lt;code&gt;git stash&lt;/code&gt; command? Please feel free to comment and let us know.&lt;/p&gt;




&lt;p&gt;Thanks for reading it. I hope it was insightful and helped you get familiar with some new git commands. If you liked the article, please post likes/comments and share it in your circles.&lt;/p&gt;

&lt;p&gt;Let's connect. You can follow me on &lt;a href="https://dev.to/atapas"&gt;&lt;strong&gt;Dev&lt;/strong&gt;&lt;/a&gt;, and I also share content on these platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/tapasadhikary?sub_confirmation=1" rel="noopener noreferrer"&gt;&lt;strong&gt;tapaScript on YouTube&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/tapasadhikary" rel="noopener noreferrer"&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/atapas" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/in/tapasadhikary/" rel="noopener noreferrer"&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Dynamic routes recipes from Next.js App Router</title>
      <dc:creator>Tapas Adhikary</dc:creator>
      <pubDate>Wed, 15 Nov 2023 05:09:37 +0000</pubDate>
      <link>https://dev.to/atapas/dynamic-routes-recipes-from-nextjs-app-router-5c32</link>
      <guid>https://dev.to/atapas/dynamic-routes-recipes-from-nextjs-app-router-5c32</guid>
      <description>&lt;p&gt;Next.js &lt;code&gt;App Router&lt;/code&gt; has brought many improvements over its predecessor, &lt;code&gt;Page Router&lt;/code&gt;. One of the significant improvements is the &lt;code&gt;routing&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;Next.js App Router uses the file-system-based router, where you create directories(aka folders) to define routes. You must create a special file called &lt;code&gt;page.js&lt;/code&gt;(or .ts/.jsx/.tsx) under the directory to create a page for the route.&lt;/p&gt;

&lt;p&gt;The top-level &lt;code&gt;app/&lt;/code&gt; directory acts as the root route(&lt;code&gt;/&lt;/code&gt;), and any directory you create under the app directory will create other route segments that map to a URL segment. You can also create the &lt;code&gt;nested route&lt;/code&gt; by creating the subdirectories as shown in the image below.&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%2Fmy7z770iisfd7ex8nsut.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%2Fmy7z770iisfd7ex8nsut.png" alt="Next.js Routing" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Next.js App Router, a page is unique to a route. You can create one page per route by creating a &lt;code&gt;page.js&lt;/code&gt; file under a directory that signifies a route segment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// /app/page.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&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;If a directory doesn't have a corresponding &lt;code&gt;page.js&lt;/code&gt; file, the respective route will be inaccessible and result in a 404, &lt;code&gt;page not found&lt;/code&gt; error. The image below demonstrates that each route directory has a page file that creates the page for that route segment.&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%2Faa2pkuki19koi7ctvee9.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%2Faa2pkuki19koi7ctvee9.png" alt="Next.JS Page Routes" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So far, all the routes we have discussed are static and pre-defined, known beforehand to developers to construct the route segments. But what if we do not know the value to form a route segment? What if it is dynamic, like an id, name, or slug?&lt;/p&gt;

&lt;h2&gt;
  
  
  Welcome Dynamic Routes
&lt;/h2&gt;

&lt;p&gt;You create dynamic routes when you do not know the route segment name and want to create with dynamic data. For example, you may have a static route called &lt;code&gt;/blog&lt;/code&gt;. Creating individual blog post routes under it will be too much overhead. You may want to create them using any dynamic data like id, name. or a slug.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 What is a slug?&lt;/p&gt;

&lt;p&gt;Slug is an unique part of an URL that provides information about a web page. You should keep them simple, human-readable to help out with SEO. It appears at the end part of the URL after the backslash (“/”). For example, &lt;code&gt;how-to-learn&lt;/code&gt; is the slug of the URL &lt;code&gt;https://tapascript.io/blog/how-to-learn&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&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%2Fi2wg87zrc7jts65iterg.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%2Fi2wg87zrc7jts65iterg.png" alt="dynamic routing" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Understand Things With Code
&lt;/h2&gt;

&lt;p&gt;We understand things better with code. Let's do that. All the code used in this article is available on the &lt;a href="https://github.com/tapascript/teach-next-js" rel="noopener noreferrer"&gt;tapaScript GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, we will create a project with the latest Next.js version. Open a terminal/command prompt and execute the following command. Make sure you have installed &lt;code&gt;Node.js 18&lt;/code&gt; or above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please provide the details asked. A few important things to note here.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Opt for &lt;code&gt;App Router&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The selection of TypeScript is your choice. If you are comfortable with it, you can select Yes. I'll use JavaScript code in this article as most developers will likely use it(however, I am a big TypeScript fan!).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You may opt for the &lt;code&gt;src/&lt;/code&gt; directory. I do that as I like to keep my project configuration files under the &lt;code&gt;src/&lt;/code&gt; directory but outside of the &lt;code&gt;app/&lt;/code&gt; directory. Here, we will assume to opt for it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2F6i1n634r66ndhi0d475s.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%2F6i1n634r66ndhi0d475s.png" alt="steps" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once done, change the directory to your project directory and install the dependencies using yarn/npm/pnpm/bun, whatever you want. Then, start the server locally using the &lt;code&gt;yarn dev&lt;/code&gt; or its npm/pnpm/bun equivalent commands.&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;teach-next-js
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; yarn
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; yarn dev &lt;span class="c"&gt;# or npm run dev or pnpm dev or bun dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app will be available on the &lt;code&gt;localhost:3000&lt;/code&gt; by default. As you see in the image below, the &lt;code&gt;app/&lt;/code&gt; directory under the &lt;code&gt;src/&lt;/code&gt; directory signifies the top-level route &lt;code&gt;/&lt;/code&gt;. The &lt;code&gt;page.js&lt;/code&gt; file under the &lt;code&gt;app/&lt;/code&gt; directory provides us with the page for that route.&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%2Fd57g3bdgemyuq3mdom13.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%2Fd57g3bdgemyuq3mdom13.png" alt="folder to route" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's clear the existing code in the &lt;code&gt;page.js&lt;/code&gt; file and put a simple ReactJS component like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex justify-center p-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, our home page(on the route segment &lt;code&gt;/&lt;/code&gt;) will look like this:&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%2Fpihoexndeltuavpsglw6.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%2Fpihoexndeltuavpsglw6.png" alt="Home Page" width="738" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create More Routes
&lt;/h3&gt;

&lt;p&gt;Let's create a &lt;code&gt;/blog&lt;/code&gt; route segment. To do that, we will create a &lt;code&gt;blog/&lt;/code&gt; directory under the &lt;code&gt;app/&lt;/code&gt; directory.&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%2Fpkzvnv0ngz583t10zad9.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%2Fpkzvnv0ngz583t10zad9.png" alt="Added Blog" width="350" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you will have a &lt;code&gt;/blog&lt;/code&gt; route segment. However, it will not be accessible publicly because we have not defined a page for it yet.&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%2Fodsthnfonfbdq2qvdlk7.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%2Fodsthnfonfbdq2qvdlk7.png" alt="404 page" width="741" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's create a &lt;code&gt;page.js&lt;/code&gt; file under the &lt;code&gt;blog/&lt;/code&gt; directory with the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BlogPage&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="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;BlogPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will see the blog page rendered successfully. It is a simple page with a paragraph of text.&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%2Fu7sj9tso9wf110ayb1m6.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%2Fu7sj9tso9wf110ayb1m6.png" alt="blog page" width="613" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Nested Routes
&lt;/h3&gt;

&lt;p&gt;Let us now create a couple of nested routes like &lt;code&gt;/about/form&lt;/code&gt; and &lt;code&gt;/about/tax&lt;/code&gt;. You guessed it right! We will have to create an &lt;code&gt;about/&lt;/code&gt; directory and then two sub-directories under it. Those are &lt;code&gt;form/&lt;/code&gt; and &lt;code&gt;tax/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, to make all three routes accessible, we need to create a &lt;code&gt;page.js&lt;/code&gt; file under each of the directories.&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%2Fylnfu3tzp3qk2o26rizs.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%2Fylnfu3tzp3qk2o26rizs.png" alt="About Page" width="289" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is an example page for the &lt;code&gt;/about&lt;/code&gt; route segment. You can create something similar for the pages of &lt;code&gt;/about/form&lt;/code&gt; and &lt;code&gt;/about/tax&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AboutPage&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="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-3xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;About&lt;/span&gt; &lt;span class="nx"&gt;Page&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;AboutPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how each of the pages may appear for each of the routes.&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%2Fjt0jg8nfh6n7oxl2zy4d.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%2Fjt0jg8nfh6n7oxl2zy4d.png" alt="All Pages" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Dynamic Routes
&lt;/h3&gt;

&lt;p&gt;Now it's time we start understanding dynamic route segments with code. You can create a dynamic route segment by wrapping the directory name in square brackets(&lt;code&gt;[]&lt;/code&gt;). For example, &lt;code&gt;[name]&lt;/code&gt;, &lt;code&gt;[slug]&lt;/code&gt;, &lt;code&gt;[id]&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Taking forward the example of a blog and its posts, the individual posts can include a route like this, &lt;code&gt;/blog/[slug]/page.js&lt;/code&gt;. Here &lt;code&gt;[slug]&lt;/code&gt; is the dynamic route segment.&lt;/p&gt;

&lt;p&gt;Create a directory named &lt;code&gt;[slug]&lt;/code&gt; under the &lt;code&gt;blog/&lt;/code&gt; directory and a &lt;code&gt;page.js&lt;/code&gt; file under the &lt;code&gt;blog/[slug]/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeo966fr9xzz0f9by0in.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%2Ffeo966fr9xzz0f9by0in.png" alt="blog with slug" width="274" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All dynamic segments are passed as the &lt;code&gt;params&lt;/code&gt; prop to the &lt;code&gt;page&lt;/code&gt;. We can destructure the dynamic route segment value from the &lt;code&gt;params&lt;/code&gt; prop. Let's create the content for the dynamic route page with the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;slug&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Showing&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;blog&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; 
      &lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;strong&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;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The page has received a &lt;code&gt;params&lt;/code&gt; prop, and we can extract the &lt;code&gt;slug&lt;/code&gt; value from it. Now, you can do whatever logic you need using the &lt;code&gt;slug&lt;/code&gt; value. You can use it to make a network call and get details to render on the page, or you can just render it on the page, as shown below.&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%2Fzjp2qv1dema44iwq714a.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%2Fzjp2qv1dema44iwq714a.png" alt="blog slugs" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Dynamic &lt;strong&gt;Catch-all Segments&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can broaden the use of the dynamic route segment(&lt;code&gt;[slug]&lt;/code&gt;) to a &lt;code&gt;catch-all&lt;/code&gt; route segment by adding an ellipsis inside the brackets&lt;code&gt;[...slug]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example &lt;code&gt;/app/store/[...slug]/page.js&lt;/code&gt; will match &lt;code&gt;/store/book&lt;/code&gt;, &lt;code&gt;/store/design&lt;/code&gt;, and also &lt;code&gt;/store/book/novels&lt;/code&gt;, &lt;code&gt;/store/design/shoes&lt;/code&gt;, &lt;code&gt;/store/design/shoes/boot&lt;/code&gt;, and so on.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;store/&lt;/code&gt; directory under the &lt;code&gt;app/&lt;/code&gt; directory. Now, create a directory with the name &lt;code&gt;[...name]&lt;/code&gt; under the &lt;code&gt;app/store/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqhudc6p1p41jes9typj.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%2Fcqhudc6p1p41jes9typj.png" alt="ctach-all" width="251" height="144"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;page.js&lt;/code&gt; file under the &lt;code&gt;app/store/[...name]&lt;/code&gt; will define a page for the catch-all route segment. This page component is quite similar to the page component we have seen above for the dynamic routes. However, notice that we are extracting &lt;code&gt;name&lt;/code&gt; instead of &lt;code&gt;slug&lt;/code&gt; here because we have used &lt;code&gt;[...name]&lt;/code&gt; as the directory name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;StorePage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&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="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="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-2xl&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Showing&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; 
      &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;strong&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;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;StorePage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when you try the route &lt;code&gt;localhost:3000/store/a&lt;/code&gt;, the &lt;code&gt;params&lt;/code&gt; returns &lt;code&gt;{name: ['a']}&lt;/code&gt;. We are printing that on the console and browser.&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%2F2w63zvcj48tqdz57qppn.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%2F2w63zvcj48tqdz57qppn.png" alt="catch all example 1" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also catch the route &lt;code&gt;localhost:3000/store/a/b&lt;/code&gt; with the same, and the &lt;code&gt;params&lt;/code&gt; prop value will be &lt;code&gt;{name: ['a', 'b']}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8u0tgdjoem5fdur5rylt.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%2F8u0tgdjoem5fdur5rylt.png" alt="catch all example 2" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Optional Dynamic &lt;strong&gt;Catch-all Segments&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;But hang on! How about the route &lt;code&gt;/store&lt;/code&gt;? It gives us 404, page not found.&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%2Fcksy7tnfbcleoio2rdr5.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%2Fcksy7tnfbcleoio2rdr5.png" alt="store route" width="712" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes! One way to fix that is by creating a &lt;code&gt;page.js&lt;/code&gt; file inside the &lt;code&gt;app/store/&lt;/code&gt; directory. If you don't want that, you can make the catch-all segment as an &lt;code&gt;optional catch-all&lt;/code&gt; segment by wrapping the parameter(or directory name) in double square brackets, &lt;code&gt;[[...name]].&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vc97gkgcm7zjhubo72t.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%2F5vc97gkgcm7zjhubo72t.png" alt="optional catch all" width="269" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now even the &lt;code&gt;/store&lt;/code&gt; route page will be served from the &lt;code&gt;app/store/[[...name]]/page.js&lt;/code&gt;. However, in this case, the value of &lt;code&gt;name&lt;/code&gt; will be &lt;code&gt;undefined&lt;/code&gt; and the &lt;code&gt;params&lt;/code&gt; prop value will be &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqddoe1wmak1c5pw7pbbs.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%2Fqddoe1wmak1c5pw7pbbs.png" alt="optional catch all 2" width="800" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's all. Thanks for reading it. I hope it was insightful. If you liked the tutorial, please post likes and share it in your circles.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Last Thing...
&lt;/h2&gt;

&lt;p&gt;I am a self-declared &lt;code&gt;Next.js&lt;/code&gt; evangelist who loved this framework from its very beginning days. With the inclusion of the App Router, the affection has gone higher 😊.&lt;/p&gt;

&lt;p&gt;I have a &lt;a href="https://www.youtube.com/watch?v=eX9KA48IZes&amp;amp;list=PLIJrr73KDmRwz_7QUvQ9Az82aDM9I8L_8&amp;amp;index=6" rel="noopener noreferrer"&gt;full-fledged playlist&lt;/a&gt; on my YouTube channel(&lt;a href="https://www.youtube.com/tapasadhikary?sub_confirmation=1" rel="noopener noreferrer"&gt;tapaScript&lt;/a&gt;) that will teach you to build projects with Next.js, from clarifying fundamental concepts to coding and tasks.&lt;/p&gt;

&lt;p&gt;You may want to check it out.&lt;/p&gt;

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




&lt;p&gt;Let's connect. I share knowledge on web development, content creation, Open Source, and careers on these platforms.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/tapasadhikary?sub_confirmation=1" rel="noopener noreferrer"&gt;&lt;strong&gt;tapaScript on YouTube&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://twitter.com/tapasadhikary" rel="noopener noreferrer"&gt;&lt;strong&gt;X(eka Twitter)&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.linkedin.com/in/tapasadhikary/" rel="noopener noreferrer"&gt;&lt;strong&gt;LinkedIn&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/atapas" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>nextjs</category>
      <category>react</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
