<?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: Anurag</title>
    <description>The latest articles on DEV Community by Anurag (@kranurag).</description>
    <link>https://dev.to/kranurag</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%2F699114%2F014e3d5c-01b6-4db1-beaf-edd3e6a2ea3c.jpg</url>
      <title>DEV Community: Anurag</title>
      <link>https://dev.to/kranurag</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kranurag"/>
    <language>en</language>
    <item>
      <title>Basics of E2E Testing and Integrating Cypress with Next.js</title>
      <dc:creator>Anurag</dc:creator>
      <pubDate>Fri, 25 Feb 2022 16:31:59 +0000</pubDate>
      <link>https://dev.to/kranurag/basics-of-e2e-testing-and-integrating-cypress-with-nextjs-l5l</link>
      <guid>https://dev.to/kranurag/basics-of-e2e-testing-and-integrating-cypress-with-nextjs-l5l</guid>
      <description>&lt;p&gt;👋 Hello fellas! It's been a while since I posted an article. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3ornk57KwDXf81rjWM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3ornk57KwDXf81rjWM/giphy.gif" alt="hello" width="453" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As developers, we always want to deliver the best products to users. And Testing is a crucial part of this process. One of the commonly used testing techniques is E2E testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 E2E Testing - The Basics
&lt;/h2&gt;

&lt;p&gt;End to End Testing (or E2E testing in short) is a technique that tests the entire software product from beginning to end to ensure the application flow behaves as expected. &lt;/p&gt;

&lt;p&gt;The main intent of E2E testing is to simulate the real user scenario and to test from the end user's experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  📃 Benefits of E2E Testing
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Reduced Risks&lt;/li&gt;
&lt;li&gt;Increased Confidence&lt;/li&gt;
&lt;li&gt;Reduced Cost&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚡ E2E testing methods
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Horizontal E2E testing
&lt;/h4&gt;

&lt;p&gt;Horizontal Testing is done from the end user's perspective. It evaluates whether the user can navigate the software and use its functions properly. It also helps to detect the bugs that might prevent the user from using some software functions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Vertical E2E Testing
&lt;/h4&gt;

&lt;p&gt;This method refers to testing in layers, meaning that tests happen in sequential, hierarchical order. Each subcomponent of the system is tested from start to finish to ensure quality.&lt;/p&gt;

&lt;p&gt;It is mostly done when the system has no UI or the UI has a high level of technicality and is used to test critical components.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❓ How to perform E2E Testing?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Analyze all the requirements. Have a clear idea about what the app is supposed to do.&lt;/li&gt;
&lt;li&gt;Set up a test environment as per the requirements.&lt;/li&gt;
&lt;li&gt;List down all the testing methods required to test these responses.&lt;/li&gt;
&lt;li&gt;Design the test cases.&lt;/li&gt;
&lt;li&gt;Run the tests and jot the results.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚡ E2E Testing Frameworks
&lt;/h3&gt;

&lt;p&gt;E2E Testing frameworks are used to ensure that all the moving parts in an application is configured properly.&lt;/p&gt;

&lt;p&gt;Here are some of the most popular ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selenium&lt;/li&gt;
&lt;li&gt;Cypress&lt;/li&gt;
&lt;li&gt;Cucumber&lt;/li&gt;
&lt;li&gt;Testim&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you are familiar with the basic concept of E2E Testing, let's take a look at how to integrate E2E Testing using Cypress in Next.JS&lt;/p&gt;

&lt;h2&gt;
  
  
  👨‍💻 Integration of Cypress with Next.js for E2E Testing
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Now that you're familiar with the Basics of E2E Testing, let's take a look at how to get started with Cypress in Next.js&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Next.JS
&lt;/h4&gt;

&lt;p&gt;In case you are not familiar with Next.js, it's a react framework packed with some extra features to help both developers and clients.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cypress
&lt;/h4&gt;

&lt;p&gt;Cypress is a test runner for E2E Testing for the web.&lt;/p&gt;

&lt;h4&gt;
  
  
  Setting up the Project
&lt;/h4&gt;

&lt;p&gt;You can use &lt;code&gt;create next-app&lt;/code&gt; with the &lt;code&gt;cypress&lt;/code&gt; example to get started quickly.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;For existing projects, you can start off by installing the &lt;code&gt;cypress&lt;/code&gt; package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev cypress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, add Cypress to the &lt;code&gt;scripts&lt;/code&gt; section in the &lt;code&gt;package.json&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cypress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cypress open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run cypress to generate examples that use their recommended folder structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run cypress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Creating your first Cypress integration test
&lt;/h4&gt;

&lt;p&gt;Let's say you have two pages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/index.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&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;next/link&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;About&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/about.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="nx"&gt;About&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;About Page&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, to test that your navigation is working correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// cypress/integration/app.spec.js&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Navigation&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should navigate to the about page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Start from the index page&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:3000/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Find a link with an href attribute containing "about" and click it&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;a[href*="about"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;// The new url should include "/about"&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// The new page should contain an h1 with "About page"&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&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;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;About Page&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;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Instead of doing &lt;code&gt;cy.visit('http://localhost:3000/')&lt;/code&gt;, you can just do &lt;code&gt;cy.visit('/')&lt;/code&gt; if you set the &lt;code&gt;baseUrl&lt;/code&gt; to &lt;code&gt;http://localhost:3000&lt;/code&gt; in the &lt;code&gt;cypress.json&lt;/code&gt; config file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cypress.json&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:3000"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, you will have a simple test setup. Since Cypress is testing a real Next.js application, it requires the Next.js server to be running prior to starting cypress.&lt;/p&gt;

&lt;p&gt;First Run &lt;code&gt;npm run build&lt;/code&gt; and &lt;code&gt;npm run start&lt;/code&gt;, then run &lt;code&gt;npm run cypress&lt;/code&gt; in another terminal window to start Cypress.&lt;/p&gt;

&lt;p&gt;Now, cypress will start and you can view the results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further steps for Continuous Integration (CI)
&lt;/h3&gt;

&lt;p&gt;At this point, you will have noticed that running Cypress so far has opened an interactive browser which is not ideal for CI environments.&lt;/p&gt;

&lt;p&gt;You can run Cypress headlessly using the &lt;code&gt;cypress run&lt;/code&gt; command. &lt;/p&gt;

&lt;p&gt;In the &lt;code&gt;package.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cypress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cypress open"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cypress:headless"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cypress run"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it for this article! You can show your support by dropping some reactions here!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;About the Author&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kr-anurag"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/kr_anurag_"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anurag.tech"&gt;Portfolio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.anurag.tech"&gt;Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>testing</category>
    </item>
    <item>
      <title>How I structure my Next JS Projects</title>
      <dc:creator>Anurag</dc:creator>
      <pubDate>Mon, 07 Feb 2022 06:53:18 +0000</pubDate>
      <link>https://dev.to/kranurag/how-i-structure-my-next-js-projects-2m5h</link>
      <guid>https://dev.to/kranurag/how-i-structure-my-next-js-projects-2m5h</guid>
      <description>&lt;p&gt;Hello folks! It's been a while since I published an article. So today I'm going to explain how I structure my NextJS projects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HhS77-61--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/-z2KfO5zAckAAAAC/hello-there-baby-yoda.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HhS77-61--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://c.tenor.com/-z2KfO5zAckAAAAC/hello-there-baby-yoda.gif" alt="" width="498" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: There is no right or wrong way to structure a Next JS project, and this is highly opinionated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, the structure of a Next JS project depends mainly on the complexity of a project. And if a project needs only page and is small in terms of complexity, you should not over-structure it. With that being said, let's see how to manage your project depending upon the complexity.&lt;/p&gt;

&lt;h4&gt;
  
  
  📃 Single Pages
&lt;/h4&gt;

&lt;p&gt;Next JS automatically routes every file in the &lt;code&gt;pages/&lt;/code&gt; directory to a name associated with the file name.&lt;/p&gt;

&lt;p&gt;For example, the React component inside the &lt;code&gt;pages/dashboard.jsx&lt;/code&gt; will be routed to &lt;code&gt;${URL}/dashboard&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For single pages, you can just create a single file that will export a React component.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello world&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  🧩 Breaking down into smaller components
&lt;/h4&gt;

&lt;p&gt;Now, at some point, your file will have a lot of lines, so you can make smaller standalone components.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;dashboard&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* component code */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&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;Hero&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* component code */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Hero&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  📁 Creating custom files for components
&lt;/h4&gt;

&lt;p&gt;The above example works if you have smaller components. But it is advisable to create standalone files for components.&lt;/p&gt;

&lt;p&gt;Now, conventionally, components should be stored in the &lt;code&gt;components&lt;/code&gt; directory at the root directory of the app.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* some code */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* some more code */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Then, in the desired file, you can import and use it.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Header&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/header.jsx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* main component */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Now, as your apps grow, they will contain more and more components, and while importing them, the code can be a little messy.&lt;/p&gt;

&lt;p&gt;Here's a simple workaround for this:&lt;/p&gt;

&lt;p&gt;First, make a file inside the &lt;code&gt;components&lt;/code&gt; directory named &lt;code&gt;index.js&lt;/code&gt; or &lt;code&gt;index.jsx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then, inside the file, export all the components at once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- components/index.js

export * from "./Header.jsx";
export * from "./Hero.jsx";
export * from "./Footer";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you can import all the components inside your desired file at once.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- pages/index.js

import { Header, Hero, Footer } from "../components";

function Home() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Header /&amp;gt;
      &amp;lt;Hero /&amp;gt;
      &amp;lt;Footer /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  🗃 Making categories for similar components
&lt;/h4&gt;

&lt;p&gt;Now, let's say you have components of similar kinds. Like the &lt;code&gt;Header&lt;/code&gt; and the &lt;code&gt;Footer&lt;/code&gt; component acts like navigation components. Similarly, you have different &lt;code&gt;Card&lt;/code&gt; components that can be sorted into the Cards category.&lt;/p&gt;

&lt;p&gt;So, you can create different folders inside the &lt;code&gt;components&lt;/code&gt; directory&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- components
    | - Navigation
        | - Header.component.jsx
        | - Footer.component.jsx
    | - Cards
        | - Confirm.card.jsx
        | - Checkout.card.jsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  📖 Making categories for similar pages
&lt;/h4&gt;

&lt;p&gt;Back to pages, in some cases, pages can also fall into some categories. For example, the &lt;code&gt;sign-up&lt;/code&gt; and &lt;code&gt;login&lt;/code&gt; page falls into the auth category.&lt;/p&gt;

&lt;p&gt;So, for that case, you can make a directory inside the &lt;code&gt;pages&lt;/code&gt; directory named &lt;code&gt;auth&lt;/code&gt; containing the &lt;code&gt;sign-up&lt;/code&gt; and &lt;code&gt;login&lt;/code&gt; pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- pages
    | - auth
        | - sign-up.jsx
        | - login.jsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🗄 Storing Files, Fonts
&lt;/h4&gt;

&lt;p&gt;Moving from this, the conventional way to store external files such as Images, Fonts, etc. is to store them in the public directory.&lt;/p&gt;

&lt;p&gt;For example, you can store all the required images in the &lt;code&gt;public/assets&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Similarly, you can store the required fonts in the &lt;code&gt;public/fonts&lt;/code&gt; directory.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- public
    | - assests
        | - cover.png
        | - logo.png
    | - fonts
        | - poppins-medium.woff2
        | - sen-regular.woff2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🔮 Managing custom hooks, types, functions
&lt;/h4&gt;

&lt;p&gt;In addition to this, you can create separate folders for custom hooks, types, functions, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- hooks
    | - useuser.jsx
- @types
    | - propTypes.ts
- utils
    | - uploadImage.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a wrap for this article. If you liked this, make sure to drop some reactions on this article.&lt;/p&gt;

&lt;h4&gt;
  
  
  About the Author
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kr-anurag"&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/kr_anurag_"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://anurag.tech"&gt;Portfolio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.anurag.tech"&gt;Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>architecture</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Introducing Vault3 - Your Safest Decentralized Vault!</title>
      <dc:creator>Anurag</dc:creator>
      <pubDate>Thu, 27 Jan 2022 09:26:57 +0000</pubDate>
      <link>https://dev.to/byteslash/introducing-vault3-your-safest-decentralized-vault-2oak</link>
      <guid>https://dev.to/byteslash/introducing-vault3-your-safest-decentralized-vault-2oak</guid>
      <description>&lt;p&gt;&lt;a href="https://i.giphy.com/media/3ornk57KwDXf81rjWM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3ornk57KwDXf81rjWM/giphy.gif" alt="hello" width="453" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ❓ What is Vault3?
&lt;/h2&gt;

&lt;p&gt;Simply speaking, Vault3 is a decentralized vault for all your digital belongings, like &lt;strong&gt;Passwords, Images, and Files.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vault3 is our submission for the &lt;strong&gt;&lt;a href="https://townhall.hashnode.com/thirdweb-hackathon"&gt;Hashnode x ThirdWeb&lt;/a&gt;&lt;/strong&gt; Hackathon&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vault3.live"&gt;&lt;code&gt;Try Vault3&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✏️ Hashnode
&lt;/h2&gt;

&lt;p&gt;In case you don’t know, &lt;strong&gt;&lt;a href="https://hashnode.com"&gt;Hashnode&lt;/a&gt;&lt;/strong&gt; is the easiest way to start a developer blog on your personal domain for free and connect with the readers through its global dev community! &lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 ThirdWeb
&lt;/h2&gt;

&lt;p&gt;These days, Web3.0 is catching everyone’s eyes, and as a developer myself, the learning curve is pretty steep. That’s where &lt;strong&gt;ThirdWeb&lt;/strong&gt; comes in! &lt;strong&gt;ThirdWeb&lt;/strong&gt; is a sweet collection of tools that can be used to build sophisticated Web3 apps, with ease.&lt;/p&gt;

&lt;p&gt;Tracing Back to Vault3, let’s first see where the Idea came from.&lt;/p&gt;

&lt;h2&gt;
  
  
  😕 The Problem
&lt;/h2&gt;

&lt;p&gt;It is normal tendency for humans to forget things that are long or things that cant be remembered easily. Hence, we write them down in a place to use them when needed. But in the digital world, writing important things that are hard to remember like passwords in physical objects like paper has become highly unlikely. It has become quite common to store important things in applications like password/note managers.&lt;/p&gt;

&lt;p&gt;But have we ever thought about the safety of our digital belongings in those applications that are centralized? Have we ever thought that our data can be easily censored by the applications where we store them in? &lt;/p&gt;

&lt;p&gt;Enter Vault3, a safe and secure digital vault.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔭 Deep Dive into Vault3
&lt;/h2&gt;

&lt;p&gt;Speaking of Vault3, it’s a web application built with technologies like &lt;strong&gt;NextJS&lt;/strong&gt;, &lt;strong&gt;Chakra UI&lt;/strong&gt; and some external libraries.&lt;/p&gt;

&lt;p&gt;Vault3 provides users with a safe vault, which they can use to store important belongings such as &lt;strong&gt;Photos&lt;/strong&gt;, &lt;strong&gt;Passwords&lt;/strong&gt; and &lt;strong&gt;Files&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The way it works is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User first connects their wallet, like &lt;strong&gt;Metamask&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Then they create a private key to access their vault. To create a private key, user needs to upload an &lt;strong&gt;Image&lt;/strong&gt; of their choice. This Image is hashed and will be used as a private key to access the vault.&lt;/li&gt;
&lt;li&gt;Now the user can access their vault through a Dashboard&lt;/li&gt;
&lt;li&gt;Here the user can upload &lt;strong&gt;Passwords&lt;/strong&gt;, &lt;strong&gt;Images&lt;/strong&gt; and &lt;strong&gt;Files&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Users can also delete, download and view their stats.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✨ The Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NextJS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chakra UI&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thirdweb&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hardhat&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  👀 Understanding the flow of the app
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔒 Authentication
&lt;/h3&gt;

&lt;p&gt;The auth flow is handled by crypto wallets as in &lt;strong&gt;web3.0&lt;/strong&gt; protocols. We are using &lt;strong&gt;Thirdweb&lt;/strong&gt; as our provider. At the time of writing this article, &lt;strong&gt;Vault3&lt;/strong&gt; only supports &lt;strong&gt;Metamask&lt;/strong&gt; wallet.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔑 Generating the private key
&lt;/h3&gt;

&lt;p&gt;The private key to access the vault is basically generated from the &lt;strong&gt;Image&lt;/strong&gt; that the user provides when creating a new private key. &lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Image&lt;/strong&gt; is first converted into byte data, and then its hashed using the HmacSHA256 algorithm, which is then used as a private key to access the vault.&lt;/p&gt;

&lt;p&gt;To access their vault again, users must provide the same &lt;strong&gt;Image.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💽 Uploading Flow
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;All of your data is stored safely on the &lt;strong&gt;Polygon&lt;/strong&gt; blockchain using the &lt;strong&gt;AES&lt;/strong&gt; encryption algorithm.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  🔑 Uploading Password
&lt;/h3&gt;

&lt;p&gt;Storing a password is extremely simple. You are just required to enter the &lt;strong&gt;Website&lt;/strong&gt; for which you want to store the password, your &lt;strong&gt;Username&lt;/strong&gt; or &lt;strong&gt;Email&lt;/strong&gt; you used for that site and lastly the &lt;strong&gt;Password&lt;/strong&gt; itself. You can also copy the password and also reveal it once it has been stored. You can also filter your passwords by searching for the site address that you have given while storing a new password.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌆 Uploading Image
&lt;/h3&gt;

&lt;p&gt;The process for storing an image relatively remains the same as storing a password except the field where you would enter the name of the site is now replaced by a field for Name of the image. And, you now have a field to insert your image. Vault3 supports various image formats such as PNG, JPG, SVG, GIF and WEBP. Ta-da! Your image is now stored in your vault!&lt;/p&gt;

&lt;h3&gt;
  
  
  📁 Uploading Files
&lt;/h3&gt;

&lt;p&gt;Moving onto importing a file. Vault3 supports insertion of files of all kinds, so you do not have to worry about the format of your file. You just need to insert your file and the Name field is populated by the name of the file you have chosen and you cannot change the Name for a file unlike the situation of storing an Image.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Apart from uploading Passwords, Images, and Files, users can also delete and download the data stored in their vault.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Since Vault3 is based on web 3.0, most of these operations require &lt;strong&gt;Gas Fees&lt;/strong&gt; in the form of &lt;strong&gt;MATIC&lt;/strong&gt; tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  ℹ️ On a sidenote:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Vault3 currently operates on the &lt;strong&gt;Mumbai Polygon Testnet&lt;/strong&gt; Network, and you can get some fake &lt;strong&gt;MATIC&lt;/strong&gt; &lt;a href="https://faucet.polygon.technology/"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  👥 Moving from this, Let’s meet the Team:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Saptarshi Basu - Builder, &lt;a href="//mailto:saptarshii.me@gmail.com"&gt;saptarshii.me@gmail.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anurag - Co-Builder, &lt;a href="//mailto:kr.anurag24@gmail.com"&gt;kr.anurag24@gmail.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://twitter.com/imsaptarshiii/status/1484802359956230147"&gt;Twitter Launch Post&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔗 External Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/imsaptarshi/vault3"&gt;&lt;code&gt;Github&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.producthunt.com/posts/vault3-1"&gt;&lt;code&gt;Product Hunt&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web3</category>
      <category>nextjs</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Metamask authentication in NextJS with Third Web</title>
      <dc:creator>Anurag</dc:creator>
      <pubDate>Tue, 11 Jan 2022 13:33:55 +0000</pubDate>
      <link>https://dev.to/byteslash/metamask-authentication-in-nextjs-with-third-web-55ff</link>
      <guid>https://dev.to/byteslash/metamask-authentication-in-nextjs-with-third-web-55ff</guid>
      <description>&lt;p&gt;Hey There! What's up!&lt;/p&gt;

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

&lt;p&gt;So Web3 has been in total hype these days, and a lot of developers have been trying out web3 lately, including me. &lt;/p&gt;

&lt;p&gt;And, Authentication is one of the most skeptical parts of a Full Stack application! And in Web 3.0, this flow is managed by wallets, and Metamask is the most popular among them. &lt;/p&gt;

&lt;p&gt;So, in this article, I'm going to show how you can integrate Metamask auth with ThirdWeb in NextJS!&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo of what we are building today:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.loom.com/share/d28cd1093e8046a8b9475777d3bf65ac" rel="noopener noreferrer"&gt;Demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing a new NextJS app
&lt;/h3&gt;

&lt;p&gt;First, create a NextJS app. I'm also using Tailwind CSS as my UI preference. You can use anything that you 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;npx&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="nx"&gt;metamask&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Clear up the boilerplate
&lt;/h4&gt;

&lt;p&gt;Now, clear up the boilerplate in the &lt;code&gt;index.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Installing the dependencies
&lt;/h4&gt;

&lt;p&gt;Now, we will install the only required dependency for this app, &lt;code&gt;@3rdweb/hooks&lt;/code&gt;. Go ahead and install &lt;code&gt;@3rdweb/hooks&lt;/code&gt; in your project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# for npm
npm i @3rdweb/hooks

# for yarn
yarn add @3rdweb/hooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting up the Third Web Provider
&lt;/h3&gt;

&lt;p&gt;Now, we are going to set up the &lt;code&gt;ThirdwebWeb3Provider&lt;/code&gt; in our &lt;code&gt;_app.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/globals.css&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;ThirdwebWeb3Provider&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;@3rdweb/hooks&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;regenerator-runtime/runtime&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&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;supportedChainIds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;80001&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connectors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;injected&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThirdwebWeb3Provider&lt;/span&gt;
      &lt;span class="na"&gt;supportedChainIds&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;supportedChainIds&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;connectors&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;connectors&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ThirdwebWeb3Provider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here, first, we are going to import the provider and &lt;code&gt;regenerator-runtime/runtime&lt;/code&gt; at the top of the script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThirdwebWeb3Provider&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;@3rdweb/hooks&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;regenerator-runtime/runtime&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;Next, in the main function, we are specifying the &lt;code&gt;supportedChainIds&lt;/code&gt; and &lt;code&gt;connectors&lt;/code&gt;. You might be wondering what are these.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;supportedChainIds&lt;/code&gt; contains a list of networks that are supported by our app. Here, &lt;code&gt;80001&lt;/code&gt; is for &lt;code&gt;Mumbai Testnet Network&lt;/code&gt; and &lt;code&gt;4&lt;/code&gt; is for &lt;code&gt;Rinkeby Testnet Network&lt;/code&gt;. You can check the list of all networks and their Chain Ids  &lt;a href="https://dev.toLink"&gt;here&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;&lt;code&gt;connectors&lt;/code&gt; is basically all the wallet providers we want to support. Here, &lt;code&gt;injected&lt;/code&gt; is for Metamask wallet. This will be used when we are actually making the function to connect wallet.&lt;/p&gt;

&lt;p&gt;Next, we are wrapping our whole app in &lt;code&gt;ThirdwebWeb3Provider&lt;/code&gt; with &lt;code&gt;supportedChainIds&lt;/code&gt; and &lt;code&gt;connectors&lt;/code&gt; props to specify the configuration.&lt;/p&gt;

&lt;p&gt;That's it for the &lt;code&gt;_app.js&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making a UI in the &lt;code&gt;index.js&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;Now, let's first make a UI for the login flow.&lt;/p&gt;

&lt;p&gt;Head over to &lt;code&gt;index.js&lt;/code&gt; file and make a simple &lt;code&gt;button&lt;/code&gt; to connect wallet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col items-center justify-center min-h-screen py-2 bg-slate-100"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
          &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"px-4 py-2 rounded-md bg-purple-600 cursor-pointer hover:bg-purple-500 text-xl font-semibold duration-100 text-white"&lt;/span&gt;
        &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          Connect Wallet
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, you will have a basic UI like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641906515845%2FFMDlG49IA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641906515845%2FFMDlG49IA.png" alt="Screenshot (3).png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the connect wallet functionality
&lt;/h3&gt;

&lt;p&gt;Now, let's build the &lt;code&gt;connect wallet&lt;/code&gt; functionality.&lt;/p&gt;

&lt;p&gt;First, we will import the &lt;code&gt;useWeb3&lt;/code&gt; hook from &lt;code&gt;@3rdweb/hooks&lt;/code&gt; in our &lt;code&gt;index.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useWeb3&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;@3rdweb/hooks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, inside the &lt;code&gt;Home&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { connectWallet, address, error } = useWeb3();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we are going to assign the &lt;code&gt;connectWallet&lt;/code&gt; to the connect wallet button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"px-4 py-2 rounded-md bg-purple-600 cursor-pointer hover:bg-purple-500 text-xl font-semibold duration-100 text-white"&lt;/span&gt;
&lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;connectWallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;injected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Connect Wallet
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are passing &lt;code&gt;injected&lt;/code&gt; as a param to the &lt;code&gt;connectWallet&lt;/code&gt; function. If your remember from the above steps, this is used to specify that we are going to use Metamask to authenticate user.&lt;/p&gt;

&lt;p&gt;Now, at this point, you will have a working connect wallet button.&lt;/p&gt;

&lt;h4&gt;
  
  
  Displaying user address:
&lt;/h4&gt;

&lt;p&gt;Now, in the &lt;code&gt;Home&lt;/code&gt; component, we are going to check if the user is authenticated and then render component based on that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;
&lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col items-center justify-center min-h-screen py-2 bg-slate-100"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"px-2 py-1 rounded-full bg-gray-200 hover:bg-gray-300 font-mono font-medium cursor-pointer duration-100"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"px-4 py-2 rounded-md bg-purple-600 cursor-pointer hover:bg-purple-500 text-xl font-semibold duration-100 text-white"&lt;/span&gt;
        &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;connectWallet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;injected&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Connect Wallet
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Error handling:
&lt;/h4&gt;

&lt;p&gt;Sometimes, the app may not work cause of errors, so in that case, we can use the &lt;code&gt;error&lt;/code&gt; object and log its value.&lt;/p&gt;

&lt;p&gt;Below our &lt;code&gt;useWeb3&lt;/code&gt; hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;connectWallet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useWeb3&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="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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! We have done it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o6fJ1BM7R2EBRDnxK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o6fJ1BM7R2EBRDnxK/giphy.gif" alt="congrats"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>blockchain</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Component Polymorphism in React</title>
      <dc:creator>Anurag</dc:creator>
      <pubDate>Mon, 03 Jan 2022 14:18:26 +0000</pubDate>
      <link>https://dev.to/byteslash/component-polymorphism-in-react-3cbc</link>
      <guid>https://dev.to/byteslash/component-polymorphism-in-react-3cbc</guid>
      <description>&lt;p&gt;What's Up, people! Hope you're doing fine!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3ornk57KwDXf81rjWM/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3ornk57KwDXf81rjWM/giphy.gif" alt="hello"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this article, I'm going to explain Polymorphic Components in React, along with their implementation and using them with Typescript!&lt;/p&gt;

&lt;p&gt;So, there is a high chance that you might not be familiar with this concept. But you may have encountered this pattern.&lt;/p&gt;

&lt;p&gt;In a nutshell, this pattern lets us specify which HTML tag to use to render our component.&lt;/p&gt;

&lt;p&gt;But, the flexibility of polymorphic components also makes them easy to misuse, and that’s where TypeScript can help us. &lt;/p&gt;

&lt;p&gt;So, let's dive deep into this!&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview - Polymorphic Components
&lt;/h3&gt;

&lt;p&gt;First, let’s see how we would use polymorphic components in react. Say we have a &lt;code&gt;Button&lt;/code&gt; component that we want to render as an HTML link. If Button is a polymorphic component, we can write it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&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;./Button&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;as&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://open.spotify.com"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  )
}

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, our button will render as &lt;code&gt;a&lt;/code&gt; tag and it also accepts &lt;code&gt;href&lt;/code&gt; attribute.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Implementation:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: To implement this in your react app, you need to have Typescript set up.&lt;/p&gt;

&lt;p&gt;Now, let's implement a Basic example for this, without type checking for now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;any&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;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;&amp;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;Button&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 avoid type checking by setting the type to &lt;code&gt;any&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here, we render our component using the &lt;code&gt;as&lt;/code&gt; prop or if it's not provided, use the &lt;code&gt;button&lt;/code&gt; tag as fallback.&lt;/p&gt;

&lt;p&gt;Here's the line which makes this work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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 all we need to build a basic implementation.&lt;/p&gt;

&lt;p&gt;However, the problem with this approach is that there is no mechanism to prevent the client from passing incorrect props.&lt;/p&gt;

&lt;p&gt;Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&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;./Button&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://open.spotify.com"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  )
}

export default App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are passing the &lt;code&gt;href&lt;/code&gt; prop, which belongs to &lt;code&gt;a&lt;/code&gt; tag, without setting the &lt;code&gt;as&lt;/code&gt; prop to &lt;code&gt;a&lt;/code&gt;.&lt;br&gt;
Ideally, TypeScript would catch this bug immediately, and we would see an error.&lt;/p&gt;
&lt;h3&gt;
  
  
  Type checking using Typescript!
&lt;/h3&gt;

&lt;p&gt;Next up, we are gonna tighten up the prop type using Typescript.&lt;/p&gt;

&lt;p&gt;Here's a basic implementation for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&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;ComponentPropsWithoutRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ElementType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&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;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ElementType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;ComponentPropsWithoutRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&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;children&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;/Component&amp;gt;&lt;/span&gt;&lt;span class="err"&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;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, this code involves generics. The following line made this component generic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ElementType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ElementType&lt;/code&gt; is a type from React. We set our parameter T to ElementType to ensure our button only accepts HTML tags and other React component types.&lt;/p&gt;

&lt;p&gt;At this point, our Button component can dynamically calculate the props it accepts based on the value of as. If we try our client example earlier, we will see an error like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641050583211%2FAFT0C_N1N.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641050583211%2FAFT0C_N1N.png" alt="Screenshot (330).png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, we get an error stating that &lt;code&gt;Property 'href' does not exist on type 'IntrinsicAttributes &amp;amp; MyButtonProps&amp;lt;"button"&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's it! Our Button component no longer accepts the &lt;code&gt;href&lt;/code&gt; property because it doesn’t render itself as a link. If we add &lt;code&gt;as="a"&lt;/code&gt;, the error goes away.&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Get Started with Supabase Database in NextJS! ⚡</title>
      <dc:creator>Anurag</dc:creator>
      <pubDate>Thu, 09 Dec 2021 15:04:32 +0000</pubDate>
      <link>https://dev.to/byteslash/get-started-with-supabase-database-in-nextjs-48gj</link>
      <guid>https://dev.to/byteslash/get-started-with-supabase-database-in-nextjs-48gj</guid>
      <description>&lt;p&gt;🙋‍♂️Hello Everyone&lt;/p&gt;

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

&lt;h2&gt;
  
  
  In this blog post, we're gonna Get Started with Supabase Database in NextJS!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One of the coolest things about Supabase is its database and for building full-stack apps, we all like to use NextJS, so in this tutorial, I'm gonna show you how can we integrate the two!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why choose Supabase
&lt;/h2&gt;

&lt;p&gt;In case you don't know about Supabase Database, here are a few points to catch up on!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It's free to use and follows the &lt;em&gt;pay as you go, model,&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;The free version provides unlimited read and write requests!&lt;/li&gt;
&lt;li&gt;The free version contains 500 MB of space&lt;/li&gt;
&lt;li&gt;It's a SQL Based database&lt;/li&gt;
&lt;li&gt;It is one of the easiest databases to get started with!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, let's jump right in!&lt;/p&gt;

&lt;h2&gt;
  
  
  What we're building today:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.loom.com%2Fshare%2Fd39e39db3c634b3d8ed2df61b554de69" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.loom.com%2Fshare%2Fd39e39db3c634b3d8ed2df61b554de69" alt="Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, you need to set up a project in &lt;a href="https://supabase.io/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;, you can go to their official website and create a free project! In case you don't have an account there, you need to make an account there.&lt;/p&gt;

&lt;p&gt;Go to Supabase, and click on create a new Project, choose a name and a password, and you're good to go!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638968211764%2FoCcXRuJLU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638968211764%2FoCcXRuJLU.png" alt="Screenshot (296).png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next up, create a new table in the database named &lt;em&gt;responses&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638970345348%2Fcit4t6yG2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638970345348%2Fcit4t6yG2.png" alt="Screenshot (298).png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638970419288%2F_mdgg2ZU6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638970419288%2F_mdgg2ZU6.png" alt="Screenshot (299).png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let's jump to the coding part! &lt;br&gt;
So, we're using NextJS for this demo, and I'm using Tailwind as my UI preference. But you can use your preferred UI Framework as your preference!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app -e with-tailwindcss supabase-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we're gonna make a simple form. &lt;br&gt;
For this demo, you can just use the &lt;em&gt;index.js&lt;/em&gt; file. Clear up the boilerplate code.&lt;/p&gt;

&lt;p&gt;Now, we're gonna make a simple form!&lt;/p&gt;

&lt;p&gt;First, make the main div and align its children to the center using flexbox&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="min-h-screen min-w-screen bg-purple-500 flex justify-center items-center"&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can add input fields and a submit button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className="min-h-screen min-w-screen bg-purple-500 flex justify-center items-center"&amp;gt;
  &amp;lt;form className="p-8 bg-white shadow rounded flex flex-col justify-center items-center"&amp;gt;
    &amp;lt;input
      type="text"
      className="m-2 outline-none py-2 px-4 border-2 border-black-200 rounded focus:border-blue-400 text-black-300 text-xl"
      placeholder="Your Name"
    /&amp;gt;

    &amp;lt;input
      type="text"
      className="m-2 outline-none py-2 px-4 border-2 border-black-200 rounded focus:border-blue-400 text-black-300 text-xl"
      placeholder="Your Email"
    /&amp;gt;

    &amp;lt;button className="m-1 p-2 bg-green-500 text-white font-medium text-xl grid place-items-center rounded"&amp;gt;
      Submit
    &amp;lt;/button&amp;gt;
  &amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we are gonna use hooks to get the input values:&lt;/p&gt;

&lt;p&gt;First, let's make two variables using the &lt;em&gt;useState&lt;/em&gt; hook&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const [name, setName] = useState('')
  const [email, setEmail] = useState('')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we will assign these values to the input fields and update them if the value changes. We can do this using the onChange event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;input
    type="text"
    className="m-2 outline-none py-2 px-4 border-2 border-black-200 rounded focus:border-blue-400 text-black-300 text-xl"
    placeholder="Your Name"
    value={name}
    onChange={(e) =&amp;gt; setName(e.target.value)}
  /&amp;gt;

  &amp;lt;input
    type="text"
    className="m-2 outline-none py-2 px-4 border-2 border-black-200 rounded focus:border-blue-400 text-black-300 text-xl"
    placeholder="Your Email"
    value={email}
    onChange={(e) =&amp;gt; setEmail(e.target.value)}
  /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now, you should have a simple form that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1639054552792%2FfcufKw4gE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1639054552792%2FfcufKw4gE.png" alt="Screenshot (304).png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we will work on the database part, first, we will install &lt;em&gt;supabase-js&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @supabase/supabase-js     # for npm
yarn add @supabase/supabase-js     # for yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we need to initialize supabase, go to the project dashboard on supabase, and get your keys from there. Then, follow along:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  "&amp;lt;your_project_url_here&amp;gt;",
  "&amp;lt;your_public_anon_key_here&amp;gt;"
);

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

&lt;/div&gt;



&lt;p&gt;Now, let's make a function to handle form submit.&lt;br&gt;
We are gonna structure the form data in a new variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleSubmit = async () =&amp;gt; {
  const form = {
    name: name,
    email: email,
  };
};

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

&lt;/div&gt;



&lt;p&gt;Now, we're going to upload the form data to Supabase Database!&lt;br&gt;
Here's how we're gonna do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleSubmit = async () =&amp;gt; {
  const form = {
    name: name,
    email: email,
  };

  const { data, error } = await supabase
    .from("responses")
    .insert([{ response: form }]);

  error ? console.log(error) : console.log(data);
};

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;And, That's it!!&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Now, you can fill the form and submit it to see the data update in the database!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/11F0d3IVhQbreE/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/11F0d3IVhQbreE/giphy.gif" alt="well-done"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>database</category>
    </item>
  </channel>
</rss>
