{"componentChunkName":"component---src-pages-author-author-yaml-id-js","path":"/author/siddhant-varma/","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"id":"893e5b7c-0511-5997-acf7-15f1076c0f15","html":"<p>SolidJS is a declarative JavaScript framework used for building UIs and web applications pragmatically and performatively. Even though it's relatively new, its similarity with other JavaScript frameworks like React and Svelte has made it more adoptable for the developer community. </p>\n<p>So in this tutorial, I'll give you a complete walkthrough of SolidJS and help you understand the essentials. You'll also build a simple web application with SolidJS to get a better hang of the basics. Finally, I'll compare and contrast it with the most popular framework in town — React. </p>\n<h2 id=\"what-is-solidjs\" style=\"position:relative;\"><a href=\"#what-is-solidjs\" aria-label=\"what is solidjs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is SolidJS?</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACW0lEQVQoz0VS21LTUBTNv+mL4wX1wTd/wtEZuTkD+sqLIwpPchmh0wtpGUQotKU0UOy9ITlNStI2acmlhfETlvucQnlYZycnZ6+z1tqRPm2e48y6RssL0PKH2FPO8WNrC+vJFDZSKSSOM1iTkwQZq5GI+Labz2MhqeGI9WFQX6xoY+XIwFKyAWn5QIfhh4LQGo6oeqhZFuq2jYplo9S2Ub7i1ULJ5Gij2XOQ0zrQrwOYwVD0m0EIbRBAyuiueFFaPexX2kjXLRw3OzisE4k9oG8jMG8o1OteiGLbpbMOLq5cFFhX9F32fSLz6QIfEl/s0QiffxXw+EMEr+bieD2/g0fvtrEUv0Dv9gZNxxMqTkjVk5kdTM3u4MVsAs+m43g5l0C1O46Mk0qc3RwNsZ9l+Pb1FIflNvZLGuRCDQqzSV04UdB0fRweHGEtncPGnyJ+7p0idlJDozcQ9gUhXxhZLmsOjtMt6O41FFVFrlKB5vZhhjyjAMboBlemjWF6HoqZxUmlgXytCqWpot5xiDAEu7cs/PMph+FdFsFDXkYPZwIOFL1D1YI68IRqtT+u4jz1HZg0lLJDRER6SRv31hiRV7sDvF2UMTUdxfOZcVZPP8bwZiGF2iQzwp1VRlXWSeFvY7zJBPwHhUS+UrKwXjQRzVaxzZGpIFFoisvvM+O4JGLT85GxQ0jf811EVZ/YA2StAOMIxqp3g38ohreUr4a/jFGmLl30MIBJXMJViE2lDWkhpuKLrGFRZtht8H8yEAo4qUFZcaUaBc4z5cFrE7I7y/Rs0FDj5Q7er2bxH3UH7eTP28LLAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Features of SolidJS\"\n        title=\"Features of SolidJS\"\n        src=\"/static/9d5253ce2f2f38b45c825b4c98ea94ca/e5715/features-of-solidjs.png\"\n        srcset=\"/static/9d5253ce2f2f38b45c825b4c98ea94ca/a6d36/features-of-solidjs.png 650w,\n/static/9d5253ce2f2f38b45c825b4c98ea94ca/e5715/features-of-solidjs.png 768w,\n/static/9d5253ce2f2f38b45c825b4c98ea94ca/7b67d/features-of-solidjs.png 2240w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>SolidJS takes the syntax and developer experience of React and combines it with the performance of Svelte to give you the best of both worlds.</p>\n<p>Just like React, Solid uses JSX to render HTML in the browser. It also uses similar syntax for reactivity to update DOM in real-time. However, unlike React, it uses a compiled DOM instead of virtual DOM. </p>\n<p>This means you get a smaller size pure JavaScript bundle, much like the production bundle of your Svelte or Vanilla JS application. This makes it blazingly fast and highly performant.</p>\n<h2 id=\"solidjs-essentials\" style=\"position:relative;\"><a href=\"#solidjs-essentials\" aria-label=\"solidjs essentials permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>SolidJS Essentials</h2>\n<p>Let's now understand the fundamentals of SolidJS using some code examples. To follow along, you can directly run these snippets in the <a href=\"https://playground.solidjs.com/\">SolidJS playground</a>. </p>\n<h3 id=\"architecture\" style=\"position:relative;\"><a href=\"#architecture\" aria-label=\"architecture permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Architecture</h3>\n<p>Solid follows the component architecture for modularity and reusability. Let's see how you can create an entry component and render it to the DOM. </p>\n<p><a href=\"https://playground.solidjs.com/?hash=1358759546&#x26;version=1.4.1\">Here's a component <code>HelloWorld</code></a> that is injected into the DOM inside an HTML element that has an id <code>app</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">HelloWorld</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello World</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">HelloWorld</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;app&quot;</span><span class=\"mtk1\">)!);</span></span></code></pre>\n<p>From the above code, it's also clear that components are functions that return the HTML template using JSX.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 38.76923076923077%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAYAAAD5nd/tAAAACXBIWXMAABYlAAAWJQFJUiTwAAABdElEQVQoz3WS604CMRCF9yVUFmi3ewe5hOBuYW+KAvG3oGjUxMdQwEviix9nihpj9MeX6ZlOz3S6a509vGNy+4LJ3Sv08gl68YTRck1QvNwgWz1TXCNdPCK9eDTrbLVFcb3F+GqDk9tXlDfPRp/ev8Eqqwmy8gRZVqLIcuREkmokSYpkVCDLK0xnc8zm5zibzlFWx5QroEdjpHqEo0RjTPqI6ouyguW4HoLQh+cqiEYDTaJerxsaxP7+Hnq9HrTWGA6HcF0XtdrBZ429i7YNm/A8D1YYhIjCmIQPISWEELtISOkYfdjp0Fqaw0JIOI5j9r5gzfkoimF5vktdPShydxwFpVgrg1IKzWYTHTLk7tI0+RtuHEURrCjywWMrGtv1fQTUJY5DQ0CaDbvdrhmVb8j6N2zWoKcKggCWELvEN6ZIGFjzgXa7jTAM0Wq1DHEcG9iA4T2O/X4flpQCUvw/CnfmG6ZpSn9CZj7MYDAwsMFP8jzHB4lL8V3B7Cf1AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"HelloWorld Example\"\n        title=\"HelloWorld Example\"\n        src=\"/static/fcef69bea460903232532ef90c48da89/e5715/hello-world-example.png\"\n        srcset=\"/static/fcef69bea460903232532ef90c48da89/a6d36/hello-world-example.png 650w,\n/static/fcef69bea460903232532ef90c48da89/e5715/hello-world-example.png 768w,\n/static/fcef69bea460903232532ef90c48da89/d9ed5/hello-world-example.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Solid components allow only a single JSX element at the top level. To combat this, you can use special JSX elements called fragments: </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Hello World </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">This is my first solid app </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span></code></pre>\n<h4 id=\"nesting-components\" style=\"position:relative;\"><a href=\"#nesting-components\" aria-label=\"nesting components permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nesting Components</h4>\n<p>Components can be nested inside one another. For instance, here you have a <code>&#x3C;Header/></code>component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Header</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     Header</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Header</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>That is rendered inside the main <code>&#x3C;App/></code>component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Header</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./header&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Header</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      Hello World</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;app&quot;</span><span class=\"mtk1\">)!);</span></span></code></pre>\n<p>That should give you both the components on the DOM like this:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.46153846153847%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAABpUlEQVQoz5WRWVPCMBSF8zMUuqTpikJLYRwp4IYVF0oRBkd9dRkd3P//w/EmiKDoOD58c5Obk3vvSVgyfEZzMMHW8AlJ/oBKeoXw4BoREdK62r1BfHiLjd49NgeP2Mju0MxfkYzf0Mgn2Bm/ok13t0YvaJ0+gaXZBbr5JdL+BXYPR8QQ291TtNIB2oSMrf0+mgdjdHrnSLNzJJ0MrU4fe8dnSit1O0cj0uZgDucoldYQBAF8y4TDdRjaKrTCypziNOoUt9sJst4JanFE+286ggnbhU1wi0M3DIVhmDBMcxoX1ibFer2GWq2u4JY113/ABCW9UgnCdaDrNJ0SzJnlZOTkpry+hkKhoFg8m+mZbdtwXA8y6poGTaErFoXTgibK5XW1N9XUxhIsCHwIIZQtLmzYDjVwBDUQ4JT7OuG0oEZrrVj8aP4VJotZZNskO38XlB8YkF7A9/1PPM+jOw5c1wWTwjmL3ZYtS5thWKGPqaPRaCCOY0W1WkUURSrPfnqH3z5FFoyiUE0k31y6myH3kj8LLk1YKX9elja/8/+CZFm+1U/FJO9tJ2BDgIGOqAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Header and HelloWorld\"\n        title=\"Header and HelloWorld\"\n        src=\"/static/414b0805fab01839d7fc5a7b677f3d4a/e5715/header-and-hello-world.png\"\n        srcset=\"/static/414b0805fab01839d7fc5a7b677f3d4a/a6d36/header-and-hello-world.png 650w,\n/static/414b0805fab01839d7fc5a7b677f3d4a/e5715/header-and-hello-world.png 768w,\n/static/414b0805fab01839d7fc5a7b677f3d4a/d9ed5/header-and-hello-world.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h4 id=\"props\" style=\"position:relative;\"><a href=\"#props\" aria-label=\"props permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Props</h4>\n<p>Props are data and functions you can pass from one component to another to share data and features between the two components. In the previous example, you can pass a <code>title</code> prop to the <code>&#x3C;Header/></code> component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Header</span><span class=\"mtk1\"> </span><span class=\"mtk12\">title</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Header&quot;</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>Then consequently consume this prop inside the child component: </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Header</span><span class=\"mtk1\">({</span><span class=\"mtk12\">title</span><span class=\"mtk1\">}) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk4\">{</span><span class=\"mtk12\">title</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Header</span><span class=\"mtk1\">;</span></span></code></pre>\n<h3 id=\"reactivity-and-events\" style=\"position:relative;\"><a href=\"#reactivity-and-events\" aria-label=\"reactivity and events permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Reactivity and Events</h3>\n<p>Reactivity allows you to create variables that dynamically trigger a DOM update when changed.</p>\n<p>SolidJS allows you to create reactive variables called <em>signals</em> using the <code>createSignal</code> function. This function takes in the initial value of the variable as a parameter. And it returns an array where the first element is the variable itself and the second element is a function used to mutate that variable.</p>\n<p><a href=\"https://playground.solidjs.com/?hash=776620219&#x26;version=1.4.1\">Here's an example</a> that changes the reactive variable called <code>name</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">DisplayName</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">name</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setName</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;fuzzysid&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">changeName</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk11\">setName</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;siddhant&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">changeName</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Change Name </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">DisplayName</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;app&quot;</span><span class=\"mtk1\">)!);</span></span></code></pre>\n<p>Initially, the name outputs the string 'fuzzysid':</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 43.84615384615385%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABf0lEQVQoz32R2VLCQBBF8xMoBMgkmS1BEQIChiWIKL5R5Vr6rp/ggnz8tadDyQvlw6k7vcydTscrXreYE7OXH5zffTDD+08M7kqGTikePWyIL6p9sY6fN7h4/EbxskX+tMHk+Ydjb7FYYUrMiiXm8yvSBYb5DKPxnuG4wPhyheXNLabzJeUKFItrPl9MqDa9xITuuV5PqQSnWRdpqwUdhdCxQKPuo+7X4NeqjDsfH1WgZIT3tzemTj3V6vFfT22nnk7baGcdmNYJTk5TnLVTtIxGGIYIggCBEBBEs9lEklis12usVrecP4SnlYGyKSKpEEYxG7GZKA2dkdNGowFrDdcqlUr5WEA1ru/xnEmsE0ht2VgqBa00RCTRPGCYJMnO7DA0oaTLEYSWCOMY0hgYI2GNop3Ff417Qwvf9zk+hOf2I+gzBP0QpyGZR3R2hG4vO0M3qaXdGqac1FrLaK0Zl/dc43+UuykndGa9Xg95nmMwGKDb7SLLMnQ6Habf7+MXDOYPVqQlEeoAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Reactivity Before Update\"\n        title=\"Reactivity Before Update\"\n        src=\"/static/41c08d39e8885ee93e09ebbd571bf0b1/e5715/reactivity-before-update.png\"\n        srcset=\"/static/41c08d39e8885ee93e09ebbd571bf0b1/a6d36/reactivity-before-update.png 650w,\n/static/41c08d39e8885ee93e09ebbd571bf0b1/e5715/reactivity-before-update.png 768w,\n/static/41c08d39e8885ee93e09ebbd571bf0b1/39148/reactivity-before-update.png 2876w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>A click event is used on the button that fires a function called <code>changeName</code>. When you press the <em>Change Name</em> button, the <code>changeName</code> function updates the <code>name</code> signal to 'siddhant':</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 43.23076923076923%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABkklEQVQoz32S61LbMBCF9RRp6pts62I5cRLiOLYcSEj7CLQDbXmFzJQ/LYXw7qcrmQDDdPrjm5296MzqSOzT7RM+3x5x+f0R7dUvdFe/Yb+85x6b6yPOrx/Qf733bG8efb7/ccTFzQN231z+B6y3GzREt7Y4txa2bbGsa9T16pVVg3W3wXZ7gd3uEtb26Dd0prPUW2HVUL/t/DmmTYWzdYNyWqGQgsiRxBHCMEQQBJ4wDDAef0CWpTgcDvh5dwfOOdXGCJ9nguCjj0xPZpidzaFMiaoymE0NSiWRpimSJPG4w3Eco9Aa+/0efd/72qk/MORMCYVMFUhzgYSTCA1yzyDohFyMoghaK+R5jtFo9CI09F9hTkhoA0GisighpISSCjwTiN8JFiRYlual9i+YFDl4noErQVvmkHQtrclLLSEoj58HT4LGGO9VFIXeZ4frnWD+euQXJ8NdTLPMm+9I3/jktnJXLgrtRatqislk4jGmoN5QZ27wfyRvNtT0WMvlEi19rYa+ynw+x2Kx8NFR07f5C0B4DgyWnkafAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Reactivity After Update\"\n        title=\"Reactivity After Update\"\n        src=\"/static/a7867711b63ad1711fe106153ac7b921/e5715/reactivity-after-update.png\"\n        srcset=\"/static/a7867711b63ad1711fe106153ac7b921/a6d36/reactivity-after-update.png 650w,\n/static/a7867711b63ad1711fe106153ac7b921/e5715/reactivity-after-update.png 768w,\n/static/a7867711b63ad1711fe106153ac7b921/d9ed5/reactivity-after-update.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>What a <code>state</code> is to React components, a <code>signal</code> is to Solid components. <a href=\"https://playground.solidjs.com/?hash=-1579873004&#x26;version=1.4.1\">Here's another useful and typical example</a> of reactive variables:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Counter</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">count</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setCount</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Counter: </span><span class=\"mtk4\">{</span><span class=\"mtk12\">count</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">setCount</span><span class=\"mtk1\">(</span><span class=\"mtk12\">count</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">count</span><span class=\"mtk1\">-</span><span class=\"mtk7\">1</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">  Decrement </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">&nbsp;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">setCount</span><span class=\"mtk1\">(</span><span class=\"mtk12\">count</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">count</span><span class=\"mtk1\">+</span><span class=\"mtk7\">1</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">  Increment </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Counter</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;app&quot;</span><span class=\"mtk1\">)!);</span></span></code></pre>\n<p>You can take the current value of a signal inside the signal's mutation's callback function. The above code used the present value of <code>count</code> to increment and decrement it accordingly. </p>\n<h3 id=\"effects\" style=\"position:relative;\"><a href=\"#effects\" aria-label=\"effects permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Effects</h3>\n<p>Effects are triggers or watchers that can help you fire a function when a signal updates.</p>\n<p>Let's say, in the previous example, you want to throw an alert when the count becomes greater than 5.</p>\n<p>To do so, you can create an effect using the <code>createEffect</code> function. It takes a callback function as a parameter. This callback function is fired whenever a signal invoked inside it changes. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">createEffect</span><span class=\"mtk1\">(()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk11\">count</span><span class=\"mtk1\">()&gt;</span><span class=\"mtk7\">5</span><span class=\"mtk1\">) </span><span class=\"mtk11\">alert</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Count is greater than five&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">})</span></span></code></pre>\n<p>So now, if you click on the <em>Increment</em> button, you should get an alert when it becomes greater than 5:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 44.15384615384615%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABwklEQVQoz2WSTW/TQBCG/SMgIk2y6/3wer3xR6K0dRPHcVNXBHIBIaCIUzkA14gDtEL89pdZG0IkDo9mPLN658tB/fEXNh8e0RDLt9+xePUNF2/I7r+iXK6xrq+xOC+RuAxummOaFjh/+QXV3U96/wP13SPW7x+weveAigja9gWa7XPUxKZp0Vy3qOotLsoVbJJ2xNbBGAuXztC+/oyy2uJyWWHd3GBFBctVjWpzg2XVIAi5hIos4jSFUBo6iiA4h2ATcLKTyQSMMTDyh8Mh2ttbHA4HfLq/x2xWYPD0Cc7OhpR71hEoHSGlhCtmJBwjNhpxbBDysBfq6EVHoxGuri6x3++x2+1QFAXG474w+0OglYI1EbSW0FJAUlCJsPM5Z32HxN9Op1OHwWDQ4Qv4WJ/rIUGNiEbWkYHU1JlUlKBR6aGv3FVn/NhtnmcncfYfgRQCOqELFgskaY4sc7TPHIauahNLV6XdRslxdC84Ho+77jzePyWIjYEgURaG4ISQEtKPTlb42EmH3k9pZEVrSqmQc64jSRL6CwystTQy7U4pCU6EJKJNTEl/GA1F3/921I9UFDnm8znKsqRu8yNZlnXx37VcDjNxtfqhAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Effects Example\"\n        title=\"Effects Example\"\n        src=\"/static/5bfec53557d129d8aae31fb9f40f7a0a/e5715/effects-example.png\"\n        srcset=\"/static/5bfec53557d129d8aae31fb9f40f7a0a/a6d36/effects-example.png 650w,\n/static/5bfec53557d129d8aae31fb9f40f7a0a/e5715/effects-example.png 768w,\n/static/5bfec53557d129d8aae31fb9f40f7a0a/d9ed5/effects-example.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"conditionals\" style=\"position:relative;\"><a href=\"#conditionals\" aria-label=\"conditionals permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conditionals</h3>\n<p>Solid provides special components called <code>&#x3C;Show></code> to render a template based on a condition or the value of a signal. <a href=\"https://playground.solidjs.com/?hash=1279589651&#x26;version=1.4.1\">Here's an example of that</a>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\">,</span><span class=\"mtk12\">Show</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Counter</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">count</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setCount</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Counter: </span><span class=\"mtk4\">{</span><span class=\"mtk12\">count</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">setCount</span><span class=\"mtk1\">(</span><span class=\"mtk12\">count</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">count</span><span class=\"mtk1\">-</span><span class=\"mtk7\">1</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">  Decrement </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">&nbsp;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">setCount</span><span class=\"mtk1\">(</span><span class=\"mtk12\">count</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">count</span><span class=\"mtk1\">+</span><span class=\"mtk7\">1</span><span class=\"mtk1\">)</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">  Increment </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Show</span><span class=\"mtk1\"> </span><span class=\"mtk12\">when</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk11\">count</span><span class=\"mtk1\">()&gt;</span><span class=\"mtk7\">5</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Count is greater than five </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Show</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Counter</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;app&quot;</span><span class=\"mtk1\">)!);</span></span></code></pre>\n<p>Once the <code>count</code> becomes greater than 5, the <code>&#x3C;p></code> will start showing on the DOM:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 44.15384615384615%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABpklEQVQoz22QyZLTMBCG/Q6Qg+NNsuQtXmKHxGsSE4ZjcmGn4BGGW2pgAgfe/Kel1LgCxeGrbnW3/l6M8etvHL78witi+PCIzZsHNIq33//m3Q907x/RklUMHy9Uf8H+80/sPl30e0cY4/6AbtijHUYM/Q7bYYu27bDeNDfUWDdb9LsRd3evUTcdXlC87beo217XtN2ATd3C4EwgiBdIiiWEDCE5h/QZbMvCfG4Sc20tYvb8GQ4vR5zPZ3y7v0dT15jNZrAsqjFNXWcIGSCMU4goBhcBglBCSgHXdeE4Ckf7nse03/cdjscjTqcTqmoF27Yp58FVuB4J+j5kuECcFYgWGeIkhgivBEGAKIrAqJESVWRZCtOc68mV2LWxanrF8GnFIC+RrxssyxJZvkCYpJNg+I9gkWeT/z8Mnyb06aMMaFUhwBnXo1t0QzWBwnHsafVlkeuYyt/yFDPCMADndB9GN2CM7igghE/TCfg+nzo/CaZpQnmBPM9p/YzeqUadJkmS64SMBD1anRG+lFpQEpwa3IopW5YFVqsVmqZBURQTqkFVVfgDaqIRVH3BTXQAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Conditionals Example\"\n        title=\"Conditionals Example\"\n        src=\"/static/7aec3c908829756166d7e070b184627d/e5715/conditionals-example.png\"\n        srcset=\"/static/7aec3c908829756166d7e070b184627d/a6d36/conditionals-example.png 650w,\n/static/7aec3c908829756166d7e070b184627d/e5715/conditionals-example.png 768w,\n/static/7aec3c908829756166d7e070b184627d/d9ed5/conditionals-example.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"loops\" style=\"position:relative;\"><a href=\"#loops\" aria-label=\"loops permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Loops</h3>\n<p>Just like <code>&#x3C;Show></code>, Solid also provides a special component called <code>&#x3C;For></code> to render a list on the DOM from an array. </p>\n<p>In the <a href=\"https://playground.solidjs.com/?hash=195732488&#x26;version=1.4.1\">following example</a>, you use the <code>&#x3C;For></code> component to render a list of fruits from the <code>fruits</code> signal. Inside the opening brackets of the <code>&#x3C;For></code> component, you specify the variable name that will be used to extract items to loop through using the <code>each</code> prop. </p>\n<p>Then, you can take a callback inside which you get the individual item as the first parameter and an optional index of the iteration as a second parameter.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\">, </span><span class=\"mtk12\">For</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Counter</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">fruits</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setFruits</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">([</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;Mango 🥭&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;Apple 🍎&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;Banana 🍌&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;Melon 🍈&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;Watermelon 🍉&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ]);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\"> Fruits </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">For</span><span class=\"mtk1\"> </span><span class=\"mtk12\">each</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk11\">fruits</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">fruit</span><span class=\"mtk1\">,</span><span class=\"mtk12\">index</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk11\">index</span><span class=\"mtk1\">()+</span><span class=\"mtk7\">1</span><span class=\"mtk4\">}</span><span class=\"mtk1\">: </span><span class=\"mtk4\">{</span><span class=\"mtk12\">fruit</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">For</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Counter</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;app&quot;</span><span class=\"mtk1\">)!);</span></span></code></pre>\n<p>Here's what the list looks like when rendered in the DOM:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 46.15384615384615%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABc0lEQVQoz2VSaVLCMBjtMaRLmjahQFLaWqBlsQp4ApFBdMZT4IZ/PPozSa1sP968b98Sa/H6g+XL3qDafKB82GG82mGyeqvxqFnp609U229M1+8Yq5hqo/SnL8yf90a+2+5xo/KtSTFGWUwwGs8Ul5gWBYrhAFmWIU3TA64HGA5HuF8uUFW3yHOtD//j8jw3bNGAod3ro5ukCHiEiDN0Ig7XdWHbNhzHMdCy3WqhKAvMZxM4rSu0tF/b/+A4NqyQcRRZjFREcIkPSimCIIDv+ycghgnKssRyXoGHFB4hIGewOGNIuhFEm8FTU3medwFCaqbUhxQ9JRP4Krn2nRfkHCzkZjIziXY0fJTQFIxjeVHkpGAYBgijDrLBAEJKRKIP3uldBNYFKaQU5qau65g7N9B+zWZC39ysSfbrVd3jlQ8TCrWylLF54eYHJEmibNKw1Y7a5hGI6k5UAg1C6KkZC2u7aVIX1k2zLDVfRUMIcYI4jvELgJEL+TBslwEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"For Example\"\n        title=\"For Example\"\n        src=\"/static/4f38c58718891a069960d064d57822f9/e5715/for-example.png\"\n        srcset=\"/static/4f38c58718891a069960d064d57822f9/a6d36/for-example.png 650w,\n/static/4f38c58718891a069960d064d57822f9/e5715/for-example.png 768w,\n/static/4f38c58718891a069960d064d57822f9/d9ed5/for-example.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"lifecycle-methods\" style=\"position:relative;\"><a href=\"#lifecycle-methods\" aria-label=\"lifecycle methods permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Lifecycle Methods</h3>\n<p>Most frameworks provide several lifecycle methods for different purposes. This often leads to a steeper learning curve as well as unnecessary complexity.</p>\n<p>Solid stays truly reactive: it gives you the <code>createEffect</code> and signals to build whatever interaction you want. However, to simplify things further, it gives you two primary lifecycle methods. </p>\n<h4 id=\"onmount\" style=\"position:relative;\"><a href=\"#onmount\" aria-label=\"onmount permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>onMount</h4>\n<p>The <code>onMount</code> method is fired just once in the entire lifecycle of a Solid component. It runs only the first time your component mounts on the DOM. It's an excellent place to make any API calls your application needs.</p>\n<p>For instance, consider the <a href=\"https://playground.solidjs.com/?hash=-1837326429&#x26;version=1.4.1\">following example</a> that uses the <code>onMount</code> method to fetch and render some data:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\">, </span><span class=\"mtk12\">onMount</span><span class=\"mtk1\">, </span><span class=\"mtk12\">For</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">posts</span><span class=\"mtk1\">, </span><span class=\"mtk12\">setPosts</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">([]);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">onMount</span><span class=\"mtk1\">(</span><span class=\"mtk4\">async</span><span class=\"mtk1\"> () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\"> = </span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk8\">`https://jsonplaceholder.typicode.com/posts`</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setPosts</span><span class=\"mtk1\">(</span><span class=\"mtk15\">await</span><span class=\"mtk1\"> </span><span class=\"mtk12\">res</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Effects: onMount</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">For</span><span class=\"mtk1\"> </span><span class=\"mtk12\">each</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk11\">posts</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">post</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">{</span><span class=\"mtk12\">post</span><span class=\"mtk1\">.</span><span class=\"mtk12\">body</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">For</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;app&#39;</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>It renders a list of posts fetched from a dummy API:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 48.92307692307692%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB3klEQVQoz22S6W7aQBSF/RSNABvwMh6DcTF4X7CxA83vtuki5TmapGmlPvrpmSmpUNUfR/eONXP83cXoH35hePiJkWo+f0f+/huKj4/Uk1b5qvtn1J9edJ5/eGT+jOr+Cd3XH1rtlxccGI3+MKBqOpRNj6Zu0TYtiqJClhdIM6UcaUoVjb53fneH43CLpu1wOt+hrBrs9ilyvkl4z7CXLoRcww9D2K6A47pwljbs+Ryz2RSTyQRTpekENzdvkCZ7nE5ndF2H4/GI7XYLz/MgBN86DgyXSbjbQ25iiGCFVSAoH45N0+WScanjYrGAZVkkz2g0kHJEziryokBV1ajrBkmSwhB0X29CBDLEehUg8D1I18FKuAgoFQXPcxKbpomShuN4i74/YqBp1/Vo24P+SRS9JaFLXI9EDolsByYp/sq8iPmrYUXDYRy12eHQkTLXpBmjlBKGqtvxJSk3kEHAPnr68f80m81Ql4UmVGaKTEVFqYiTJKEhe+UIHzKM9EDm7NW1ieqbdSFUcbeLda8UWZZlWmmaIY7jP4Z6Op6AxXJMEqiyrsv8V9ttpCerjKIowoaVKYXcEvXdkFJw7C4WpPPlCiEHE619hNLX07WujFUex1yTy4oouWrNKB15/g3IWjYPDF+mngAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"onMount Example\"\n        title=\"onMount Example\"\n        src=\"/static/c0f0e6692797e95e552866929aabc018/e5715/on-mount-example.png\"\n        srcset=\"/static/c0f0e6692797e95e552866929aabc018/a6d36/on-mount-example.png 650w,\n/static/c0f0e6692797e95e552866929aabc018/e5715/on-mount-example.png 768w,\n/static/c0f0e6692797e95e552866929aabc018/d9ed5/on-mount-example.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h4 id=\"oncleanup\" style=\"position:relative;\"><a href=\"#oncleanup\" aria-label=\"oncleanup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>onCleanup</h4>\n<p><code>onCleanup</code> is the exact opposite of <code>onMount</code>. It's fired whenever a component unmounts from the DOM completely. Ideally, you can use this method to clear any event listeners you may have added to your DOM elements. </p>\n<p>Here's an example that does that:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">render</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js/web&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {  </span><span class=\"mtk12\">onMount</span><span class=\"mtk1\">, </span><span class=\"mtk12\">onCleanup</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;solid-js&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleMouseEnter</span><span class=\"mtk1\">=()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Entered the box&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">onCleanup</span><span class=\"mtk1\">(()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">box</span><span class=\"mtk1\">=</span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelector</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;#box&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">box</span><span class=\"mtk1\">.</span><span class=\"mtk11\">removeEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;mouseenter&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">handleMouseEnter</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">onMount</span><span class=\"mtk1\">(</span><span class=\"mtk4\">async</span><span class=\"mtk1\"> () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">box</span><span class=\"mtk1\">=</span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">querySelector</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;#box&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onMouseEnter</span><span class=\"mtk1\">=</span><span class=\"mtk12\">box</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;mouseenter&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">handleMouseEnter</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  });</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Effects</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;box&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">style</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk1\">{</span><span class=\"mtk12\">height:</span><span class=\"mtk8\">&#39;200px&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">width:</span><span class=\"mtk8\">&#39;200px&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">border:</span><span class=\"mtk8\">&#39;1px solid red&#39;</span><span class=\"mtk1\">}</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/&gt;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">render</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">App</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">document</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getElementById</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;app&#39;</span><span class=\"mtk1\">));</span></span></code></pre>\n<p>When you enter the red box, the <code>mouseenter</code> event fires, and you get a message on the console. As a cleanup, when the component unmounts, we remove this event listener from that <code>&#x3C;div></code>. </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 57.38461538461538%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAAByElEQVQoz21S2W7bMBDUXzSNdZIURVGSJVk1/JAUTtLjOW2aAP2GHk4L9Puns4QiGEIeBpR2ydmZ3Y0+fv+Hu6dn3D2ecHz4hav7HwHX9z9x/WWGxL6ecPv0F8dvp5A/Pvzm/x/c8t0NYzePzyEWvRsGTMOIfjdh5Pd+7DH1LVrvUDu7wPsaTe1wfH+Fz58+YOg7tA1j8z35ljPKco3SefjWQ5clslwhTRIkxGYTL4jjGG8uLjC0DfqmQZGkSN5eMrcJ+cv5jJRSMI6VGgdfGRitEQshCYQ0TdMFEh8bjzzLsIkTFIxlZ3lBZIxB09EibdfBFu1VFsZWKLQJl16INywykNAURXChJC7FzwlL2nTsTUWUtqRCBa0KqNJCzYSLQhL2tCyEGYnW6mZCg9K3MN0Evx0wDA26toYzGpoPDftrqnoh7EiY5XnoXTz3+gWSDwpLQzXs5WsV1wpl2l3XYb/fY5om7HY7jOMYYnJGmkPQ1sFxMKZyoXeWfTVSiJDTqJxtUEHVwNU6HA7o+55v3IKqqljMI7LWIqe19URfg6zFdtsFAnEUxJxBYiQUJQY5h2E4CF/TkueickmVFFpZFkJRIwSyIWv8B8IsQ45K/nRYAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"OnCleanup Example\"\n        title=\"OnCleanup Example\"\n        src=\"/static/3589ae72ca32c795711c4a5671315e4b/e5715/on-cleanup-example.png\"\n        srcset=\"/static/3589ae72ca32c795711c4a5671315e4b/a6d36/on-cleanup-example.png 650w,\n/static/3589ae72ca32c795711c4a5671315e4b/e5715/on-cleanup-example.png 768w,\n/static/3589ae72ca32c795711c4a5671315e4b/fd561/on-cleanup-example.png 2866w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"build-a-todo-app-with-solidjs\" style=\"position:relative;\"><a href=\"#build-a-todo-app-with-solidjs\" aria-label=\"build a todo app with solidjs permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Build a Todo App with SolidJS</h2>\n<p>Let's combine all that knowledge to build a small todo application with Solid.</p>\n<h3 id=\"setup\" style=\"position:relative;\"><a href=\"#setup\" aria-label=\"setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup</h3>\n<p>To get started, you'll create a new SolidJS project configured with <a href=\"https://vitejs.dev/\">Vite</a> by running:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npx degit solidjs/templates/js my-app</span></code></pre>\n<p>That should create a new Solid project for you. Navigate inside this project and open it in a code editor (like VS Code):</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">cd my-app && code .</span></code></pre>\n<p>Next, install the dependencies by running:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm i</span></code></pre>\n<p>And finally, kickstart the app by running:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm run start</span></code></pre>\n<p>That should open the project for you at <code>http://localhost:3000</code>. Awesome!</p>\n<h3 id=\"architecture--boilerplate-code\" style=\"position:relative;\"><a href=\"#architecture--boilerplate-code\" aria-label=\"architecture  boilerplate code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Architecture &#x26; Boilerplate Code</h3>\n<p>Your initial project structure gives the <code>&#x3C;App/></code> component by default. This is going to be your entry point component. For starters, clean everything that's inside it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">styles</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./App.module.css&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">styles</span><span class=\"mtk1\">.</span><span class=\"mtk12\">App</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">App</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Notice that you also have an <code>App.module.css</code> file being imported here. It's then referenced inside the <code>&#x3C;div></code> container. You'll add all our styles inside this <code>App.module.css</code> file and reference it the same way. </p>\n<p>Now let's create some boilerplate files. Here's what the architecture of our Todo app would look like:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACtUlEQVQozzWT228TVxDG/TfyVCRaJCQQqloQ15YHWplY3JQIRBICAsSlaQRx4tgh4A0hBMe54QQw2F6v7V17fd2ztkNA5AGefszZiIfRzNkz881835wN/fvfGquVNkXPx1I9jI0Mo+PjPIwnuDM5ydjEBBPPk9yPzXBT4jvRqSC+G42SXN+Qmj6T6xVuLVgMxbOERo0CloDlWx5l5VPxFPl6A6vd5l3F4b1j43SlWadD2etg+x45uc/W6hSkpqS6VHxfvmsMRWixIMUCkpPDw7dNhlJVhlfrDC67GHaf0cQmh64+4++7S5wce8nhwefENkqMvWlyPmkRNiwuLDUY2eoJhkeo2FHBdGbHZ3StztVXNtfTVS4vOTwtKgafrPDrxVnO3l7kz+F5fpP48XJemtb4K5EjPF8iku4wvNXlY1MANZhGLsuURr5J7G2VcsOm3G5gK4/6tk//21ecXg+1+5lP37+KLG3MZpNNM0/GdlkwW+QErNBWGlBRbHuikRdQf7xqcWZsgfP3U2KvOSVxZDwtyR5Xnqzx+3WDfx6kODGS5MiVaQaiGYxCC83UlJyQTsy4irTjsdXqMZ2x2Tcwxx835jk+8oLDQ0nO3XsddA8/SvHLhXhwd/SawYGLcyTeWMH0mqVREsB3zT3tjiVKnJotcnquxKV0g1K3T63fp9BwyVZrTG25mF43oKx2v1Drevi7O7S+7OztQAabKQjgM0ux7vosO4qVqiIlPmV7gcAf6i1S2TzreZPZbI3pzSoHInH2DyQ4eCkh085IHCfjNKkoxaLtE7qZksScx1PTIy2Apc6enloKTVNvvyCm3+iHeltoLxP5P83Q1Ib4leD83tU/RpdHK2VC4ehHIrE84ZhJItsIHrnemF6WpvLTtEa6gftpm9p2P9BNe1dMP+6pTYfTt1/xA/FE3HC767xPAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Todo App Architecture\"\n        title=\"Todo App Architecture\"\n        src=\"/static/9c267ef542e8d1c595072b7702a549b4/e5715/todo-app-architecture.png\"\n        srcset=\"/static/9c267ef542e8d1c595072b7702a549b4/a6d36/todo-app-architecture.png 650w,\n/static/9c267ef542e8d1c595072b7702a549b4/e5715/todo-app-architecture.png 768w,\n/static/9c267ef542e8d1c595072b7702a549b4/7b67d/todo-app-architecture.png 2240w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>You'll have your top-most parent <code>&#x3C;App/></code> component that would store all the todos and the functions to manipulate these todos. This <code>&#x3C;App/></code> component will have two child components. </p>\n<p>First, the <code>&#x3C;AddTodo></code> component will be responsible for adding a new todo.</p>\n<p>Second, the <code>&#x3C;Todos/></code> component will be responsible for rendering the list of todos via its own child — <code>&#x3C;TodoItem/></code> component. </p>\n<p>Create a JSX file for each of the above components. </p>\n<h3 id=\"the-addtodo-component\" style=\"position:relative;\"><a href=\"#the-addtodo-component\" aria-label=\"the addtodo component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The <AddTodo/> Component</h3>\n<p>The <code>&#x3C;AddTodo/></code> component will render an input field and a button. The input field is where the user types a new todo. The button will be used to send this new todo back to a function in the parent <code>&#x3C;App/></code> component to add this todo to the todos list. This function will be taken as props inside the <code>&#x3C;AddTodo/></code> component.</p>\n<p>To store the <code>newTodo</code>, create a signal since you want this property to be reactive based on what the user enters in the input. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setNewTodo</span><span class=\"mtk1\">]=</span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Now let's add the template inside the component's JSX:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;solid-js&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">AddTodo</span><span class=\"mtk1\">({</span><span class=\"mtk12\">addTodo</span><span class=\"mtk1\">}){</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setNewTodo</span><span class=\"mtk1\">]=</span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">onChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleChange</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk11\">newTodo</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Type a new todo...&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleClick</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Add Todo</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">AddTodo</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>You bind the input field to the <code>newTodo</code> signal. You now need to create the <code>handleChange</code> function that updates the <code>newTodo</code> signal based on the <code>onChange</code> event. </p>\n<p>You also need to create the <code>handleClick</code> function that passes the <code>newTodo</code> signal to the <code>addTodo</code> function prop and clears the input state.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleChange</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">setNewTodo</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleClick</span><span class=\"mtk1\">=()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">addTodo</span><span class=\"mtk1\">(</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">setNewTodo</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> }</span></span></code></pre>\n<p>Here's how the entire <code>&#x3C;AddTodo/></code> component looks like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;solid-js&#39;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">AddTodo</span><span class=\"mtk1\">({</span><span class=\"mtk12\">addTodo</span><span class=\"mtk1\">}){</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setNewTodo</span><span class=\"mtk1\">]=</span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleChange</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">setNewTodo</span><span class=\"mtk1\">(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleClick</span><span class=\"mtk1\">=()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">addTodo</span><span class=\"mtk1\">(</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">setNewTodo</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">onChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleChange</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk11\">newTodo</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Type a new todo...&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleClick</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Add Todo</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">AddTodo</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>You also need to render this inside the <code>&#x3C;App/></code> component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">styles</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./App.module.css&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;solid-js&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">AddTodo</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./AddTodo&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addTodo</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">deleteTodo</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">styles</span><span class=\"mtk1\">.</span><span class=\"mtk12\">App</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">styles</span><span class=\"mtk1\">.</span><span class=\"mtk12\">heading</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Todos</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">AddTodo</span><span class=\"mtk1\"> </span><span class=\"mtk12\">addTodo</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">addTodo</span><span class=\"mtk4\">}</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">App</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Once you do that, you should see an input field with a submit button rendered by the <code>&#x3C;AddTodo/></code> component on the screen:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 54.15384615384615%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABUElEQVQoz6WRzWrCQBSF5xmsDRQTTap113ZTSu3DKdn4eFmFJM1fFyKiqGiCGmPGY+5YRdIIlgY+7sz9OXMuYe12A2/vH+h0PvH88grtsYlK5e5MtXoPSZIgywoUrYFa7QENuQnlqY26WoemaVAUGaqqotVqgbmuB8d2YOdYliWgs+Pkd9sWOM4XPM+DF/h5dBH4IfzwG35+D4IAvn+MYQ7jnGO/3/+C8mUf1TKegWcER0aRHyPB1us1iqxWK6RpKl42DAPj8RhhGGI6nSKOY2w2G5TNESxJEhShAjmhtfv9PnRdR7fbRa/Xg2mawin1lM2WCpKD7XYrXJLbKIoE5I7qlKeemwRPjYvFAsvl8kcoEnlaeTgcYj6f5w8mpaLsmrvZbIbJZHKGnA4GA7iui9FoJHpuEiyufILyu91O/Mk/rXwpekkxd22OFQf/AwkeAP2xF5/Nus2WAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"AddTodo Component\"\n        title=\"AddTodo Component\"\n        src=\"/static/ea4ec890d45584376fe6c1a67d026846/e5715/add-todo-component.png\"\n        srcset=\"/static/ea4ec890d45584376fe6c1a67d026846/a6d36/add-todo-component.png 650w,\n/static/ea4ec890d45584376fe6c1a67d026846/e5715/add-todo-component.png 768w,\n/static/ea4ec890d45584376fe6c1a67d026846/23814/add-todo-component.png 2856w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"rendering-todos\" style=\"position:relative;\"><a href=\"#rendering-todos\" aria-label=\"rendering todos permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Rendering Todos</h3>\n<p>Now let's work on two simple components responsible for rendering the todos. First is the <code>&#x3C;Todos/></code> component. As you already know, this component takes in two props — a list of todos called the <code>todos</code> signal and the <code>deleteTodo</code> method. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">For</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;solid-js&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">TodoItem</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./TodoItem&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Todos</span><span class=\"mtk1\">({</span><span class=\"mtk12\">todos</span><span class=\"mtk1\">,</span><span class=\"mtk12\">deleteTodo</span><span class=\"mtk1\">}){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk11\">todos</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">For</span><span class=\"mtk1\"> </span><span class=\"mtk12\">each</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk11\">todos</span><span class=\"mtk1\">()</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk1\">(</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">,</span><span class=\"mtk12\">ind</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">           </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">For</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Todos</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>You use the <code>&#x3C;For/></code> component to loop through the list of todos. Now, you need to pass each todo item and the <code>deleteTodo</code> method further down to your <code>&#x3C;TodoItem/></code> component. This component is responsible for rendering each list item. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"24\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">TodoItem</span><span class=\"mtk1\">({</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">,</span><span class=\"mtk12\">deleteTodo</span><span class=\"mtk1\">}){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleDelete</span><span class=\"mtk1\">=()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">deleteTodo</span><span class=\"mtk1\">(</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onClick</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleDelete</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk4\">{</span><span class=\"mtk12\">todo</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">TodoItem</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>When you click on an item, you invoke the <code>deleteTodo</code> function and pass the clicked todo item as a parameter. </p>\n<p>Finally, render the <code>&#x3C;Todos/></code> component inside the root <code>&#x3C;App/></code> component.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"25\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">styles</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./App.module.css&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">createSignal</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;solid-js&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Todos</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./Todos&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">AddTodo</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./AddTodo&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">todos</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setTodos</span><span class=\"mtk1\">]=</span><span class=\"mtk11\">createSignal</span><span class=\"mtk1\">([])</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addTodo</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">deleteTodo</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">styles</span><span class=\"mtk1\">.</span><span class=\"mtk12\">App</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h1</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">styles</span><span class=\"mtk1\">.</span><span class=\"mtk12\">heading</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Todos</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h1</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">AddTodo</span><span class=\"mtk1\"> </span><span class=\"mtk12\">addTodo</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">addTodo</span><span class=\"mtk4\">}</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Todos</span><span class=\"mtk1\"> </span><span class=\"mtk12\">deleteTodo</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">deleteTodo</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">todos</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">todos</span><span class=\"mtk4\">}</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">App</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Great! Let's complete the todo app by writing the logic for adding and deleting a todo.</p>\n<h3 id=\"adding-and-deleting-todos\" style=\"position:relative;\"><a href=\"#adding-and-deleting-todos\" aria-label=\"adding and deleting todos permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding and Deleting Todos</h3>\n<p>To add a new todo, you only need to complete the logic inside the <code>addTodo</code> function in the <code>&#x3C;App/></code> component. This function already takes a <code>newTodo</code> parameter, the new todo item you need to add. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"26\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">addTodo</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">newTodo</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setTodos</span><span class=\"mtk1\">([</span><span class=\"mtk11\">newTodo</span><span class=\"mtk1\">(),...</span><span class=\"mtk11\">todos</span><span class=\"mtk1\">()]);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You'll add the <code>newTodo</code> in the <code>todos</code> signal that is an array using its setter function <code>setTodos</code>. Use JavaScript array destructuring here to ensure to keep the previous todos intact. Let's give this a whirl now:</p>\n<p><video controls width=\"600\" align=\"center\" src=\"/ee1e93cf316cf6b97e0ebabed82c67bf/add-todos-demo.mp4\"> </video> <br></p>\n<p>It looks like you're able to add todos now. Awesome! </p>\n<p>To delete the todo when they're clicked, populate your <code>deleteTodo</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"27\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">deleteTodo</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">newTodos</span><span class=\"mtk1\">=</span><span class=\"mtk12\">todos</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">newTodos</span><span class=\"mtk1\">=</span><span class=\"mtk11\">newTodos</span><span class=\"mtk1\">().</span><span class=\"mtk11\">filter</span><span class=\"mtk1\">(</span><span class=\"mtk12\">_todo</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">_todo</span><span class=\"mtk1\">!=</span><span class=\"mtk12\">todo</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">setTodos</span><span class=\"mtk1\">(</span><span class=\"mtk12\">newTodos</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span></code></pre>\n<p>First, make a copy of the current todos array. Then, filter through this copy to remove the todo you wish to delete. Finally, update your original <code>todos</code> signal with this copy using the <code>setTodos</code> setter. Let's test it out now:</p>\n<p><video controls width=\"600\" align=\"center\" src=\"/ba95b63a0a55ccc16cee9ce827c28811/delete-todos-demo.mov\"> </video> <br></p>\n<p>You can delete todos as well; fantastic! </p>\n<h3 id=\"styling-the-app\" style=\"position:relative;\"><a href=\"#styling-the-app\" aria-label=\"styling the app permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Styling the App</h3>\n<p>Functionally your app is complete, but it surely misses some aesthetics. Let's add some simple yet neat-looking styles. You can directly update the styles in our <code>App.module.css</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"28\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">*</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.App</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">text-align</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">height</span><span class=\"mtk1\">: </span><span class=\"mtk7\">100vh</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#F8F8F8</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">: </span><span class=\"mtk7\">100px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">display</span><span class=\"mtk1\">:</span><span class=\"mtk8\">flex</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">flex-direction</span><span class=\"mtk1\">: </span><span class=\"mtk8\">column</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">align-items</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.heading</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-size</span><span class=\"mtk1\">: </span><span class=\"mtk7\">96px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin-bottom</span><span class=\"mtk1\">: </span><span class=\"mtk7\">20px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">input</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">border-radius</span><span class=\"mtk1\">: </span><span class=\"mtk7\">12px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">outline</span><span class=\"mtk1\">: </span><span class=\"mtk8\">none</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">border</span><span class=\"mtk1\">: </span><span class=\"mtk8\">none</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">: </span><span class=\"mtk7\">5px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">20px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin-right</span><span class=\"mtk1\">: </span><span class=\"mtk7\">20px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">height</span><span class=\"mtk1\">: </span><span class=\"mtk7\">60px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">400px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-size</span><span class=\"mtk1\">: </span><span class=\"mtk7\">24px</span><span class=\"mtk1\">; </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">box-shadow</span><span class=\"mtk1\">: </span><span class=\"mtk11\">rgba</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0.05</span><span class=\"mtk1\">) </span><span class=\"mtk7\">0px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">button</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">height</span><span class=\"mtk1\">: </span><span class=\"mtk7\">65px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">150px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">border</span><span class=\"mtk1\">: </span><span class=\"mtk8\">none</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">outline</span><span class=\"mtk1\">: </span><span class=\"mtk8\">none</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">border-radius</span><span class=\"mtk1\">: </span><span class=\"mtk7\">12px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-size</span><span class=\"mtk1\">: </span><span class=\"mtk7\">24px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">: </span><span class=\"mtk7\">5px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">15px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">box-shadow</span><span class=\"mtk1\">: </span><span class=\"mtk11\">rgba</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0.05</span><span class=\"mtk1\">) </span><span class=\"mtk7\">0px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">cursor</span><span class=\"mtk1\">: </span><span class=\"mtk8\">pointer</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-weight</span><span class=\"mtk1\">: </span><span class=\"mtk7\">600</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">:</span><span class=\"mtk8\">#2e3136</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">color</span><span class=\"mtk1\">:</span><span class=\"mtk8\">#fff</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">p</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">height</span><span class=\"mtk1\">: </span><span class=\"mtk7\">60px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">: </span><span class=\"mtk8\">white</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">600px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">text-align</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">display</span><span class=\"mtk1\">: </span><span class=\"mtk8\">flex</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">align-items</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">justify-content</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">border-radius</span><span class=\"mtk1\">: </span><span class=\"mtk7\">12px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-size</span><span class=\"mtk1\">: </span><span class=\"mtk7\">24px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin</span><span class=\"mtk1\">: </span><span class=\"mtk7\">20px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">box-shadow</span><span class=\"mtk1\">: </span><span class=\"mtk11\">rgba</span><span class=\"mtk1\">(</span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0</span><span class=\"mtk1\">, </span><span class=\"mtk7\">0.05</span><span class=\"mtk1\">) </span><span class=\"mtk7\">0px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2px</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">p:hover</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">: </span><span class=\"mtk11\">rgb</span><span class=\"mtk1\">(</span><span class=\"mtk7\">232</span><span class=\"mtk1\">, </span><span class=\"mtk7\">169</span><span class=\"mtk1\">, </span><span class=\"mtk7\">146</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">color</span><span class=\"mtk1\">:</span><span class=\"mtk8\">#fff</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">cursor</span><span class=\"mtk1\">: </span><span class=\"mtk8\">pointer</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.header</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#282c34</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">min-height</span><span class=\"mtk1\">: </span><span class=\"mtk7\">100vh</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">display</span><span class=\"mtk1\">: </span><span class=\"mtk8\">flex</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">flex-direction</span><span class=\"mtk1\">: </span><span class=\"mtk8\">column</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">align-items</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">justify-content</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-size</span><span class=\"mtk1\">: </span><span class=\"mtk11\">calc</span><span class=\"mtk1\">(</span><span class=\"mtk7\">10px</span><span class=\"mtk1\"> + </span><span class=\"mtk7\">2vmin</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">white</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>And that should give us a much better-looking todo app now:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 54.61538461538461%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAABlElEQVQoz4WRy07CQBiF+wTCSqhIBNyqcaELfCA3bnwMVy58D3YGTAwkmphAiAu5lNLahoWmGGLLxba0pRxn/ogBbHCSr+fM5T+di7CfS+H45BT5/BkODo+QzeYQi8WxFYuREvE4EokEkqkdJJPb2BX3IGazSKVTSKfTEEWRNJPJQFAUFbIso8OQJIngfVnuQup0SN/e3mEYBox+H6qqQFN1aL0edF0nNE379UIYhpjP55HwVqlUUCgUUCwWUa1WsWh8fjabETxjoYLjOIhiPBrBZaoqCu5KJZTLZdRYIN9Ns9GEaZqYTqd/6gQ+6LouTbqMKfeeD2tiY2Q7WG9X1zc4v7hEqy3RLnnIcsZqIFffhz0wYNXuYdXL+KxXYD4/ENx/PJVgPN7CNge0dqU2MtDz4AxNjNUGJloL49cWzO4Lwf2XLsHW23AnI1q7MXDhPT9AyC+e4bPP2HGJgPXDH/i1rNetBC7/yWM6CwL2cgF5iz3A0LLgsx3ROGP9ZCuBUXismMO9bdvE+ngUwiJ9E8vH+o9vF9kR7clrkQwAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Updated-app\"\n        title=\"Updated-app\"\n        src=\"/static/e24ed975dd640e252975fc4230a62301/e5715/updated-app.png\"\n        srcset=\"/static/e24ed975dd640e252975fc4230a62301/a6d36/updated-app.png 650w,\n/static/e24ed975dd640e252975fc4230a62301/e5715/updated-app.png 768w,\n/static/e24ed975dd640e252975fc4230a62301/9f75f/updated-app.png 2858w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"solidjs-vs-react\" style=\"position:relative;\"><a href=\"#solidjs-vs-react\" aria-label=\"solidjs vs react permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>SolidJS vs. React</h2>\n<p>If you're coming from a React background, building the todo app must feel like a piece of cake to you! This is because, in terms of syntax and architecture, Solid is strikingly similar to React. It uses the same structure of using functional components, returning JSX, fragments, one-way data binding, etc. </p>\n<p>Using effects, refs and events are also much similar to React in Solid. So it's safe to say that Solid provides almost the same if not slightly different syntactic sugar as React. Then why do we need another React-like framework for building web applications?</p>\n<p>Solid differs from React in terms of performance, developer experience, rendering algorithm, and reactivity. Let's skim through the key differences:</p>\n<h3 id=\"performance\" style=\"position:relative;\"><a href=\"#performance\" aria-label=\"performance permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Performance</h3>\n<p>At the beginning of this tutorial, we discussed how Solid doesn't use a virtual DOM. Instead, it uses a compiled DOM. This gives it a significant edge over React and any other framework in terms of run-time performance. It generates a blazingly fast production bundle that is aimed to provide a more rich user experience for your users. </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 75.53846153846155%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAACD0lEQVQ4y5WUyW4TQRCG8xygeDz75tm3MFvbDihRhMIlXJDCIUJISOFAIpQLIEQQPAZvwSnv9lPV1lgZLwcOv6q6xv1NbZ4DTdPAUlUVhmHAdV1Mp1M4loE0cJEEjhT7lqHK3w13dulgcCTEcVCUJTRVQdyd4cXVDxy//YIl6eTdPfLnF5gcPoWm63vBW8A8L+B7DsLmVILmb+4gSOyL80sYOmX5PxnmeY4oihH4DtqjDE2VkjLURQLR1kjTDJPJZN2mvUB+yMCSSk6SBFEco+t7tG2Htuuk7To+tzBNcwR77I+Atm3LDGezGcIwJEAnAYOapoEQAlVVyYoURVnDBrsFzLJMWobyZYZuiuP8nDdC3xjQFjBNU/i+LzPs+1WJm0COMXSxWEggZzswdpYcU/+4j3yJofs0ZMr7u6dkC0kcYea7NGUPVZmjLEhlQXZDFCvo5W3bIAiCdZYjoG7asIMclp/ATyqkRwKmF1GvPLge9czzR/IoZjvujh5SH5TDJwj7V7j49YDXP/+u9PsB55//4P2HG3y8/Y7rm69kv0mx/+nuHpdX16PBPFpsBY4fohBnyPtTacvFS1TiBM/qBk0rUDcd6rYn21Ns5edFNc5wOHAPuBfHyyUW8znmPBD6ZxRZAsuyaOlt2WOHBseyKcbnzSWXGarD18a0ZJbuLJLSDRMTWl5+2X7xF2h1n/UPj2zT8Hr9WgoAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"SolidJS Performance\"\n        title=\"SolidJS Performance\"\n        src=\"/static/9fa1169a9f82c81354ea851118fac952/e5715/solidjs-performance.png\"\n        srcset=\"/static/9fa1169a9f82c81354ea851118fac952/a6d36/solidjs-performance.png 650w,\n/static/9fa1169a9f82c81354ea851118fac952/e5715/solidjs-performance.png 768w,\n/static/9fa1169a9f82c81354ea851118fac952/5440e/solidjs-performance.png 1419w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span> </p>\n<p>If you wish to dive deeper into these stats and take a closer look at performance benchmarks, <a href=\"https://krausest.github.io/js-framework-benchmark/current.html\">here's a comparison guide you can refer to</a>. </p>\n<h3 id=\"solid-is-truly-reactive\" style=\"position:relative;\"><a href=\"#solid-is-truly-reactive\" aria-label=\"solid is truly reactive permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Solid is Truly Reactive</h3>\n<p>Reactivity lies at the heart of SolidJS, which is why you'll never find any unnecessary renders of your Solid components. Only the part of a template that needs to update will re-render.</p>\n<p>With React, however, change in a state leads to re-rendering the entire component. There are ways to combat this, but it needs additional efforts to learn and incorporate these concepts into your applications.</p>\n<h3 id=\"community-support-documentation-and-resources\" style=\"position:relative;\"><a href=\"#community-support-documentation-and-resources\" aria-label=\"community support documentation and resources permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Community Support, Documentation, and Resources</h3>\n<p>Even though Solid has excellent and extensive documentation, the React community is much larger since it has been around for longer. That can be a deal-breaker if you want to build scalable web applications quickly. Even third-party libraries are short in number for Solid in comparison to React.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>Solid has an exciting future and is worth a side-project or an MVP for your startup. If you wish to explore Solid in-depth, you can check out an official tutorial by the Solid team <a href=\"https://www.solidjs.com/tutorial/introduction_basics\">here</a> that walks you through every concept in Solid. You can also <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/SolidJs/todo-app-solidjs\">explore the entire code for the demo in this tutorial here</a>. Until next time!</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n</style>","frontmatter":{"title":"Introduction to SolidJS","author":{"id":"Siddhant Varma","github":"FuzzySid","avatar":null},"date":"June 28, 2022","updated_date":null,"tags":["SolidJS","React","Frontend"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/06f459d4c67e0e9c2b5f26d0b5c1a042/ee604/introduction-to-solidjs.png","srcSet":"/static/06f459d4c67e0e9c2b5f26d0b5c1a042/69585/introduction-to-solidjs.png 200w,\n/static/06f459d4c67e0e9c2b5f26d0b5c1a042/497c6/introduction-to-solidjs.png 400w,\n/static/06f459d4c67e0e9c2b5f26d0b5c1a042/ee604/introduction-to-solidjs.png 800w,\n/static/06f459d4c67e0e9c2b5f26d0b5c1a042/f3583/introduction-to-solidjs.png 1200w,\n/static/06f459d4c67e0e9c2b5f26d0b5c1a042/5707d/introduction-to-solidjs.png 1600w,\n/static/06f459d4c67e0e9c2b5f26d0b5c1a042/9ddc6/introduction-to-solidjs.png 2240w","sizes":"(max-width: 800px) 100vw, 800px"}}}},"fields":{"authorId":"Siddhant Varma","slug":"/engineering/guest-post/introduction-to-solidjs/"}}},{"node":{"id":"02c046b5-a3c5-5202-88e5-595429732aeb","html":"<p>Web design and CSS have come a long way. And today, modern websites have everything you could wish for alongside stunning designs. Then why should your website's login and signup forms look boring?</p>\n<p>The web ecosystem has tons of reliable third-party libraries and frameworks to help you build intuitive designs even if you're not a design wizard. Amidst the plethora of libraries comes a utility first CSS framework called <a href=\"https://tailwindcss.com/\">Tailwind CSS</a>.</p>\n<p>So in this post, you'll learn:</p>\n<ul>\n<li>what Tailwind CSS is;</li>\n<li>why it's awesome; and,</li>\n<li>how you can use it in a React app.</li>\n</ul>\n<p>I'll then walk you through step by step how to use it to create a modern login and signup form with routing in React.</p>\n<p>Finally, you'll see how to make these forms functional using <a href=\"https://www.loginradius.com/resource/whitepaper/loginradius-ciam-developers/\">LoginRadius Authentication APIs</a> docs/references/api/authentication).</p>\n<h2 id=\"what-is-tailwind-css\" style=\"position:relative;\"><a href=\"#what-is-tailwind-css\" aria-label=\"what is tailwind css permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Tailwind CSS?</h2>\n<p>If you've heard of Materialize and Bootstrap, Tailwind CSS is much similar in what it offers. It's a CSS framework that helps developers build layouts, components, themes, and whatnot, without writing all the CSS themselves.</p>\n<p>However, unlike Bootstrap and Materialize, it doesn't give you built-in components out of the box. Instead, it gives you a wide range of fully customizable utility classes that you can use to style your pages.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACn0lEQVQoz22SW08TURSF+wNUFEpbC7RQRLFcCgaIMSi3couAQklsmemEUlpKKZCoie++++SrD8aQYOIf8DeYIMYgd1IKbaEzreCjT59npqgx8WHN3jlnztp77bVNsbo80do8jys/8tC5wpB9hRHHe8Zcq0yY14g4z1ls0lAseSTLEcMVqwza34m4gtf6lvGyT8iWLIq1IKBh0j9SWY42xwzDQyMM9I4z7PXR2+Olp+wNTz0/eR0tEK44x2dep7fzEf09o3i7Rum+P0h/6Qek8ixTlpQomMEUtKoo5XkCpUdMlGzju7yH79IuvpIdZFuWYLnGtF10aNNErjJZss/EFf1+l8mruwTMSdFhmkB5SiApOhQPZMcJ/o5DZgZSLPRliLcKkjsnBCtFMYsgsqhF4gqVBXeBxcYCCfcZMXcK2bnOlPWbID0yZJuCNhV/exJf6wGBvh2U8S3kkS0CTYdIpaIzXYFA0FLMZ12nxOpzhGuP8VeuEW9OkWhOo1RtIFu3BeH1HIo9x9ItYc7tU2Zb00QbT0g05IjeKHb2mzDsVJmrK54rrk1iLZu8eHDKQlOaRU8GybauE6pM1QuSrhSRxiyxWpVoS4b5BkFe/ZdQKtMIVanEbqpE6tJMudZ41pliqU3v8IRQzbaQvoHpyd0D/P3CgLFt5OFdgv17KO0pZp0aM46iXH2OEZeQW6MaRcICiiOJ5PzKvGefZfF/wPrFMMckVWeZrs6R6D5mzpskdu+YuDvHcusp87dzxm7pcufF3JZahDwxirjAYrNKwpMl4t4h7P5M0L5PyJ4vuqzLkq8JlOoxj2zWDIl6DBrzU43cwMW5bFaNXH8bcmRZ8uTF3AsXe6jDpv5x9B8Y7mr/uSuuU6hS43nHd15JP3g5csYvp6AG8t8jLJkAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"TailwindCSS vs. Bootstrap Comparison\"\n        title=\"TailwindCSS vs. Bootstrap Comparison\"\n        src=\"/static/53e88d5c504fe9fe3dc546ca8b0da336/e5715/tailwind-css-vs-bootstrap-comparison.png\"\n        srcset=\"/static/53e88d5c504fe9fe3dc546ca8b0da336/a6d36/tailwind-css-vs-bootstrap-comparison.png 650w,\n/static/53e88d5c504fe9fe3dc546ca8b0da336/e5715/tailwind-css-vs-bootstrap-comparison.png 768w,\n/static/53e88d5c504fe9fe3dc546ca8b0da336/7b67d/tailwind-css-vs-bootstrap-comparison.png 2240w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"why-tailwind-css-better-or-worse-than-the-others\" style=\"position:relative;\"><a href=\"#why-tailwind-css-better-or-worse-than-the-others\" aria-label=\"why tailwind css better or worse than the others permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why Tailwind CSS Better or Worse Than the Others?</h2>\n<p>The community loves Tailwind. For most developers, the key takeaway is that it gives you more freedom on how you want your components or elements to look. So in many cases, when developers use component-based CSS frameworks like Bootstrap, they have a hard time changing the way they want their website to look.</p>\n<p>Being utility first, it's the most customization-friendly CSS framework! </p>\n<p>Also, it's pretty easy to integrate with modern frontend frameworks like React, NextJS, VueJS, Angular, Svelte, etc. I'll also explore that shortly when we add Tailwind to our React app. </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACLklEQVQoz2VTXWvTYBjtrbBN6ZI0W+0+pAVBhjLZwIvB0JuJm7DVfWRNmnSdWMQyZYyNguA2EUFEFHYr+C9kKqh3gleKovgxOl3bfEfw/vgkb5NavTh5wvs+73nPOU8SK2UsXElbUHtMKIKJfMKgamDpqIHtSRd3sx5uX3SD9zvTHu5JHpZS1MvryIsWFvkqFoV9qAmbzpqI+Q9GElYLcrdN1cb6GCPaPM9QGXdw85wDLUlEHFXOgCw0MM9/QU74STgICZtkvAlNrKGY+UG1CuVIHbMdBuY6dIKBhS5676ReroZS/1fMZhyoJEQW6pD4vQCRQh9S3MXOyiu8XtvC7sPneDD1FnOHXRSSOqkyoPXqmOd+YWfkGTYvPMbEqTqpDAVZAdoIZbK7evYdtsee4tbMZ5RP70HmKAI6JHVSDFRzhMrQJ5SH91FM0TlSqDRz9xGLFnxSWtBEF2rfb1LlYHmASHgriOD6xEdcPn4AOW5B6XVRSjso9psBSSs2GgojMttvogmyRgOXDpl4VNDxpLGL7I0XyHe5NF2dlJIjvp2MTZkGoVBGikibXGifbaoiWY3r2BjxUKq8waTyEmq3HUXk94RWI8tKDwV95huyUx8gD9YQXBA1M+Jin4mrgy7Kaa/5vbbIwou1JENMGqpiZvo9Fka/B0r/tp6PKhGLRnO9ZS/cWx4wsXLSxrUTFrOcO1aDnGqQZQtRpon/A/+XyK8FUrU6auN+zsMW/QR/AKmtFC5/kCD5AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"TailwindCSS Pros\"\n        title=\"TailwindCSS Pros\"\n        src=\"/static/4409d71c09a348492578a1acd7833fba/e5715/tailwind-css-pros.png\"\n        srcset=\"/static/4409d71c09a348492578a1acd7833fba/a6d36/tailwind-css-pros.png 650w,\n/static/4409d71c09a348492578a1acd7833fba/e5715/tailwind-css-pros.png 768w,\n/static/4409d71c09a348492578a1acd7833fba/7b67d/tailwind-css-pros.png 2240w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>On the downside, Tailwind might make your HTML bloated with loads of CSS classes for small and specific rules. However, you can control it with a framework like React by building smaller reusable components and using JSX bindings for long class names for more maintainability and readability. </p>\n<p>In fact, we'll take this optimal approach in building our Login form, so you'll understand some best practices you can use to avoid bloated HTML templates in your React app. </p>\n<h2 id=\"what-youll-build-today\" style=\"position:relative;\"><a href=\"#what-youll-build-today\" aria-label=\"what youll build today permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What You'll Build Today?</h2>\n<p>We'll create a simple yet modern looking login and signup form that looks like this:</p>\n<p><video controls width=\"700\" align=\"center\" src=\"/46886cf38c3148a337f29fc7cbf22acb/demo.mov\"> </video></p>\n<p>It will be interactive using React state, can route to different pages, and we'll also, in the end, talk about how we can make it functional from a backend standpoint. </p>\n<p>Sounds good? Let's start by understanding how we can add TailwindCSS to our React app. </p>\n<h2 id=\"project-setup\" style=\"position:relative;\"><a href=\"#project-setup\" aria-label=\"project setup permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Project Setup</h2>\n<p>Inside a directory of your choice, create a new React project by running:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npx create-react-app react-tailwind-app</span></code></pre>\n<p>Next, move inside the project and install react-router-dom by running:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">cd create-react-app react-tailwind-app && npm i react-router-dom</span></code></pre>\n<h3 id=\"install-tailwind-css\" style=\"position:relative;\"><a href=\"#install-tailwind-css\" aria-label=\"install tailwind css permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Install Tailwind CSS</h3>\n<p>Now, <a href=\"https://tailwindcss.com/docs/guides/create-react-app\">add Tailwind to your React project by following the steps given here</a>. </p>\n<p>First, install Tailwind CSS and its related dependencies by running the following command in the root directory:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm install -D tailwindcss postcss autoprefixer</span></code></pre>\n<p>Next, generate some configurational files by running the following command in the root directory:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npx tailwindcss init -p</span></code></pre>\n<p>That should generate a <code>tailwind.config.js</code> file and <code>postcss.config.js</code> file for you as shown:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 496px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 362.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABJCAYAAAA9mQYkAAAACXBIWXMAABYlAAAWJQFJUiTwAAAHGElEQVRYw+1YSY8k1REuDpYsJGQJW6CBXqoq932tLWvrmuruqa7pZXqWbmbMaHxqIWEOIMtsEuCbhQBLRgjZV+4IBIN/hH+AjTTD8ks+IiIrs6tqesQMXPsQeplZWd/7IuKLePle5dq1a2i1Wtjc3EQYhlBVDaZpwfN8OI4L3w/EdN2Q3zRNX7DimWGYMlaOjo5w+/ZtnJycIE1T1OsKms18gsFgiOn0Mi5dmsC2nYcC8mQ8uQDevHkTd+7cATMNgkBeUBQVtVpdRr7nSdiKex7ZCsDiGY+Vvb09cslHFEVizGQ83sStW3/E9es3iOkW9vcPcOPGDRwdHePFF29jZ2eK4+NjXL68SxMrC4wrDNJoNNDpdASQHzJ9vg4opjZd5/cxeRDK6LqemGXZD4RBAIfDocQsjmOhziw910fWzjDoDRBHCbKsi35/gI2NDbTbndJNcVsjt5Xc9UqSJOj1epJpBueHnDHTsWFFLuxmCCf0H0jGfFLkP44FTdcZMCa5UPziRNzhHx3LIaAY9mSA4GADVpsmqlPQ5wDmXZVMhwEBGjOGnTZaoYMozLNsEaDn6GhH69BVRdzh2ed1l5smpqo6Aofe1VVUYgK5uH+E/snf4DV70BSFhE3gnopxZwWWWkO9RuyqM+ASVFsA9O0ZYCNwER+eIPjgv7CGB9Cra1AdH2pnDKPbgD/tw+kl8C9lMHxHXM9BFxmbFCLNmLkckTy8KJVRXqCk6ARqRiSNXpPiQ9fNCLptlSxPQXOGumvnSeHMcoYzimNI14qik2xUDIbruNhaweHoWUz7FxCRS/Va4eZi/NKwil66Qi7PZLO7uyvVUcqGfohdDV5gIIk1UgElyjWgWaa4dZqYHNAwSBn8OwubG8L29rY0BnZZoRccemHirlJMW/D2RrDHGbxJj+LYhdNvnMaRQdUclEMiMeTq4FrmUUpPpZdNKqm4DTN04W40YSU+rDQQW2Q4lxRK7kzYCbrdLkajkYCqXE6WCyUZwG6F8CfEatiEM2jAHbXkT2cC0qTCkBvDlStXMJlMZjGkH00V3dYqTGIkDKn8rFa0ALA8siJKhswuyzIBVKRSKBlpFQbN6hI7O4vFNNM8s8lyHM3Qy0uP3eTGGkWhANapUnw7xuX2LVhZBG87g021zO5ajTCv6blaLkaJbwE4Ho+lLRWy4ZbeiTKZVVymlzm7DMh/YqbLbnMVicsMyF17Z2cnd1mErVHve47cTBDsD+GRXDg54eEIwd4A4ZUNMWbPcWbW7EUpG+7W7Xa7TIpuUPcIVBieIwlhpmbsy8hMdOqVzFKf9UDxip9p+nwMo5KhZSnY6K+Jm8xMbIeEPe0h2B2IjBRaS+ZjyROXDKfTqciG12XJGLV/VbdEKnYnptgFEj9pDktZLtflQtgMyCva4eFhDkj1qdsBuetKjJiZO27DvdiGQR1FWa1Bpf6orNfLElwQNgNytzldU3R0WuuIMwv2qCNZZjCnl8LuJvC2OnLtbXYkEQVoUZaVooYL4x99X4GbUEKylNwOBZTBpD9SGNi4FPm+6I+lbLhSuNtsbW3lDDVmWEPSc+BsdeGRu5wMcXtmrEVlrbbgcpkUBmQNcmIKl31fpaXTgtmIJDZ5YkKRjtQ0C3tp0WKJlUlpNpvy9cDlx7IZ9lYRd3OGvJawy04/lViyhFjsPM7X9gJDBi37IbvgxcSM4jRsCDuuY64aDjxXBkukEHLJ0J+TDYPKYsWA9FBpjGC2msQiEzAutyK7fK/QkiqymRd2keWCYQHILrcaVVoFDVidJO+FXH5J3rGZKWdcXNTPEPYDgJSUZqMGv+nIOpKLuiXlJpokhhw/6d5zy8FDGXKl1Orkdl0Tt8Q9tppyej27n29fRZ88A1A/XXt1/aFfXcu1XH4fngV4Zps/4/lZ7z0W4KPYOeA54DngOeA54DngOeCvA1z4+vrVgMU39uzcRls6k3lswHyvdxGbfdpJBV65u/zFgGkSY/fwOry/fAa7P4Ver+Vb/6VTpEe1Ssrf2Fkfq3/6kL5QJyXg8ouP5TIfXqSugTjwYZj09U8f46aMp8YHbI9icirC+7ztyY4khc8K+4Mhjo9foOc7uE7btk3aw/CJp+yVf44hbyn4zOHgYF+kw2eHadqg/XKftr2ZnBvyeaHJR4DmqcmR4NIztkpCe5N8n0J7EdejvbKFJG3ikCa5ShvKq1ev4WB/H2vrNTkeLUxV8nPZKl2vV+syslV++8pXWHvzG6yTKW//BzUaq298jSdf/hxPvfIF/vDql/jNS5+j9tY3WPnr17hA9hzZk3/+Er9/7Susv3EX6tv0nzfvYuX1u6hU3vkfLnx0H89+cA/Opz/A+9ePUD7+HpV3v8Xv/n4Pz3x4H5X3vkX1n9/jeXrv+X98J+8/8d7/8fT79+Td6N8/ok6j/skP+Anhob5P4VXOpgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"tailwind config files\"\n        title=\"tailwind config files\"\n        src=\"/static/9ced8f7783ffd5b9ebd9abab98363db4/bb630/tailwind-config-files.png\"\n        srcset=\"/static/9ced8f7783ffd5b9ebd9abab98363db4/bb630/tailwind-config-files.png 496w\"\n        sizes=\"(max-width: 496px) 100vw, 496px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Awesome!</p>\n<h3 id=\"configuring-tailwind-css\" style=\"position:relative;\"><a href=\"#configuring-tailwind-css\" aria-label=\"configuring tailwind css permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configuring Tailwind CSS</h3>\n<p>Now, go ahead and update the <code>tailwind.config.js</code> file to support templates for your React component files as shown:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">module</span><span class=\"mtk1\">.</span><span class=\"mtk10\">exports</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">content:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;./src/**/*.{js,jsx,ts,tsx}&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">theme:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">extend:</span><span class=\"mtk1\"> {},</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">plugins:</span><span class=\"mtk1\"> [],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Almost there! We'll now add some necessary Tailwind directives to your <code>index.css</code> file present in the root directory:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">@tailwind</span><span class=\"mtk1\"> base;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">@tailwind</span><span class=\"mtk1\"> components;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">@tailwind</span><span class=\"mtk1\"> utilities;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>Each of the above directives represents a layer of Tailwind's utility classes that you can use in your project. Their declaration allows using these utility classes anywhere in your project. </p>\n<p>Finally, we'll kickstart your React project by spinning a local development server:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm start</span></code></pre>\n<p>You're now ready to start using Tailwind CSS to create some awesome-looking UI for your React app!</p>\n<h2 id=\"frontend-architecture-and-boilerplate\" style=\"position:relative;\"><a href=\"#frontend-architecture-and-boilerplate\" aria-label=\"frontend architecture and boilerplate permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Frontend Architecture and Boilerplate</h2>\n<p>We'll break down the entire page into small, reusable components to ensure that your code is readable and maintainable and doesn't have bloated HTML templates. </p>\n<h3 id=\"component-architecture\" style=\"position:relative;\"><a href=\"#component-architecture\" aria-label=\"component architecture permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Component Architecture</h3>\n<p>For instance, you can have a <code>&#x3C;Header/></code> component that takes care of the page's heading and displays a link to navigate to another page. </p>\n<p>Similarly, you can have a reusable custom <code>&#x3C;Input/></code> component that can be used inside the form. All in all, here's what your frontend architecture would look like:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACPklEQVQoz4VTTWsTURTNT9BO3rxMMqlpqSCk4qLUhaYRbSk1laJtqGmaZCZJY0REFDeCUhB3ChVKoaBbV+JG8GPnQhFBqKKL4kLRYDWdzMR82KYu1OOdN0laRXFxuHPfO++8e89948rvtJDvsaApJpJyCZrHRGybgdnBNSxmgAXtO27kf2I++QMLM3VcOVIRPBspbiHOCojLH6HxMuUmXClub67+Bk2uYUx6grDnGobVRQyp8zjEbiIuFZFgm3xbwI4x9hbT8grhky1oIcMbhA2BlGwh51/HiHwHfTsSCPWcwsCuk+jnZ6Grn5FR1pvchqjQFk2Q6BR7T/gAl11uxP0AEXafcA/H+Ruc6P4C3VNFmn2D7m4QNui7gWxnGVHfU4xIdzHKHlKrhbaoEy24xjteIqhGsK83it7AIIY6biMtN+jWIpJ8tYmiyBNSGX3uc+gPHsZu/yjGtj8j76qiwqRsCF9djg9m02hTtGz76qw70T6UVirIdVuCk+k0aN1ALlBGVq1Bl+vQec0ZSutQC0leal/QyiekV5jyLiOtEsddQz7QEF5qSgmT3hc4Kj3HBFsiruEI/onN6ixMsxWE/bM46J2jli0My7cQUi/igHIVMfc7hJTLCHddwH7lEg2l4LT8N2wVHBCC18WTifIljKuPcEx5LLzTeZ3sqCPro9a95v8ETWF2lL3GJFsW7ev0RnW2RvFr0xIDM10lnNlj4nTQ+rfgVlGdhqLxCg3MEWiD9tM+E+f3ljGXqIq/6Bco8Pyp5un9kAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Login Page Architecture Hierarchy\"\n        title=\"Login Page Architecture Hierarchy\"\n        src=\"/static/04ff8abefb4aa8da5c5d0ab928cddd6b/e5715/login-page-architecture-hierarchy.png\"\n        srcset=\"/static/04ff8abefb4aa8da5c5d0ab928cddd6b/a6d36/login-page-architecture-hierarchy.png 650w,\n/static/04ff8abefb4aa8da5c5d0ab928cddd6b/e5715/login-page-architecture-hierarchy.png 768w,\n/static/04ff8abefb4aa8da5c5d0ab928cddd6b/7b67d/login-page-architecture-hierarchy.png 2240w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h3 id=\"directory-structure\" style=\"position:relative;\"><a href=\"#directory-structure\" aria-label=\"directory structure permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Directory Structure</h3>\n<p>So first, let's go ahead and create these files and folders. You'll develop corresponding files for the Signup page as well. Create the following files and folders inside your root directory:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"shell\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">.</span>\n<span class=\"grvsc-line\">├── components/</span>\n<span class=\"grvsc-line\">│   ├── FormAction.js</span>\n<span class=\"grvsc-line\">│   ├── FormExtra.js</span>\n<span class=\"grvsc-line\">│   ├── Header.js</span>\n<span class=\"grvsc-line\">│   ├── Input.js</span>\n<span class=\"grvsc-line\">│   ├── Login.js</span>\n<span class=\"grvsc-line\">│   └── Signup.js</span>\n<span class=\"grvsc-line\">├── constants/</span>\n<span class=\"grvsc-line\">│   └── formFields.js</span>\n<span class=\"grvsc-line\">└── pages/</span>\n<span class=\"grvsc-line\">    ├── Login.js</span>\n<span class=\"grvsc-line\">    └── Signup.js</span></code></pre>\n<p>For perspective, here's how we'll use those components to build your entire Login Page:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACh0lEQVQoz2WSS0hUURzGZ5c9JLKZO2oWIrZq4SJRCNpZgUaRmo/xNWP5iB7Sw9QgIhHbZLRwZYtKLF+gBJJSi1BBC11oiTUp5uhM3nnpjJPzdPx15zrJkBf+fOecy/873/c/n6L6uI2qZBvaOCslgoUSlYWuxj+M93kZfuthuNPNSKeH0R6vvP63nx6C5swg+QdsFMcaKVPbKVXbUJSqrURWsdLC/KSf/7+AwxWxCzI7N0Ft7iAZ0e/IE2YpFn5TJBhRyKrUIqWxZhmLVWZmhn1ym9+3hclkxri0wqJ+GaNRxGZz4HH7qK9r4EyajhRlOXmq72iERQpUCyhCUnUqD2VKN1qlhConMyOebR1BEEULS8tGTKKIYcHEqt0BW9s626qgMMpPRVyAcsEn2V5Dkav8SmrsTU4n1pJ+rJqMQ138+rLd4Fp34/OG7YdJQrglXTQw2I/mVBsXD06RldBFVnwvhYKksEA1T+bRN1xK7uVCUgdnY/r42LPAhneVTfxSf8j+ZmiK4dqUeTt72sk++Zxz0R9IT6wkNb6aHOV0pOUNtIe9ZMX103D7CeOfxzBMupkbceHUw/oc2L+BYTSIccqDx7fOE42B/P2rXI31oRO88kvvepQSpZ2f49vu9EN+Bp7padZ10XKtj6ayTtofjGMYC8j/W69skLtXpCxO6hNEOXZybEKLndhIOZyb8O0M7YdhgvrH12lqqaNOwvefuneG2VrplAjN6I5Y0YZrVw5D5E81Dl7dd9F2y8nrWi+9j6D7ITJ21Ad4UePk5T0Xd1LtaGIsVCRZqUmxc+NERLBl62Gl+dEW+ebL+yyypew9KzuVEyWGz80ymS7Byt00Oy1FDhrPr/EX7AF5kqCl0RYAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Login Page Architecture\"\n        title=\"Login Page Architecture\"\n        src=\"/static/4abf614464356d75a4c1bad1e319e7a5/e5715/login-page-architecture.png\"\n        srcset=\"/static/4abf614464356d75a4c1bad1e319e7a5/a6d36/login-page-architecture.png 650w,\n/static/4abf614464356d75a4c1bad1e319e7a5/e5715/login-page-architecture.png 768w,\n/static/4abf614464356d75a4c1bad1e319e7a5/7b67d/login-page-architecture.png 2240w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Makes sense? Great! </p>\n<h3 id=\"components-boilerplate-code\" style=\"position:relative;\"><a href=\"#components-boilerplate-code\" aria-label=\"components boilerplate code permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Components Boilerplate Code</h3>\n<p>While we're at it, let's also create some component boilerplate for all these files except the <code>/src/constants/formFields.js</code>.</p>\n<p>For the Login.js files (<code>/src/pages/Login.js</code>), you can put down the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LoginPage</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Similarly, you can create such boilerplates for the rest of the files. </p>\n<h3 id=\"form-fields-constants\" style=\"position:relative;\"><a href=\"#form-fields-constants\" aria-label=\"form fields constants permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Form Fields Constants</h3>\n<p>You've created a <code>formFields.js</code> file earlier. This file will hold all the input fields related constants like placeholder, value, name, field type, etc. Inside this file, add the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">=[</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelText:</span><span class=\"mtk8\">&quot;Email address&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelFor:</span><span class=\"mtk8\">&quot;email-address&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk8\">&quot;email-address&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">autoComplete:</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">isRequired:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">placeholder:</span><span class=\"mtk8\">&quot;Email address&quot;</span><span class=\"mtk1\">   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelText:</span><span class=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelFor:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">autoComplete:</span><span class=\"mtk8\">&quot;current-password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">isRequired:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">placeholder:</span><span class=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk1\">   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">=[</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelText:</span><span class=\"mtk8\">&quot;Username&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelFor:</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk8\">&quot;text&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">autoComplete:</span><span class=\"mtk8\">&quot;username&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">isRequired:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">placeholder:</span><span class=\"mtk8\">&quot;Username&quot;</span><span class=\"mtk1\">   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelText:</span><span class=\"mtk8\">&quot;Email address&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelFor:</span><span class=\"mtk8\">&quot;email-address&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk8\">&quot;email-address&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">autoComplete:</span><span class=\"mtk8\">&quot;email&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">isRequired:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">placeholder:</span><span class=\"mtk8\">&quot;Email address&quot;</span><span class=\"mtk1\">   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelText:</span><span class=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelFor:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">autoComplete:</span><span class=\"mtk8\">&quot;current-password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">isRequired:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">placeholder:</span><span class=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk1\">   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelText:</span><span class=\"mtk8\">&quot;Confirm Password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">labelFor:</span><span class=\"mtk8\">&quot;confirm-password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">id:</span><span class=\"mtk8\">&quot;confirm-password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">name:</span><span class=\"mtk8\">&quot;confirm-password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">type:</span><span class=\"mtk8\">&quot;password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">autoComplete:</span><span class=\"mtk8\">&quot;confirm-password&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">isRequired:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">placeholder:</span><span class=\"mtk8\">&quot;Confirm Password&quot;</span><span class=\"mtk1\">   </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">]</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">,</span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">}</span></span></code></pre>\n<p>The above file has two arrays: one each for your login form fields and signup form fields. Each array contains an object that contains attributes for the input fields.</p>\n<p>The field names should be self-explanatory as to what they represent. Here's a quick summary of that:</p>\n<ul>\n<li><code>labelText</code>: The label for an input field</li>\n<li><code>labelFor</code>: The value that associates a label to the input field via an id attribute on the input field</li>\n<li><code>id</code>, <code>name</code> , <code>type</code>, and <code>placeholder</code>: Respective attributes on the input field  </li>\n<li><code>isRequired</code>: If you want to make an input field mandatory, in this case, all our input fields for form submission will be mandatory</li>\n</ul>\n<p>Later, we'll use this array to cycle through each input field and render a custom <code>&#x3C;Input/></code> component that you'll create shortly.</p>\n<h2 id=\"set-up-routing\" style=\"position:relative;\"><a href=\"#set-up-routing\" aria-label=\"set up routing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Set Up Routing</h2>\n<p>As you already have your components boilerplates in place, let's first set up routing for your app.</p>\n<p>By default, when a user opens the app, we'll direct them to a Login page. Then, if the route changes to <strong>/signup</strong>, we'll direct them to a Signup page. </p>\n<p>Head over to your <code>/src/App.js</code> file and add the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./App.css&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">BrowserRouter</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">Routes</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">Route</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;react-router-dom&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">SignupPage</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./pages/Signup&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">LoginPage</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;./pages/Login&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">App</span><span class=\"mtk1\">() {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> (</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;min-h-full h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;max-w-md w-full space-y-8&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">BrowserRouter</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Routes</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">element</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">LoginPage</span><span class=\"mtk17\">/&gt;</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/signup&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">element</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">SignupPage</span><span class=\"mtk17\">/&gt;</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Routes</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">BrowserRouter</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  );</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk12\">App</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>Notice that you have two containers wrapped around your <code>&#x3C;BrowserRouter/></code> with some long classnames. </p>\n<p>The first container gives a minimum height of 100% and sets a fixed height of the container to 100vh via the <code>min-h-full</code> and <code>h-screen</code> classes. Then, it centers everything via <code>flex</code>, <code>items-center</code> to vertically center all the flex child elements, and <code>justifty-center</code> to center them horizontally. </p>\n<p>Finally, we have some padding classes prefixed with <code>p</code>. For top and bottom padding, we use the prefix <code>py-</code> followed by some value. We also have some responsive padding on small and large screen devices prefixed with <code>sm:</code> and <code>lg:</code> respectively. You can learn more about these <a href=\"https://tailwindcss.com/docs/padding\">padding</a> and <a href=\"https://tailwindcss.com/docs/margin\">margin</a> properties to see other similar classes you can use. </p>\n<p>Similarly, the second container sets some width for its child elements and provides some spacing via the respective Tailwind classes.</p>\n<h2 id=\"the-header-component\" style=\"position:relative;\"><a href=\"#the-header-component\" aria-label=\"the header component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Header Component</h2>\n<p>Now, let's create the <code>&#x3C;Header/></code> component that you can render on both the login and signup pages for quick information and navigation.</p>\n<p>Head over to <code>/src/components/Header.js</code>, and add the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> {</span><span class=\"mtk12\">Link</span><span class=\"mtk1\">} </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react-router-dom&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Header</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">heading</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">paragraph</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">linkName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">linkUrl</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;#&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;mb-10&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;flex justify-center&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">img</span><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">alt</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;h-14 w-14&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://ik.imagekit.io/pibjyepn7p9/Lilac_Navy_Simple_Line_Business_Logo_CGktk8RHK.png?ik-sdk-version=javascript-1.4.3</span><span class=\"mtk14\">&</span><span class=\"mtk8\">updatedAt=1649962071315&quot;</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h2</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;mt-6 text-center text-3xl font-extrabold text-gray-900&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">{</span><span class=\"mtk12\">heading</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h2</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;mt-2 text-center text-sm text-gray-600 mt-5&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">{</span><span class=\"mtk12\">paragraph</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk8\">&#39; &#39;</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Link</span><span class=\"mtk1\"> </span><span class=\"mtk12\">to</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">linkUrl</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;font-medium text-purple-600 hover:text-purple-500&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">{</span><span class=\"mtk12\">linkName</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Link</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Your <code>&#x3C;Header/></code> component takes four props:</p>\n<ul>\n<li>a dynamic <code>heading</code> that it displays on the top;</li>\n<li>then some additional text as <code>paragraph</code>;</li>\n<li>a <code>linkName</code> to display which page it will redirect the user to; and,</li>\n<li>its corresponding path as <code>linkUrl</code>.</li>\n</ul>\n<p>Using the ' justify-center ' class, we place all these elements inside a flexbox container and horizontally center them. There is also an outer container that simply gives the header some bottom margin using the <code>mb-10</code> class.</p>\n<p>Then, we give our header image some fixed height and width using the <code>h-14</code> and <code>w-14</code> classes, respectively. </p>\n<p>Finally, our text and links have some typography classes for font-size, font-colour, hover effect, and font-weight.</p>\n<p>Let's now go ahead and render the <code>&#x3C;Header/></code> component with all the props inside the Login page (<code>/src/pages/Login.js</code>):</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Header</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../components/Header&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LoginPage</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Header</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">heading</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Login to your account&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">paragraph</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Don&#39;t have an account yet? &quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">linkName</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Signup&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">linkUrl</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/signup&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Here's what the login page should now look like:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 18.923076923076923%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAEABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd+AsD//xAAWEAADAAAAAAAAAAAAAAAAAAAAARD/2gAIAQEAAQUCFP/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABQQAQAAAAAAAAAAAAAAAAAAABD/2gAIAQEABj8Cf//EABYQAAMAAAAAAAAAAAAAAAAAAAAQcf/aAAgBAQABPyEpf//aAAwDAQACAAMAAAAQ8A//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAaEAEAAQUAAAAAAAAAAAAAAAABEQAQITFx/9oACAEBAAE/EHTmKCDKe2//2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"login page header\"\n        title=\"login page header\"\n        src=\"/static/496d8822658d348bc2c55fffe8cac357/212bf/login-page-header.jpg\"\n        srcset=\"/static/496d8822658d348bc2c55fffe8cac357/6aca1/login-page-header.jpg 650w,\n/static/496d8822658d348bc2c55fffe8cac357/212bf/login-page-header.jpg 768w,\n/static/496d8822658d348bc2c55fffe8cac357/27b8c/login-page-header.jpg 2666w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Let's now start building the rest of the Login page form.</p>\n<h2 id=\"the-input-component\" style=\"position:relative;\"><a href=\"#the-input-component\" aria-label=\"the input component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Input Component</h2>\n<p>We'll now create our reusable and great looking <code>&#x3C;Input/></code> component that you'll use to build your Login form.</p>\n<p>Head over to the <code>/src/components/Input.js</code> file, and add the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fixedInputClass</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;rounded-md appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 focus:outline-none focus:ring-purple-500 focus:border-purple-500 focus:z-10 sm:text-sm&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Input</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">handleChange</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">value</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">labelText</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">labelFor</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">name</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">isRequired</span><span class=\"mtk1\">=</span><span class=\"mtk4\">false</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">customClass</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;my-5&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">htmlFor</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">labelFor</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;sr-only&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk4\">{</span><span class=\"mtk12\">labelText</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">onChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleChange</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">value</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">type</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">required</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">isRequired</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">fixedInputClass</span><span class=\"mtk1\">+</span><span class=\"mtk12\">customClass</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">placeholder</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Remember all those fields' key-value pairs you set earlier in your <code>formFields.js</code> constants file?</p>\n<p>Those are all the props your <code>&#x3C;Input/></code> component will take. It will also take a <code>value</code> and a <code>handleChange</code> prop since we want this to be a controlled component linked to some state.</p>\n<p>Notice how the HTML markup of this component looks very clean. How is that possible? Are you not using any Tailwind classes here?</p>\n<p>As there are a lot of Tailwind classes for styling this input field, we have created a constant for it — called <code>fixedInputClass</code>. It contains all the essential styling classes for the input field.</p>\n<p>We also take a <code>customClass</code> prop that will append any custom Tailwind class you want to pass to the input field for customizations. How cool is that?!</p>\n<h2 id=\"the-login-component\" style=\"position:relative;\"><a href=\"#the-login-component\" aria-label=\"the login component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Login Component</h2>\n<p>Next, create the <code>&#x3C;Login/></code> component inside <code>/src/components/Login.js</code>, where the entire Login form will be rendered. This component will also be responsible for owning any state or event handlers passed down as props to other child components.</p>\n<p>Based on your <code>loginFields</code> from your <code>formFields</code> constants, we programmatically generate an initial value for your <code>loginState</code>.</p>\n<p>Then we have a <code>handleChange</code> event handler to update the state whenever an <code>onChange</code> event is fired from the nested <code>&#x3C;Input/></code> component. </p>\n<p>Then we simply loop through the <code>fields</code> array and render an <code>&#x3C;Input/></code> component that you've created in the previous section.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useState</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../constants/formFields&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Input</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./Input&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fields</span><span class=\"mtk1\">=</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\"> = {};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">fields</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forEach</span><span class=\"mtk1\">(</span><span class=\"mtk12\">field</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\">[</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">]=</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Login</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">loginState</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setLoginState</span><span class=\"mtk1\">]=</span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleChange</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">setLoginState</span><span class=\"mtk1\">({...</span><span class=\"mtk12\">loginState</span><span class=\"mtk1\">,</span><span class=\"mtk12\">[e.target.id]:e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;mt-8 space-y-6&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;-space-y-px&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">fields</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">field</span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">key</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">handleChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleChange</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">loginState</span><span class=\"mtk1\">[</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">labelText</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">labelText</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">labelFor</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">labelFor</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">type</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">isRequired</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">isRequired</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">placeholder</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Before seeing how the login form looks, you need to render it inside your Login page.</p>\n<p>So render the above <code>&#x3C;Login/></code> component inside <code>/src/pages/Login.js</code> file as shown:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Header</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../components/Header&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../components/Login&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">LoginPage</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Header</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">heading</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Login to your account&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">paragraph</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Don&#39;t have an account yet? &quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">linkName</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Signup&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">linkUrl</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/signup&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Login</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Now, if you go back to your React app, you should see your Login page input fields appear as follows:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 25.538461538461537%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAFABQDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAECBf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAd+AsD//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAEFAn//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAUEAEAAAAAAAAAAAAAAAAAAAAQ/9oACAEBAAY/An//xAAXEAEAAwAAAAAAAAAAAAAAAAABABBh/9oACAEBAAE/IYG1/9oADAMBAAIAAwAAABDwD//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAAICAwAAAAAAAAAAAAAAAAERABAhMVH/2gAIAQEAAT8QOoh5F9r/2Q=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"login page with input fiels\"\n        title=\"login page with input fiels\"\n        src=\"/static/cbb10ea9a4b8162c9e9e9501ff9b8fad/212bf/login-page-with-input-fields.jpg\"\n        srcset=\"/static/cbb10ea9a4b8162c9e9e9501ff9b8fad/6aca1/login-page-with-input-fields.jpg 650w,\n/static/cbb10ea9a4b8162c9e9e9501ff9b8fad/212bf/login-page-with-input-fields.jpg 768w,\n/static/cbb10ea9a4b8162c9e9e9501ff9b8fad/eec88/login-page-with-input-fields.jpg 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Excellent, it looks like you're almost there!</p>\n<p>Now add the final pieces to the Login page by writing the <code>&#x3C;FormExtra></code> and <code>&#x3C;FormAction/></code> components.</p>\n<h2 id=\"wrapping-up-the-login-page\" style=\"position:relative;\"><a href=\"#wrapping-up-the-login-page\" aria-label=\"wrapping up the login page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Wrapping Up the Login Page</h2>\n<p>The <code>&#x3C;FormExtra/></code> component holds the template and styles for a simple \"Remember me\" functionality. </p>\n<p>Inside <code>/src/components/FormExtra.js</code> file, add the following code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">FormExtra</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;flex items-center justify-between &quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;flex items-center&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;remember-me&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;remember-me&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;checkbox&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">label</span><span class=\"mtk1\"> </span><span class=\"mtk12\">htmlFor</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;remember-me&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;ml-2 block text-sm text-gray-900&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            Remember me</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">label</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text-sm&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">a</span><span class=\"mtk1\"> </span><span class=\"mtk12\">href</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;#&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;font-medium text-purple-600 hover:text-purple-500&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            Forgot your password?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">a</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Again here we're using some Tailwind typography and flexbox classes to style and structure the layout of the UI. </p>\n<p>Let's go to the <code>/src/components/FormAction.js</code> file and create a submit button for the Login form. </p>\n<p>Add the following code inside this file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">FormAction</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&#39;Button&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">action</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&#39;submit&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">text</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">type</span><span class=\"mtk1\">===</span><span class=\"mtk8\">&#39;Button&#39;</span><span class=\"mtk1\"> ?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">action</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500 mt-10&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">onSubmit</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk4\">{</span><span class=\"mtk12\">text</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            :</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;&gt;&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Notice that you also have loads of CSS classes inside our <code>&#x3C;button/></code> element to style it. It makes our HTML appear bloated and difficult to read. We can follow the same approach of using a constant and a prop against the <code>className</code> for the <code>&#x3C;button/></code> as we previously did to combat this. </p>\n<p>At last, we'll put everything together inside <code>/src/components/Login.js</code> file as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useState</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../constants/formFields&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">FormAction</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./FormAction&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">FormExtra</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./FormExtra&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Input</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./Input&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fields</span><span class=\"mtk1\">=</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\"> = {};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">fields</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forEach</span><span class=\"mtk1\">(</span><span class=\"mtk12\">field</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\">[</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">]=</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Login</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">loginState</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setLoginState</span><span class=\"mtk1\">]=</span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleChange</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">setLoginState</span><span class=\"mtk1\">({...</span><span class=\"mtk12\">loginState</span><span class=\"mtk1\">,</span><span class=\"mtk12\">[e.target.id]:e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleSubmit</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">authenticateUser</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk3\">//Handle Login API Integration here</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">authenticateUser</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;mt-8 space-y-6&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onSubmit</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;-space-y-px&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">fields</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">field</span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">key</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">handleChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleChange</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">loginState</span><span class=\"mtk1\">[</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">labelText</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">labelText</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">labelFor</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">labelFor</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">type</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">isRequired</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">isRequired</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">placeholder</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">FormExtra</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">FormAction</span><span class=\"mtk1\"> </span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">text</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Login&quot;</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>And once we do that, we should have a stunning, modern looking login page appear right in front of us:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.46153846153847%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA90lEQVQoz62RTU7DMBCFff81ErCCQxQjxUncCiliAQeA8rOHRZUmrt3YMw87gRXUVSOe9EnjmfHT2COUUiiKIqIgpcRicfMLKW+R+sq6QqkKLOs71KsVylJBa4065rVeoqoqCPyzRAgBObz3CBQmwnEEMyNHUv/Rw3yaMT7WL3JGO2uxfn3H89Mb1pGXGNuYyxlnJyQiOLeHdQ7O7uEdgTFjwiQiRtcZDIMH02TOTCCmeYbpsrEGnnw6jQRPCMO3IU403G0CmssNmvMWj9cGD1c9mrMO9xd9rNHBfzxgyOOT3TbSMmxLI247kWrAyVv+4S/xvC3P4QsLC6JyPkfDCgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"login page\"\n        title=\"login page\"\n        src=\"/static/2bb44b070fe325150bbfc386d7bc3561/e5715/login-page.png\"\n        srcset=\"/static/2bb44b070fe325150bbfc386d7bc3561/a6d36/login-page.png 650w,\n/static/2bb44b070fe325150bbfc386d7bc3561/e5715/login-page.png 768w,\n/static/2bb44b070fe325150bbfc386d7bc3561/d9ed5/login-page.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<h2 id=\"the-signup-page\" style=\"position:relative;\"><a href=\"#the-signup-page\" aria-label=\"the signup page permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Signup Page</h2>\n<p>You've created so many reusable components. Now, it's straightforward to use them to build the Signup page further.</p>\n<p>Feel free to take this as a challenge and build it yourself based on what you've learned. </p>\n<p>Here's a quick walkthrough of the steps and how you can use the same approach to build the Signup page in minutes. </p>\n<p>First, create a main <code>&#x3C;Singup/></code> component inside <code>/src/components/Signup.js</code> file similar to the <code>&#x3C;Login/></code> component you've completed in the previous section. It will render the signup form fields and attach state and event handlers to it.</p>\n<p>Here's how the entire code looks like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">useState</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;react&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../constants/formFields&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">FormAction</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./FormAction&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Input</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;./Input&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fields</span><span class=\"mtk1\">=</span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\">={};</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">fields</span><span class=\"mtk1\">.</span><span class=\"mtk11\">forEach</span><span class=\"mtk1\">(</span><span class=\"mtk12\">field</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\">[</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">]=</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Signup</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> [</span><span class=\"mtk12\">signupState</span><span class=\"mtk1\">,</span><span class=\"mtk12\">setSignupState</span><span class=\"mtk1\">]=</span><span class=\"mtk11\">useState</span><span class=\"mtk1\">(</span><span class=\"mtk12\">fieldsState</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleChange</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk11\">setSignupState</span><span class=\"mtk1\">({...</span><span class=\"mtk12\">signupState</span><span class=\"mtk1\">,</span><span class=\"mtk12\">[e.target.id]:e</span><span class=\"mtk1\">.</span><span class=\"mtk12\">target</span><span class=\"mtk1\">.</span><span class=\"mtk12\">value</span><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleSubmit</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">e</span><span class=\"mtk1\">.</span><span class=\"mtk11\">preventDefault</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">signupState</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">createAccount</span><span class=\"mtk1\">()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">//handle Signup API Integration here</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">createAccount</span><span class=\"mtk1\">=()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;mt-8 space-y-6&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">onSubmit</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">className</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">fields</span><span class=\"mtk1\">.</span><span class=\"mtk11\">map</span><span class=\"mtk1\">(</span><span class=\"mtk12\">field</span><span class=\"mtk4\">=&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">key</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">handleChange</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleChange</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">signupState</span><span class=\"mtk1\">[</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">]</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">labelText</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">labelText</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">labelFor</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">labelFor</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">name</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">type</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">isRequired</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">isRequired</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                            </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">field</span><span class=\"mtk1\">.</span><span class=\"mtk12\">placeholder</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">FormAction</span><span class=\"mtk1\"> </span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">handleSubmit</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">text</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Signup&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">         </span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">form</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Then, render this component inside <code>/src/pages/Signup.js</code> alongside the <code>&#x3C;Header/></code> components with some modified props for the signup page. </p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"jsx\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Header</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../components/Header&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Signup</span><span class=\"mtk1\"> </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;../components/Signup&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk15\">default</span><span class=\"mtk1\"> </span><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">SignupPage</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">return</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Header</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">heading</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Signup to create an account&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">paragraph</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Already have an account? &quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">linkName</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Login&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">linkUrl</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Signup</span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    )</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>And that's it! That's all there is to build a great looking signup page that looks as follows:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.46153846153847%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8UlEQVQoz62R2QrCMBBF+///oSi+1q1p2oof4PKqoA+2bo0LaExt2muMKIq2uCUchmEmh2FiEEJgWZaCoNFowqxWYZp3qLxWq4Oouu1S2MSC57ThtFqwKYHrunAcCs/zQCmFgT8fQ0qJLK5HbASirbjleW+eJkzT9BbniyUWyxD+eIrJKEDIGBhbP/Q8TZgn1DJfyaYKf4ZZEGK1/kEYx/Llnr4W7nYcQkRqN4mWX/layKM9YhzP2QP66rYPhPKodjg8YD44YDWONWx0iefaxxOKbYJ+maNb5OhXLnQKe/RKXNfeFmY1vtuTu8M0ySDnU045+aKZ56aFlAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Signup page\"\n        title=\"Signup page\"\n        src=\"/static/fa1a6161f8a44b5d86827ad42aa7232a/e5715/signup-page.png\"\n        srcset=\"/static/fa1a6161f8a44b5d86827ad42aa7232a/a6d36/signup-page.png 650w,\n/static/fa1a6161f8a44b5d86827ad42aa7232a/e5715/signup-page.png 768w,\n/static/fa1a6161f8a44b5d86827ad42aa7232a/d9ed5/signup-page.png 2880w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Don't worry; if you got stuck somewhere, feel free to <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/React/react-tailwind-app\">refer to the entire codebase for this tutorial here</a>. </p>\n<h2 id=\"use-loginradius-authentication-apis\" style=\"position:relative;\"><a href=\"#use-loginradius-authentication-apis\" aria-label=\"use loginradius authentication apis permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Use LoginRadius Authentication APIs</h2>\n<p>You can use <a href=\"https://www.loginradius.com/resource/whitepaper/loginradius-ciam-developers/\">LoginRadius</a> to quickly set up an authentication backend for your frontend application.</p>\n<p>First, <a href=\"https://accounts.loginradius.com/auth.aspx\">set up an account</a>, and get your API key from your Account Dashboard.</p>\n<p>Then, you can use their <a href=\"https://www.loginradius.com/docs/api/v2/single-sign-on/Machine-to-Machine/overview/\">login endpoint</a> to authenticate users. </p>\n<p>The endpoint takes an email and password as parameters and validates them against the correct credentials. If we were to integrate this endpoint in our previously built <code>&#x3C;Login/></code> component (<code>/scr/components/Login.js</code>), here's what the <code>authenticateUser</code> method would look like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//Handle Login API Integration here</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">authenticateUser</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">=</span><span class=\"mtk8\">`https://api.loginradius.com/identity/v2/auth/login?apikey=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">apiKey</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">         </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             </span><span class=\"mtk12\">method:</span><span class=\"mtk8\">&#39;POST&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             </span><span class=\"mtk12\">body:</span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             }).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk3\">//API Success from LoginRadius Login API</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">         </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span></code></pre>\n<p>Similarly, you can use <a href=\"https://www.loginradius.com/resource/whitepaper/loginradius-ciam-developers/\">the Signup endpoint</a> to create users without managing a complete backend database yourself.</p>\n<p>Curious to learn more?</p>\n<p>I did a full-fledged <a href=\"https://www.loginradius.com/blog/engineering/guest-post/authenticating-svelte-apps/\">guide on authenticating Svelte apps with LoginRadius here</a>.</p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>In this tutorial, you have learned to create beautiful registration and authentication forms for your web app with Tailwind CSS. You also learned the advantages and disadvantages of Tailwind CSS and understood how Tailwind CSS works better with React.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n</style>","frontmatter":{"title":"Build a Modern Login/Signup Form with Tailwind CSS and React","author":{"id":"Siddhant Varma","github":"FuzzySid","avatar":null},"date":"May 17, 2022","updated_date":null,"tags":["Tailwind CSS","React","Authentication"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/a1c3066797f2394882941ee5e3297547/ee604/modern-login-and-signup-form-banner.png","srcSet":"/static/a1c3066797f2394882941ee5e3297547/69585/modern-login-and-signup-form-banner.png 200w,\n/static/a1c3066797f2394882941ee5e3297547/497c6/modern-login-and-signup-form-banner.png 400w,\n/static/a1c3066797f2394882941ee5e3297547/ee604/modern-login-and-signup-form-banner.png 800w,\n/static/a1c3066797f2394882941ee5e3297547/f3583/modern-login-and-signup-form-banner.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}}},"fields":{"authorId":"Siddhant Varma","slug":"/engineering/guest-post/modern-login-signup-form-tailwindcss-react/"}}},{"node":{"id":"40ab3278-93ec-5768-85c0-54719dbd017a","html":"<p>In this tutorial, I’ll talk about adding authentication in a Svelte application using LoginRadius Authentication APIs. You'll understand step by step how to:</p>\n<ul>\n<li>create forms in Svelte;</li>\n<li>add reactivity to it;</li>\n<li>configure routing for our Svelte app; and,</li>\n<li>setup protected routes for authenticated users.</li>\n</ul>\n<p>You'll also learn how to consume REST APIs in a Svelte app using Fetch API and update user information in your Svelte store.</p>\n<h2 id=\"what-is-svelte\" style=\"position:relative;\"><a href=\"#what-is-svelte\" aria-label=\"what is svelte permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What is Svelte?</h2>\n<p><a href=\"https://svelte.dev/\">Svelte</a> is a lightweight and minimal JavaScript compiler that ships a single JavaScript bundle to your application without any internal code of its own. This results in smaller bundle size and often a faster running application. It was also the <a href=\"https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-web-frameworks\">most loved framework of 2021</a>.</p>\n<p>But what's the first feature you'd add in a Svelte application? Authentication! It's the gateway for your users to interact and use your website.</p>\n<p>So in this post, I’ll talk about how to add authentication in a Svelte application.</p>\n<h2 id=\"svelte-project-demo\" style=\"position:relative;\"><a href=\"#svelte-project-demo\" aria-label=\"svelte project demo permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Svelte Project Demo</h2>\n<p>You'll learn how to create forms in Svelte and add reactivity to it. You'll also understand how to conditionally render different UI components and set up protected routes for authenticated users in a Svelte application.</p>\n<p>To speed things up, you won't build your own authentication services from scratch. Instead, you'll use <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer&#x26;action=register\">LoginRadius</a> to quickly configure an authentication backend for your Svelte App.</p>\n<p>Here's a little demo of what your Svelte App would look like by the end of the tutorial:</p>\n<p><video controls width=\"700\" align=\"center\" src=\"/648a1d1a74555638a162015f5d7769b5/Svelte-Auth-LoginRadius-Demo.mp4\"/> </video></p>\n<p>Looks exciting? Let's jump right into it!</p>\n<h2 id=\"setup-a-svelte-app\" style=\"position:relative;\"><a href=\"#setup-a-svelte-app\" aria-label=\"setup a svelte app permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup a Svelte App</h2>\n<p>Let's start by creating a new Svelte project and adding some boilerplate code.</p>\n<h3 id=\"create-a-new-svelte-project\" style=\"position:relative;\"><a href=\"#create-a-new-svelte-project\" aria-label=\"create a new svelte project permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create a New Svelte Project</h3>\n<p>Navigate into the directory of your choice and create a new Svelte project by running:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npx degit sveltejs/template svelte-auth-app</span></code></pre>\n<p>That should create a new Svelte project with a simple starter template.</p>\n<p>Additionally, you'll need to install <a href=\"https://github.com/mefechoel/svelte-navigator\">svelte-navigator</a> package to set up routing in your Svelte app:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm i svelte-navigator</span></code></pre>\n<h3 id=\"configure-environment-variable-support\" style=\"position:relative;\"><a href=\"#configure-environment-variable-support\" aria-label=\"configure environment variable support permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Configure Environment Variable Support</h3>\n<p>You need to add environment variable support in your Svelte app to store and use your LoginRadius API Keys and Secrets.</p>\n<p>First, install a package called <a href=\"https://www.npmjs.com/package/dotenv\">dotenv</a> that let's create and use a special <code>.env</code> file to define your environment variables.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">npm i dotenv</span></code></pre>\n<p>Next, head over to the <code>rollup.config.js</code> file. Here, make some configurational changes on the <code>plugins</code> property, so your Svelte app can read those environment variables on the client-side:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tplugins: [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk11\">replace</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk3\">// stringify the object</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t</span><span class=\"mtk12\">__myapp:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">({</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t  </span><span class=\"mtk12\">env:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t\t</span><span class=\"mtk12\">isProd:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">production</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t\t...</span><span class=\"mtk11\">config</span><span class=\"mtk1\">().</span><span class=\"mtk12\">parsed</span><span class=\"mtk1\"> </span><span class=\"mtk3\">// attached the .env config</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t}),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t  }),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t],</span></span></code></pre>\n<p>You can refer to the complete <code>rollup.config.js</code> file for this project <a href=\"https://github.com/LoginRadius/engineering-blog-samples/blob/master/Svelte/SvelteAuthApp/rollup.config.js\">here</a>.</p>\n<h3 id=\"create-files-and-folders\" style=\"position:relative;\"><a href=\"#create-files-and-folders\" aria-label=\"create files and folders permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Files and Folders</h3>\n<p>Besides the initial set of files, your project will have the following directory structure:</p>\n<p><img src=\"/b127258daa14eecbda3f07a8bccce890/Directory-Structure-Svelte-App.png\" alt=\"Directory Structure Svelte App\"></p>\n<p>So go ahead and create those files and folders accordingly. I'll talk about each of these as you start filling them with some code.</p>\n<h3 id=\"add-project-styles\" style=\"position:relative;\"><a href=\"#add-project-styles\" aria-label=\"add project styles permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Project Styles</h3>\n<p>Your starter template should come with the following styles inside your <code>App.svelte file</code>:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">main</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">text-align</span><span class=\"mtk1\">: </span><span class=\"mtk8\">center</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">padding</span><span class=\"mtk1\">: </span><span class=\"mtk7\">1em</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">max-width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">240px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk8\">auto</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">h1</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#ff3e00</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">text-transform</span><span class=\"mtk1\">: </span><span class=\"mtk8\">uppercase</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-size</span><span class=\"mtk1\">: </span><span class=\"mtk7\">4em</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">font-weight</span><span class=\"mtk1\">: </span><span class=\"mtk7\">100</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">@media</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">min-width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">640px</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk6\">main</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">max-width</span><span class=\"mtk1\">: </span><span class=\"mtk8\">none</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>However, I have also added some additional styles inside the global stylesheet inside the <code>/public/build/global.css</code> file. You can copy those styles from <a href=\"https://github.com/LoginRadius/engineering-blog-samples/blob/master/Svelte/SvelteAuthApp/public/global.css\">here</a>.</p>\n<h2 id=\"global-data-store-for-authenticated-user\" style=\"position:relative;\"><a href=\"#global-data-store-for-authenticated-user\" aria-label=\"global data store for authenticated user permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Global Data Store for Authenticated User</h2>\n<p>Your Svelte app will store the authenticated user's data in a global data store to easily access and modify that data from any component within your application. Svelte provides you with the <code>writable</code> function inside the <code>svelte/store</code> dependency.</p>\n<p>Create a global object called <code>user</code> inside your <code>/src/stores.js</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">writable</span><span class=\"mtk1\"> } </span><span class=\"mtk15\">from</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;svelte/store&quot;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">export</span><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">writable</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk12\">user</span><span class=\"mtk1\"> ? </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(</span><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user&quot;</span><span class=\"mtk1\">)) : </span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">)</span></span></code></pre>\n<p>You have also synced the above <code>user</code> object with the browser's local storage so that this data persists on page reloads. If you're unfamiliar with what local storage is, <a href=\"https://www.loginradius.com/blog/engineering/guest-post/local-storage-vs-session-storage-vs-cookies/\">check out my guide on Local Storage vs. Session Storage vs. Cookies</a> that dives deeper into browser storage and other related concepts.</p>\n<h2 id=\"the-app-component-boilerplate\" style=\"position:relative;\"><a href=\"#the-app-component-boilerplate\" aria-label=\"the app component boilerplate permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The App Component Boilerplate</h2>\n<p>The root component in your Svelte app is the App Component. This is located inside <code>/src/App.svelte</code>.</p>\n<p>It has the following imports declared inside:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  /** IMPORTS */ import Login from &#39;./Login.svelte&#39;; import Signup from</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  &#39;./Signup.svelte&#39;; import Home from &#39;./Home.svelte&#39;; import PrivateRoute from</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  &quot;./routes/PrivateRoutes.svelte&quot;; /** VARIABLES */ const sdkoptions = </span><span class=\"mtk4\">{}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>It also has an <code>sdkoptions</code> variable that will store the environment variables that you can easily pass to different components as and when they need it. You can get rid of any additional HTML inside the <code>App.svelte</code> file generated by the starter template.</p>\n<h2 id=\"the-login-component\" style=\"position:relative;\"><a href=\"#the-login-component\" aria-label=\"the login component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Login Component</h2>\n<p>Let's head over to the <code>/src/Login.svelte</code> file to create the Login Page.</p>\n<h3 id=\"create-login-form\" style=\"position:relative;\"><a href=\"#create-login-form\" aria-label=\"create login form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Login Form</h3>\n<p>Here's what the HTML of your Login Form consists of:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk14\">on:submit|preventDefault=&quot;{handleSubmit}&quot;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk14\">&lt;input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{email}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{password}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Login</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">form</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Don&#39;t have an account?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;link&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{navigateToSignup}&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Sign up</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You have a login form with two input fields for email and password and a submit button. The form also has an <code>on:submit</code> handler with an event modifier to prevent the default reloading action of the form when it gets submitted.</p>\n<p>After the form, you have a simple link with an <code>on:click</code> handler that allows the user to navigate to the Signup page.</p>\n<h3 id=\"login-form-field-bindings-and-handlers\" style=\"position:relative;\"><a href=\"#login-form-field-bindings-and-handlers\" aria-label=\"login form field bindings and handlers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Login Form Field Bindings and Handlers</h3>\n<p>Inside the script of your Login component, create two variables — <code>email</code> and <code>password</code> — to handle the bindings to the input fields. Also, make the <code>sdkoptions</code> variable exportable since you'll receive it as <code>props</code> from the App component.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">let email; let password; export let sdkoptions;</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You also need to create a function called <code>handleSubmit</code> that is the <code>on:submit</code> handler for your Login form:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const handleSubmit=(e)=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">={</span><span class=\"mtk12\">email</span><span class=\"mtk1\">,</span><span class=\"mtk12\">password</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t   </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const navigateToSignup=()=&gt;</span><span class=\"mtk4\">{}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>At the moment, you're simply encapsulating the <code>email</code> and <code>password</code> bindings into a JavaScript object. Later, you'll send a request to your Login API here. You also have an empty <code>navigateToSignup</code> function that I'll come back to once you set up your routes.</p>\n<p>Let's render the Login component inside your <code>App.svelte</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p><img src=\"/a83987b29ea11ed6919d189c638e18b3/Login-Page.png\" alt=\"Login Page\"></p>\n<p>Awesome! Let's follow the same process to create your Signup form.</p>\n<h2 id=\"the-signup-component\" style=\"position:relative;\"><a href=\"#the-signup-component\" aria-label=\"the signup component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Signup Component</h2>\n<p>Head over to the <code>/src/Signup.svelte</code> file to create your Signup Page.</p>\n<h3 id=\"create-signup-form\" style=\"position:relative;\"><a href=\"#create-signup-form\" aria-label=\"create signup form permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create Signup Form</h3>\n<p>Similar to the Login Form, the Signup Form will have the following HTML:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Create a New Account</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><span class=\"mtk1\"> </span><span class=\"mtk14\">on:submit|preventDefault=&quot;{handleSubmit}&quot;&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk14\">&lt;input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{firstName}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;First Name&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{lastName}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;text&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Last Name&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{email}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Email&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">bind</span><span class=\"mtk1\">:</span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{password}&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">placeholder</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;Password&quot;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">form</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Already have an account?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;link&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{navigateToLogin}&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Login</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>The only difference is now you have two additional fields — first name and last name. You also have a link just below the signup form that takes the user to the login page.</p>\n<h3 id=\"signup-form-field-bindings-and-handlers\" style=\"position:relative;\"><a href=\"#signup-form-field-bindings-and-handlers\" aria-label=\"signup form field bindings and handlers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Signup Form Field Bindings and Handlers</h3>\n<p>Here's what the script section of your <code>Signup.svelte</code> file should look like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\tlet email;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let password;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let firstName;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let lastName;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let loading;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    export let sdkoptions;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const handleSubmit=()=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;FirstName&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">firstName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;LastName&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lastName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;Email&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Primary&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk8\">&quot;Value&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">email</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            ],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk8\">&quot;Password&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   const navigateToLogin=()=&gt;</span><span class=\"mtk4\">{}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Your <code>signupFields</code> object has a specific format because it aligns with the structure of your Signup API's request. It would make complete sense when you hook your Signup API here.</p>\n<p>Let's render the Signup component inside your <code>App.svelte</code> file:</p>\n<p><img src=\"/f70cc840f16f82553b479878867845f4/Signup-Page.png\" alt=\"Signup Page\"></p>\n<h2 id=\"the-home-component\" style=\"position:relative;\"><a href=\"#the-home-component\" aria-label=\"the home component permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Home Component</h2>\n<p>Let's create your Home component or the page where you'll redirect an user on a successfull login. Inside <code>/src/Home.svelte</code> file, add the following HTML:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">{#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> && </span><span class=\"mtk12\">_user</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Welcome </span><span class=\"mtk4\">{</span><span class=\"mtk12\">_user</span><span class=\"mtk1\">?.</span><span class=\"mtk12\">profile</span><span class=\"mtk1\">?.</span><span class=\"mtk12\">FullName</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">h3</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{logout}&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Logout</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span></code></pre>\n<p>In the above HTML, you simply use some Svelte conditionals to render the user's name and a logout button. The script part of your Home component looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk12\">user</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &#39;./stores&#39;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let _user;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    user.subscribe(data=&gt;_user=data)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const logout=()=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk4\">null</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">clear</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>You import the global <code>user</code> object from your Svelte store and store it inside your Home component's state <code>_user</code>. For the <code>logout</code> function, you simply set this <code>user</code> object in your store to null and clear the local storage.</p>\n<h2 id=\"setup-loginradius\" style=\"position:relative;\"><a href=\"#setup-loginradius\" aria-label=\"setup loginradius permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup LoginRadius</h2>\n<p>The next step is to set up LoginRadius, so you can start using its Authentication APIs from your Svelte App.</p>\n<h3 id=\"create-loginradius-account\" style=\"position:relative;\"><a href=\"#create-loginradius-account\" aria-label=\"create loginradius account permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Create LoginRadius Account</h3>\n<p>Head over to <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer&#x26;action=register\">LoginRadius</a> and create a new account by filling in the following details:</p>\n<p><img src=\"/5f0a6c05fe8103a95752a598ff49cb06/Signup-2.png\" alt=\"Signup 2\"></p>\n<p>You'll then see a form with the name of your App, a URL, and a Data Center:</p>\n<p><img src=\"/d8b3b347f5c28460e05fcc3aeb364a90/Signup-3.png\" alt=\"Signup 3\"></p>\n<p>Hit <strong>Next</strong> and LoginRadius will set up an authentication app for you. You can try the pre-built authentication page LoginRadius provides for your app by clicking on <strong>Try Signing Up Now</strong>.</p>\n<p><img src=\"/4113757d959a0955ec852e781c5f1dad/Signup-4.png\" alt=\"Signup 4\"></p>\n<p>Once you do that, you'll be shown a pre-built authentication page of your LoginRadius app:</p>\n<p><img src=\"/294bf6ef8298c2248b922f708db69374/LoginRadius-Auth-Page.png\" alt=\"LoginRadius Auth Page\"></p>\n<p>However, for this tutorial, all you need are the LoginRadius APIs since you already have a frontend (your Svelte App) in place.</p>\n<h3 id=\"get-loginradius-api-configurations\" style=\"position:relative;\"><a href=\"#get-loginradius-api-configurations\" aria-label=\"get loginradius api configurations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Get LoginRadius API Configurations</h3>\n<p>Once you're inside your LoginRadius account, head over to the <strong>Configurations</strong> tab from your dashboard. Then expand the <strong>API Credentials</strong> tab of your application.</p>\n<p><img src=\"/2f2ec40982bff4f7b0ff5f1e2feb34e6/LoginRadius-Configuration-Tab.png\" alt=\"LoginRadius Configuration Tab\"></p>\n<p>Inside that, you should see your APP Name, API Key, and API Secret.</p>\n<p><img src=\"/f186d4d464190f4ab2407c896cb101be/LoginRadius-API-Credentials.png\" alt=\"LoginRadius API Credentials\"></p>\n<h3 id=\"add-api-credentials-as-environment-variables\" style=\"position:relative;\"><a href=\"#add-api-credentials-as-environment-variables\" aria-label=\"add api credentials as environment variables permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add API Credentials as Environment Variables</h3>\n<p>Head back to the Svelte App's <code>.env</code> file and add the above credentials inside it:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">APP_NAME=&lt;YOUR_APP_NAME&gt;</span>\n<span class=\"grvsc-line\">API_CLIENT_KEY= &lt;YOUR_APP_API_KEY&gt;</span>\n<span class=\"grvsc-line\">API_SECRET= &lt;YOUR_APP_API_SECRET&gt;</span></code></pre>\n<p>You'll need to ensure that the above <code>.env</code> file is present inside the <code>.gitignore</code> of your Svelte project. You don't want to accidentally push this file to a public repository on Github.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"16\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">/node_modules/</span>\n<span class=\"grvsc-line\">/public/build/</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">.DS_Store</span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\">.env</span></code></pre>\n<h3 id=\"consume-environment-variables-in-svelte-components\" style=\"position:relative;\"><a href=\"#consume-environment-variables-in-svelte-components\" aria-label=\"consume environment variables in svelte components permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Consume Environment Variables in Svelte Components</h3>\n<p>Finally, you need to extract these environment variables in your <code>sdkoptions</code> variables inside your App component file.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"17\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;apiKey&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">__myapp</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;env&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk12\">API_CLIENT_KEY</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk8\">&quot;appName&quot;</span><span class=\"mtk12\">:__myapp</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;env&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk12\">APP_NAME</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&quot;apiSecret&quot;</span><span class=\"mtk12\">:__myapp</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&quot;env&quot;</span><span class=\"mtk1\">].</span><span class=\"mtk12\">API_SECRET</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>And pass this variable as props to both the Login and Signup component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"18\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Signup</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>Great! Now you're ready to integrate LoginRadius APIs in your Svelte app.</p>\n<h2 id=\"integrate-loginradius-api\" style=\"position:relative;\"><a href=\"#integrate-loginradius-api\" aria-label=\"integrate loginradius api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrate LoginRadius API</h2>\n<p>You'll use two APIs — one for registering the user on the Signup page and the other for authenticating the user on the Login Page. However, both APIs will take the API key and API secret as query parameters.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"19\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`</span><span class=\"mtk4\">${</span><span class=\"mtk12\">BASE_URL</span><span class=\"mtk4\">}</span><span class=\"mtk8\">?apikey=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiKey</span><span class=\"mtk4\">}</span><span class=\"mtk8\">&apisecret=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiSecret</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span></code></pre>\n<p>So in the above endpoint, you'll only change the <code>BASE_URL</code> according to which API you're hitting.</p>\n<h3 id=\"integrate-signup-api\" style=\"position:relative;\"><a href=\"#integrate-signup-api\" aria-label=\"integrate signup api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrate Signup API</h3>\n<p>Inside your <code>Signup.svelte</code> file, you'll create a variable called <code>signupResponse</code> to store the result of the Signup API. It also has properties like <code>success</code> and <code>error</code> to prompt the user on the status of your API calls.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"20\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let signupResponse=</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">success</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">error</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">uid</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">id</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">fullname</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">     </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> \tlet loading;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Since an API request is an asynchronous process, you also have a' loading' variable to disable the submit button until the API responds.</p>\n<h4 id=\"signup-api-request-on-signup-form-submission\" style=\"position:relative;\"><a href=\"#signup-api-request-on-signup-form-submission\" aria-label=\"signup api request on signup form submission permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Signup API Request on Signup Form Submission</h4>\n<p>You need to send a request to the Signup API inside your <code>handleSubmit()</code> function. First, set the <code>loading</code> to true and reset the <code>signupResponse</code> object. Then, use the fetch API to make a POST request with the <code>signupFields</code> object as post parameter:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"21\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleSubmit</span><span class=\"mtk1\"> = () </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">FirstName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">firstName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">LastName:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lastName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Email:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">Type:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Primary&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">Value:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">email</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">Password:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">password</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">loading</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">true</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">success:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">error:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">uid:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">fullname:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">`https://api.loginradius.com/identity/v2/manage/account?apikey=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiKey</span><span class=\"mtk4\">}</span><span class=\"mtk8\">&apisecret=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiSecret</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">method:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;POST&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&quot;Content-Type&quot;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;application/json&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">body:</span><span class=\"mtk1\"> </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">signupFields</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> {})</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\"> </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    .</span><span class=\"mtk11\">finally</span><span class=\"mtk1\">(() </span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">loading</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">false</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h4 id=\"handle-api-response\" style=\"position:relative;\"><a href=\"#handle-api-response\" aria-label=\"handle api response permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Handle API Response</h4>\n<p>Inside the callback of your fetch request, you can handle any errors returned by the API based on different error codes. In case of success, you'll populate your <code>signupResponse</code> object with data from the API. In the <code>finally</code> block, set the <code>loading</code> to false.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"22\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">.</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">          </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">936</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">              </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Message</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">             }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">1134</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Errors</span><span class=\"mtk1\">[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">].</span><span class=\"mtk12\">ErrorMessage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Description</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                ...</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">success:</span><span class=\"mtk8\">&quot;Account created successfully! Please login via the same details.&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">fullname:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">FullName</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">id:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">id</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">uid:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Uid</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<h4 id=\"disable-submit-button\" style=\"position:relative;\"><a href=\"#disable-submit-button\" aria-label=\"disable submit button permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Disable Submit Button</h4>\n<p>You can set the disabled attribute on your Submit button based on the loading state of the API.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"23\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">button</span><span class=\"mtk1\"> </span><span class=\"mtk12\">disabled</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;{loading}&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;form-field&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Signup</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">button</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<h4 id=\"show-signup-success-and-error\" style=\"position:relative;\"><a href=\"#show-signup-success-and-error\" aria-label=\"show signup success and error permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Show Signup Success and Error</h4>\n<p>Lastly, render a conditional template based on the status of your Signup API.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"24\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">... {#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Error ❌ </span><span class=\"mtk4\">{</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">} {#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">success</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;success&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  Success ✔ </span><span class=\"mtk4\">{</span><span class=\"mtk12\">signupResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">success</span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">} ...</span></span></code></pre>\n<p>And that's it! Let's give your Signup functionality a whirl. Create a new account first:</p>\n<p><img src=\"/1ec6121e723d287acd3097bcf72a8fe8/Signup-Success-with-API.png\" alt=\"Signup Success with API\"></p>\n<p>And voila! You can see in the network tab that the API is successful. And you got back a bunch of data about the newly created user. You also have a success that appears underneath the Signup form.</p>\n<p>Let's also test an erroneous flow. What if you signup via the same credentials again?</p>\n<p><img src=\"/332563b5257d0cf45b9ae3039ea0a832/Signup-Failure-Existing-Email.png\" alt=\"Signup Failure Existing Email\"></p>\n<p>The LoginRadius Signup API returns the error message, details, error code, etc., that you've handled accordingly.</p>\n<p>Also, if you use a simple password, the LoginRadius API returns an error based on a validation mechanism.</p>\n<p><img src=\"/af70d87365d494ebae97ec028b47d597/Signup-Error-Password-Validation.png\" alt=\"Signup Error Password Validation\"></p>\n<p>That's great because it makes your authentication workflow more air-tight.</p>\n<h3 id=\"integrate-login-api\" style=\"position:relative;\"><a href=\"#integrate-login-api\" aria-label=\"integrate login api permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Integrate Login API</h3>\n<p>Similarly, you can now integrate the Login API as well in your <code>Login.svelte</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"25\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk12\">user</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &#39;./stores&#39;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let email;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let password;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let loading;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    let loginResponse=</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">success</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">profile</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">auth_token</span><span class=\"mtk1\">:</span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    export let sdkoptions;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const handleSubmit=(e)=&gt;</span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">let</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">={</span><span class=\"mtk12\">email</span><span class=\"mtk1\">,</span><span class=\"mtk12\">password</span><span class=\"mtk1\">};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">loading</span><span class=\"mtk1\">=</span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">error:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">success:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">profile:</span><span class=\"mtk4\">null</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">auth_token:</span><span class=\"mtk4\">null</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">=</span><span class=\"mtk8\">`https://api.loginradius.com/identity/v2/auth/login?apikey=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiKey</span><span class=\"mtk4\">}</span><span class=\"mtk8\">&apisecret=</span><span class=\"mtk4\">${</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apiSecret</span><span class=\"mtk4\">}</span><span class=\"mtk8\">`</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       </span><span class=\"mtk12\">loading</span><span class=\"mtk1\">=</span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">method:</span><span class=\"mtk8\">&#39;POST&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">headers:</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk8\">&#39;Content-Type&#39;</span><span class=\"mtk12\">:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;application/json&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">body:</span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginFields</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }).</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">response</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">response</span><span class=\"mtk1\">.</span><span class=\"mtk11\">json</span><span class=\"mtk1\">())</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">936</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Message</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk15\">else</span><span class=\"mtk1\"> </span><span class=\"mtk15\">if</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">ErrorCode</span><span class=\"mtk1\">==</span><span class=\"mtk7\">1134</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Errors</span><span class=\"mtk1\">[</span><span class=\"mtk7\">0</span><span class=\"mtk1\">].</span><span class=\"mtk12\">ErrorMessage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">error:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Description</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span><span class=\"mtk15\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">={</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    ...</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">success:</span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">profile:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">Profile</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    </span><span class=\"mtk12\">auth_token:</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">access_token:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">access_token</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">refresh_token:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">refresh_token</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                        </span><span class=\"mtk12\">ttl:data</span><span class=\"mtk1\">.</span><span class=\"mtk12\">expires_in</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">user</span><span class=\"mtk1\">.</span><span class=\"mtk11\">set</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;user&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">catch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk12\">error</span><span class=\"mtk1\">))</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">finally</span><span class=\"mtk1\">(()</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk12\">loading</span><span class=\"mtk1\">=</span><span class=\"mtk4\">false</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ...</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Error ❌ </span><span class=\"mtk4\">{</span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">error</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">loginResponse</span><span class=\"mtk1\">.</span><span class=\"mtk12\">success</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;success&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        Success ✔</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">{/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    Don&#39;t have an account?</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">strong</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;link&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">on</span><span class=\"mtk1\">:</span><span class=\"mtk12\">click</span><span class=\"mtk1\">=</span><span class=\"mtk4\">{</span><span class=\"mtk12\">navigateToSignup</span><span class=\"mtk4\">}</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">Sign up</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">strong</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">p</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>If you relate it to the Signup component, it's almost identical. The only thing that has changed is the API endpoint. Additionally, if the Login API is a success, you're also storing the data in your <code>user</code> store and consequently updating your <code>localStorage</code>.</p>\n<p>Let's also test this out:</p>\n<p><img src=\"/4bb4c7881a3e1accbb0b996f7bed9b77/Login-API-Success.png\" alt=\"Login API Success\"></p>\n<p>Let's also test an erroneous Login flow by entering the credentials for a user that doesn't exist:</p>\n<p><img src=\"/5b4dd5cb3d6ed27fc288aff238ded14f/Login-Error.png\" alt=\"Login Error\"></p>\n<p>Great! Let's now tie all these individual pages together by setting up routing in your Svelte app.</p>\n<h2 id=\"setup-routes\" style=\"position:relative;\"><a href=\"#setup-routes\" aria-label=\"setup routes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Setup Routes</h2>\n<p>You'll use the <code>svelte-navigator</code> package that you previously installed to configure routing in your app.</p>\n<h3 id=\"add-routing\" style=\"position:relative;\"><a href=\"#add-routing\" aria-label=\"add routing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Routing</h3>\n<p>First, you'll define the routes for the Signup, Login, and Home pages inside your <code>App.svelte</code> file:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"html\" data-index=\"26\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  /** IMPORTS */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Router</span><span class=\"mtk1\">, </span><span class=\"mtk12\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Router</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;signup&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Signup</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;login&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Login</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">sdkoptions</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Home</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Router</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">main</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>If you visit <code>/login</code>, you should see the Login Page. Similarly, if you go to <code>/signup</code>, you should see the Signup Page.</p>\n<h3 id=\"programmatic-redirection\" style=\"position:relative;\"><a href=\"#programmatic-redirection\" aria-label=\"programmatic redirection permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Programmatic Redirection</h3>\n<p>Remember, you had a link to the Signup page at the bottom of the Login page and vice versa?</p>\n<p>Also, your login page doesn't redirect anywhere after you login successfully. In order to programmatically navigate to a specific page on completion of an action, you can use the <code>useNavigate</code> hook from the <code>svelte-navigator</code> library.</p>\n<p>To use this hook, import <code>useNavigate</code> and save its invoked reference inside a variable, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"27\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  import </span><span class=\"mtk4\">{</span><span class=\"mtk12\">useNavigate</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;; const navigate = useNavigate();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now call the <code>navigate()</code> function and pass the path of the page you wish to redirect to. So let's complete the <code>navigateToLogin</code> function inside your Signup component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"28\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">... const navigateToLogin=()=&gt;navigate(&#39;/login&#39;); ...</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Similarly, you can also complete the <code>navigateToSignup</code> function inside your Login component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"29\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span><span class=\"mtk1\">... const navigateToSignup=()=&gt;navigate(&#39;/signup&#39;) ...</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Finally, you'll also navigate to the Home page on a successful response from your Login API inside your Login component's <code>handleSubmit</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"30\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk11\">handleSubmit</span><span class=\"mtk1\">=(</span><span class=\"mtk12\">e</span><span class=\"mtk1\">)</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">fetch</span><span class=\"mtk1\">(</span><span class=\"mtk12\">endpoint</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        .</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk4\">=&gt;</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> \t\t\t\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span><span class=\"mtk12\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t\t\t...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk11\">navigate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;/&#39;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        })</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">       ...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;/</span><span class=\"mtk12\">script</span><span class=\"mtk1\">&gt;</span></span></code></pre>\n<p>Great! You can now navigate from your Login page to the Signup page and vice versa. You should also be automatically redirected to the Home page on a successful login.</p>\n<h3 id=\"add-protectedprivate-routes\" style=\"position:relative;\"><a href=\"#add-protectedprivate-routes\" aria-label=\"add protectedprivate routes permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Add Protected/Private Routes</h3>\n<p>If you try to visit the Home component by entering the path <code>/</code> in the URL, you'll be able to see the Home page regardless of your authenticated state. However, you must protect this route so that it's only accessible to authenticated users in your application.</p>\n<p>For this purpose, you have created a <code>RouteGuard.svelte</code> file inside your <code>routes</code> folder. It's a higher-order component that uses the <code>useNavigation</code> hook to programmatically redirect to the login page if an unauthenticated user visits the home page. You use the <code>user</code> object from your Svelte store to validate the authenticated state of a user.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"31\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">useNavigate</span><span class=\"mtk1\">, </span><span class=\"mtk12\">useLocation</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">user</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;../stores&quot;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const navigate = useNavigate();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    const location = useLocation();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    $: if (!$user) </span><span class=\"mtk4\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">navigate</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;/login&quot;</span><span class=\"mtk1\">, {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">state:</span><span class=\"mtk1\"> { </span><span class=\"mtk12\">from:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$location</span><span class=\"mtk1\">.</span><span class=\"mtk12\">pathname</span><span class=\"mtk1\"> },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">replace:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  {#</span><span class=\"mtk15\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">$user</span><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">slot</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  {/</span><span class=\"mtk15\">if</span><span class=\"mtk1\">}</span></span></code></pre>\n<p>You can then wrap another higher order Route component on top of the <code>RouteGuard</code> component inside the <code>PrivateRoutes.svelte</code> file, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"32\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import </span><span class=\"mtk4\">{</span><span class=\"mtk1\"> </span><span class=\"mtk12\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk4\">}</span><span class=\"mtk1\"> from &quot;svelte-navigator&quot;;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    import RouteGuard from &quot;./RouteGuard.svelte&quot;;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    export let path;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Route</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">path</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">params</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">location</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">navigate</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">RouteGuard</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">slot</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">params</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">location</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk4\">{</span><span class=\"mtk12\">navigate</span><span class=\"mtk4\">}</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">RouteGuard</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">Route</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now, all you need to do is use this <code>PrivateRoute</code> component to wrap your Home component instead of a regular Route component:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"33\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">PrivateRoute</span><span class=\"mtk1\"> </span><span class=\"mtk12\">path</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;/&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">let</span><span class=\"mtk1\">:</span><span class=\"mtk12\">location</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t\t</span><span class=\"mtk17\">&lt;</span><span class=\"mtk10\">Home</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">\t</span><span class=\"mtk17\">&lt;/</span><span class=\"mtk10\">PrivateRoute</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">...</span></span></code></pre>\n<p>And now you should be able to access the <code>/</code> route or the Home page only when you're authenticated:</p>\n<p><img src=\"/9abde471077ac6c2b3ec3795169cafac/Home-Component.png\" alt=\"Home Component\"></p>\n<h2 id=\"conclusion\" style=\"position:relative;\"><a href=\"#conclusion\" aria-label=\"conclusion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Conclusion</h2>\n<p>I hope I've shed some light on how to authenticate Svelte apps. You can do a lot from here, like adding <a href=\"https://kit.svelte.dev/\">Svelte Kit</a> to this project to simplify the routing system for your Svelte application.</p>\n<p>You can <a href=\"https://github.com/LoginRadius/engineering-blog-samples/tree/master/Svelte/SvelteAuthApp\">refer to the entire source code for this tutorial here</a>.</p>\n<p>You can also explore <a href=\"https://accounts.loginradius.com/auth.aspx?plan=developer&#x26;action=register\">LoginRadius</a> to add forgot password functionality or social signups with Facebook and Google.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n</style>","frontmatter":{"title":"How to Authenticate Svelte Apps","author":{"id":"Siddhant Varma","github":"FuzzySid","avatar":null},"date":"March 10, 2022","updated_date":null,"tags":["Authentication","Svelte","LoginRadius"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/5d69922aea9b04a51e9dbc994fd914cd/ee604/authenticate-svelte-apps.png","srcSet":"/static/5d69922aea9b04a51e9dbc994fd914cd/69585/authenticate-svelte-apps.png 200w,\n/static/5d69922aea9b04a51e9dbc994fd914cd/497c6/authenticate-svelte-apps.png 400w,\n/static/5d69922aea9b04a51e9dbc994fd914cd/ee604/authenticate-svelte-apps.png 800w,\n/static/5d69922aea9b04a51e9dbc994fd914cd/f3583/authenticate-svelte-apps.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}}},"fields":{"authorId":"Siddhant Varma","slug":"/engineering/guest-post/authenticating-svelte-apps/"}}},{"node":{"id":"0b124592-7ba2-5b7d-8359-1d53259f85c6","html":"<p>In this post, I’ll talk about how cookies compare to browser storage. You’ll understand why cookies came out, the problem they solve, and their limitations.</p>\n<p>Then you’ll explore what browser storage is, and dive deeper into local storage and session storage. You’ll look at their features, where they can be useful, and how to use them via JavaScript.</p>\n<p>You’ll then see how you can contrast the features, advantages, and disadvantages of each and also highlight specific use cases of each.</p>\n<p>You’ll also look at the best practices or approach to keep in mind while using each of them and the best place to store your JWT or auth tokens.</p>\n<hr>\n<p>How many times have you seen a popup on a website that says:</p>\n<blockquote>\n<p>This website is using cookies to store your information.</p>\n</blockquote>\n<p>I'm guessing so often that you've lost the count!</p>\n<p>Cookies have been used since time immemorial for storing session related information of a user. This allows websites to provide a unique and engaging experience to their users.</p>\n<p>However, cookies can be a bit difficult to use, have limited use-case, and have small data storing capacity. To combat this, modern browsers come with their own storage mechanisms like local storage and session storage.</p>\n<p>In this post, I’ll talk about these storage mechanisms. You'll understand how local storage, session storage, and cookies compare against one another and explore common use cases of each. By the end of this post, you'll know exactly when to use which.</p>\n<h2 id=\"a-brief-history-of-cookies\" style=\"position:relative;\"><a href=\"#a-brief-history-of-cookies\" aria-label=\"a brief history of cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>A Brief History of Cookies</h2>\n<p>Let's have a refresher on the history of cookies.</p>\n<p>Back in the day, websites used HTTP protocol which is <em>stateless</em>. This meant that they couldn't store user-related information like the user’s session id, the name of the user, etc., in the browser.</p>\n<p>As the web advanced and grew more popular, websites started storing user related information in the browser itself. This helped them differentiate what kind of user is interacting with their website and provide a personalized experience to the user.</p>\n<h3 id=\"enter-cookies\" style=\"position:relative;\"><a href=\"#enter-cookies\" aria-label=\"enter cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Enter Cookies</h3>\n<p>That's how cookies were born. They presented a mechanism to store lightweight client or server side data on the browser as key value pairs. They also had an expiry timestamp after which they were automatically deleted by the browser.</p>\n<p>Also, both browser and the server could set and retrieve cookies from a user’s browser. Moreover, these cookies were sent alongside each HTTP request automatically. This came in handy for server side websites at a time when single page applications weren't a thing. They could easily discern a user's information with each HTTP request that user made.</p>\n<h2 id=\"the-rise-of-browser-storage\" style=\"position:relative;\"><a href=\"#the-rise-of-browser-storage\" aria-label=\"the rise of browser storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Rise of Browser Storage</h2>\n<p>Where cookies solved a great problem, it had some limitations. First, they could only store data up to a few kbs. As client-side applications became more complex, there was a need to store more complex data in the browser.</p>\n<p>With the onset of HTML5, websites were introduced to browser storage APIs for storing client side information. These APIs were available on browser's window objects globally. Thus, any JavaScript running in the browser could easily access them. The major differentiator was that they had higher data storage capacity and could only be accessed by client-side JavaScript.</p>\n<p>Browsers rolled out two storage mechanisms — local storage and session storage. So let's explore and understand them in detail.</p>\n<h2 id=\"browsers-session-storage\" style=\"position:relative;\"><a href=\"#browsers-session-storage\" aria-label=\"browsers session storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Browser’s Session Storage</h2>\n<p>Let's first take a peek at where the session storage resides in the browser:</p>\n<ol>\n<li>\n<p>Open the developer tools in the browser and head over to the \"Application\" tab.</p>\n<p><img src=\"/6322f4dfe998ff0adaa9b8ee847c80ec/application-tab-screenshot.png\" alt=\"Application Tab Screenshot\"></p>\n</li>\n<li>\n<p>Under the storage section, you'll find a section named \"Session Storage\".</p>\n<p><img src=\"/d1d9b02e5a20551b8e2dd9cb909c8588/session-storage-tab-screenshot.png\" alt=\"Session Storage Section Screenshot\"></p>\n</li>\n<li>Click on it, and you'll be able to see the session storage for that website.</li>\n</ol>\n<p>There it is! Now, let's look at the features of browser's session storage.</p>\n<h3 id=\"storage-capacity\" style=\"position:relative;\"><a href=\"#storage-capacity\" aria-label=\"storage capacity permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Storage Capacity</h3>\n<p>Session storage can store data ranging between 5mb - 10mb. The exact amount of storage capacity varies as per each browser's implementation, but it's a lot more than 4kb of storage capacity cookies offer!</p>\n<h3 id=\"data-persistence\" style=\"position:relative;\"><a href=\"#data-persistence\" aria-label=\"data persistence permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Data Persistence</h3>\n<p>As the name suggests, session storage only persists the data as long as a browser tab is opened. This means that each time you open a new tab or a new browser window, a new session storage is created. So any data you store inside the session storage will automatically get deleted when you close that tab/window.</p>\n<h3 id=\"using-session-storage\" style=\"position:relative;\"><a href=\"#using-session-storage\" aria-label=\"using session storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using Session Storage</h3>\n<p>You can access the session storage in the <code>window</code> object:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk12\">sessionStorage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Storage {length: 0}</span></span></code></pre>\n<p>This would return the length of the session storage along with an object representing the data that's currently present inside. Since it's empty to begin with, the length is 0. Note that you may directly access the <code>sessionStorage</code> object as well.</p>\n<h4 id=\"adding-data\" style=\"position:relative;\"><a href=\"#adding-data\" aria-label=\"adding data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Adding Data</h4>\n<p>Let's add a key-value pair to the session storage using the <code>setItem</code> function available in the <code>sessionStorage</code> object:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;123&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>This will set a new item in the session storage with the key <code>id</code> and value <code>123</code>. If you simply invoke the <code>sessionStorage</code> object now:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//Storage {id: &#39;123&#39;, length: 1}</span></span></code></pre>\n<p>You now get your recently added data back!</p>\n<p>You'll also see this inside the session storage section of the browser's application tab:</p>\n<p><img src=\"/a536d2cf8d666e60cd9dc0936adf8090/session-storage-example-1.png\" alt=\"Session Storage Example\"></p>\n<h4 id=\"inserting-complex-json-data\" style=\"position:relative;\"><a href=\"#inserting-complex-json-data\" aria-label=\"inserting complex json data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Inserting Complex JSON Data</h4>\n<p>Let's add a bit more complex JSON object in the session storage that looks like this:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">const</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">_id:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;61c6c1df7cda7d370a9ef601&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">index:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">guid:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;13672f0e-f693-4704-a6f9-839ff36e8960&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">isActive:</span><span class=\"mtk1\"> </span><span class=\"mtk4\">true</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">balance:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;$3,602.49&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">picture:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;http://placehold.it/32x32&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">age:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">25</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">friends:</span><span class=\"mtk1\"> [</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Adkins Coleman&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">1</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Howe Douglas&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">id:</span><span class=\"mtk1\"> </span><span class=\"mtk7\">2</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk12\">name:</span><span class=\"mtk1\"> </span><span class=\"mtk8\">&quot;Becky Velez&quot;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    },</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  ],</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>You'll first need to <em>stringify</em> it since the value against a key can only be a string. Then, you'll store it inside the session storage using the <code>setItem</code> method:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user_data&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">stringify</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">))</span></span></code></pre>\n<p>It should now appear inside the session storage of the browser's application tab:</p>\n<p><img src=\"/841be8af005e05920607f66cddfbf745/session-storage-example-2.png\" alt=\"Complex JSON Data in Session Storage Example\"></p>\n<p>Awesome! Let's take a look at retrieving this data.</p>\n<h4 id=\"retrieving-data\" style=\"position:relative;\"><a href=\"#retrieving-data\" aria-label=\"retrieving data permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Retrieving Data</h4>\n<p>You can use the <code>getItem()</code> function to retrieve a value stored against a key from the session storage by specifying the key as the first parameter in the function.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//&#39;123&#39;</span></span></code></pre>\n<p>If you're retrieving an object, you'll need to use <code>JSON.parse</code> first to convert the string into a JavaScript object:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk10\">JSON</span><span class=\"mtk1\">.</span><span class=\"mtk11\">parse</span><span class=\"mtk1\">(</span><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;user_data&quot;</span><span class=\"mtk1\">))</span></span></code></pre>\n<h3 id=\"usecase\" style=\"position:relative;\"><a href=\"#usecase\" aria-label=\"usecase permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Usecase</h3>\n<p>Since data in session storage persists only across a browser tab, there are some unique usecases for session storage.</p>\n<h4 id=\"booking-applications\" style=\"position:relative;\"><a href=\"#booking-applications\" aria-label=\"booking applications permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Booking Applications</h4>\n<p>Session storage can be used in multi-step processes that must be performed in a single instance. This includes booking flights, hotels, movie tickets, train reservations etc. You can store the details of the previous steps in the browser's session storage to prepopulate those forms or inputs.</p>\n<p>Since these are critical activities that must be performed in a single go, the data will automatically get deleted when the user jumps to a new tab or a new browser window.</p>\n<h4 id=\"prompting-loginsignups-to-a-user\" style=\"position:relative;\"><a href=\"#prompting-loginsignups-to-a-user\" aria-label=\"prompting loginsignups to a user permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Prompting Login/Signups to a User</h4>\n<p>Blogging websites, newsletters, tutorial websites etc., have tons of visitors who read through the content without creating an account. In such scenarios, you can subtly prompt the user every time they visit the website to create an account. You can track the session of each user in the session storage.</p>\n<p>Every time a user reads a blog post or an article on a different tab, you can ask them to create an account. This could be a great way to offer a non-blocking experience for your users whilst effectively converting them to a signed-up user for your website.</p>\n<h2 id=\"browsers-local-storage\" style=\"position:relative;\"><a href=\"#browsers-local-storage\" aria-label=\"browsers local storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Browser’s Local Storage</h2>\n<p>Under the application tab where session storage resides, you'll find a section called local storage right underneath it.</p>\n<p><img src=\"/6b873e80fdedd356fdc792765cbed627/local-storage-tab-screenshot.png\" alt=\"Local Storage Tab Screenshot\"></p>\n<p>That's where you can see everything you store inside the local storage of your browser. Local storage works, appears, and similar to session storage. For instance, just like Session storage, local storage can also store data ranging between 5mb - 10mb depending upon a browser's implementation.</p>\n<h3 id=\"data-persistence-1\" style=\"position:relative;\"><a href=\"#data-persistence-1\" aria-label=\"data persistence 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Data Persistence</h3>\n<p>Unlike session storage where data is automatically deleted when a browser tab or window is closed, data in local storage has no default expiry. It's only deleted if you manually delete that data from the local storage either directly, via browser settings, or through your JavaScript code.</p>\n<p>That means that data in a local storage persists even after a particular tab or browser window is closed.</p>\n<h3 id=\"using-local-storage\" style=\"position:relative;\"><a href=\"#using-local-storage\" aria-label=\"using local storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Using Local Storage</h3>\n<p>You can add and retrieve data from local storage in the same way you perform those operations with session storage. The only change is now you'll have to use the <code>localStorage</code> object to perform these operations instead.</p>\n<p>For instance, you can add an item to the <code>localStorage</code>, as follows:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;123&quot;</span><span class=\"mtk1\">)</span></span></code></pre>\n<p>Consequently, you can retrieve an item using the <code>getItem()</code> function:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;id&quot;</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//&#39;123&#39;</span></span></code></pre>\n<h3 id=\"usecase-1\" style=\"position:relative;\"><a href=\"#usecase-1\" aria-label=\"usecase 1 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Usecase</h3>\n<p>Local storage has a number of uses due to the fact that data inside it has no default expiry. Think about all those scenarios where you want to store some global data that's accessed often in your application.</p>\n<h4 id=\"generic\" style=\"position:relative;\"><a href=\"#generic\" aria-label=\"generic permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Generic</h4>\n<p>For instance, your user's email id, username, full-name, etc. All these data are widely used throughout different pages of your application. Storing this data inside the local storage will help you prevent unwanted API calls to the server to fetch this data. Also, since this data isn't normally changed often, the chances of having inconsistent data across the browser and the server is quite low.</p>\n<h4 id=\"application-specific\" style=\"position:relative;\"><a href=\"#application-specific\" aria-label=\"application specific permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Application Specific</h4>\n<p>You can also use it to store application specific data that is immutable throughout a login session of a user. For instance, if you have an ecommerce site, you can store the preferred payment option of the user, default delivery addresses, etc. You can also store user preferences such as the theme a user prefers for your website (dark or light mode).</p>\n<h2 id=\"cookies-vs-browser-storage\" style=\"position:relative;\"><a href=\"#cookies-vs-browser-storage\" aria-label=\"cookies vs browser storage permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies vs. Browser Storage</h2>\n<p>Now that you've understand how browser storage works, you can compare them effectively against cookies. However, let's first look at their similarities.</p>\n<h3 id=\"similarities\" style=\"position:relative;\"><a href=\"#similarities\" aria-label=\"similarities permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Similarities</h3>\n<p>Remember in the beginning I asked you how many times you've seen that cookies popup? Most of these popups also have an option where you can choose not to accept these cookies.</p>\n<p>In other words, cookies are <em>blockable</em> by users and so is browser storage. Users can choose not to allow their data to be stored via any of these mechanisms — and hence, your application should never completely rely on these storage mechanisms.</p>\n<p>Both cookies and browser storage store key-value pairs as strings and are well supported in all modern browsers. The data inside this can also be easily edited by the user.</p>\n<h3 id=\"differences\" style=\"position:relative;\"><a href=\"#differences\" aria-label=\"differences permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Differences</h3>\n<p>You know that browser storage has a greater storage capacity than cookies. Hence, browser storage is always a better choice than cookies to store large client-side data.</p>\n<p>However, since session storage and local storage have different data persistence, you should carefully choose either of them depending on how long you want the data to persist.</p>\n<p>Cookies allow you to automatically set a TTL or expiry time; are transferred with every HTTP request to the server; and, can also be accessed by the server. These features are missing in browser storage. Which brings us to the question — where would cookies be actually more useful than browser storage?</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 75.07692307692308%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAA7EAAAOxAGVKw4bAAADQklEQVQ4y3WT+29TZRjH+8f4n6i/0I0YoS2bISEhuhB/gTDjD2IEXaJkuIyhXNYYZWO3tsLYkKAE4wUIY4LANrfgtpb19HJOe3pZ23Pv+fi0ndNEeZNv3tt5P8/3eZ/zBqz8FC+TmZukWYzh5cdw8hNY6hToHXmFzr6tTeOV4riFmfaZwMtALbnycfLpRUZmEyw+lsOZMeaunyc6c4Hlhcs0SzMU16Is3zzJxqNz7YD/CzSykyBRVxdH+HLwEB8Pn2Dj+TS15Dcc/egUrxw8wnh0EGpxVuY+5N6Zg9ydeo96ZoKAmZsQN+P/0pU2sKnHSS6NMvDJERLj70M1QTk9xRdDpzj29mFuzJ4T4FWUJ+dZvHyU5C+nMSWjgKUmsAo3sLT5Tl+Y76SdHcNVv6KSvEBDiWLnolhbozQ2L1LbvISZuoSdiuKsj2I+l/G67GeuEHCrC7RaNqtQLpVk5GLpd3C0Seqrh8g/DJF5EKb4JIJ9vxclFkabDbOVCGN8KxrqJjUQxPi8C2d5RByW7lOrm9Trdba3t7FtS6BNfEeFF+9gre2nvhLB2zgAC724tyLUvwtj/SDzuRAMd2GcCeINBXGWBGjq99BLFXS9KNIxTaPt2HcrsNXH9tI+Co/CHeDDXpxbB9CuhTC+l/l8GM52UzwtsKEdhy1gUa9Iyllc123Dmn4LWGoDbXFYW46I2x78B71wu4fyXJjmnR5x2AGWBej+DWwUfqVQKKFpqkhDUdKomi5UcfiiD+OP/VSeCjDVAfqSqn49hLcD9IfF4Wd7/nFoiMNKtU6lUqZarVIuC1wC6Npm+w6b6yHMVUkvveNQQI2bEuCnHYcj3dQGg+273HWoqgU0NU8+l5XitArjYRt5nI0+qfK+dpW3pTAsvoU+G0GJhyjOy1xUGuwi92kQVWS1imKVFzBMaBhOW65Hp/l1/ORhNn/ew+ptcbHyplQ5RGp8L2tfd7MxsRf/6htUBl7nzw9eRT35Gs6zswSc0o/g5PDtNNgKTWsLz1TwGqs00ydAOQaZfnzlON6z4/Cb6HE//N6Pd1f2rr27K1t+8M7Tk1fxH7WeYT6GkYuLYjKOY6oyVmO7MjVZK8paodOb6jR/AZKN6VZCYGrbAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Comparison Table of Local Storage Session Storage and Cookies\"\n        title=\"Comparison Table of Local Storage Session Storage and Cookies\"\n        src=\"/static/a6522d000e0137d5fdf82fd370646d12/e5715/comparison-table.png\"\n        srcset=\"/static/a6522d000e0137d5fdf82fd370646d12/a6d36/comparison-table.png 650w,\n/static/a6522d000e0137d5fdf82fd370646d12/e5715/comparison-table.png 768w,\n/static/a6522d000e0137d5fdf82fd370646d12/2bef9/comparison-table.png 1024w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>The answer is server side data! If you've dealt with authentication before, you know that at some point you need to store the authentication token or JWT of a user somewhere where it's easily accessible. That's where cookies are helpful. But why can't we use or why shouldn't we use browser storage here?</p>\n<h2 id=\"storing-your-jwtauth-token\" style=\"position:relative;\"><a href=\"#storing-your-jwtauth-token\" aria-label=\"storing your jwtauth token permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Storing Your JWT/Auth Token</h2>\n<p>Data such as JWT or Auth token should not be stored in browser storage because they can be accessed by any client side JavaScript running in the browser. This means that if your application somehow leaves an XSS vulnerability, your user's authentication token could be easily leaked to the attacker.</p>\n<p>The attacker could then make false requests, modify your user's data in the database, and do a lot of damage for your application as well as users. Hence, it's always best to store JWTs in http only cookies. Http only cookies are special cookies that cannot be accessed by client side JavaScript. This way they're secure against XSS attacks.</p>\n<p>Also, authentication token is often refreshed on expiry and one can use cookies TTL easily to manage that. For simpler cases, one can also store JWT inside regular cookies by setting a TTL.</p>\n<p>But all in all, authentication itself can be a tricky subject. If you're looking for a no-code identity platform that can seamlessly handle authentication for your application, consider using <a href=\"https://www.loginradius.com/\">LoginRadius</a>.</p>\n<h2 id=\"wrapping-it-up\" style=\"position:relative;\"><a href=\"#wrapping-it-up\" aria-label=\"wrapping it up permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Wrapping it Up</h2>\n<p>Now that you understand how powerful browser storage is, don't feel shy to use it in your applications. Use cookies for server side data where you need a TTL, session storage for specific use cases discussed above, and local storage to manage global data in your application.</p>\n<p>However, avoid the pattern where your single page application directly interacts with the local storage. For instance, if you're using React with Redux to manage the state in your application, let your reducers take control over what goes and comes out of local storage. Your React components should be abstracted from using local storage directly.</p>\n<p>Finally, since local storage data has no default expiry, be vary of when you're clearing this data to avoid data inconsistency between your frontend and backend.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"title":"Local Storage vs. Session Storage vs. Cookies","author":{"id":"Siddhant Varma","github":"FuzzySid","avatar":null},"date":"January 12, 2022","updated_date":null,"tags":["Cookie","Browser Storage","Authentication","JWT"],"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/05c0a6d7a4539d8f04241b6ddf720a52/ee604/blog-banner.png","srcSet":"/static/05c0a6d7a4539d8f04241b6ddf720a52/69585/blog-banner.png 200w,\n/static/05c0a6d7a4539d8f04241b6ddf720a52/497c6/blog-banner.png 400w,\n/static/05c0a6d7a4539d8f04241b6ddf720a52/ee604/blog-banner.png 800w,\n/static/05c0a6d7a4539d8f04241b6ddf720a52/f3583/blog-banner.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}}},"fields":{"authorId":"Siddhant Varma","slug":"/engineering/guest-post/local-storage-vs-session-storage-vs-cookies/"}}}]},"authorYaml":{"id":"Siddhant Varma","bio":"He is a full-stack JavaScript engineer who loves building pixel perfect UIs and engineering tech products. He loves creating technical content for developers and has worked as a frontend engineer for many startups.","github":"FuzzySid","stackoverflow":null,"linkedin":"siddhantvarma99","medium":null,"twitter":null,"avatar":null}},"pageContext":{"id":"Siddhant Varma","__params":{"id":"siddhant-varma"}}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}