{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/153","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"As a front-end developer, if you haven't heard about Promise in Javascript, well ... At least you have heard about it now! And it is truly…","fields":{"slug":"/engineering/how-to-promise/"},"html":"<p>As a front-end developer, if you haven't heard about Promise in Javascript, well ...<br>\nAt least you have heard about it now! And it is truly amazing.</p>\n<p>Promise is a the standard way of handling asynchronous operations, such as calling APIs. It is comprehensive but elegant, espeically with a series of Async operations and handling the errors from them.<br>\nIt has been widely supported by mordern browsers. But of course IE is not one of the modern ones, so do not forget to find a promise-polyfill for your IE users.</p>\n<p><a href=\"http://caniuse.com/#feat=promises\">Can I use Promise</a><br>\n<a href=\"https://github.com/taylorhakes/promise-polyfill\">Polyfill for IE</a></p>\n<p>In this blog I will cover the basic usages for Promise, let's get started.<br>\nA promise function would look like this</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=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">resolve</span><span class=\"mtk1\">, </span><span class=\"mtk12\">reject</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">data</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">asyncCall</span><span class=\"mtk1\">(); </span><span class=\"mtk3\">// could be API calls</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// success</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=\"mtk11\">reject</span><span class=\"mtk1\">(</span><span class=\"mtk12\">data</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// fail</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>First we need to declare it is a `new` Promise, inside you can put your async calls and let promise know how to deal with the response with `resolve` and `reject`. You can treat `resolve` and `reject` as two callback functions, `resolve` when you are confirmed that you have got what you expect, and reject if anything bad happened.</p>\n<p>Here is a brief example, <a href=\"https://jsfiddle.net/02fj0cnv/\">Fiddle it here</a></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=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk11\">aync1</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</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 class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">resolve</span><span class=\"mtk1\">, </span><span class=\"mtk12\">reject</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// Wait 1s and alert</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">setTimeout</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk11\">resolve</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Hello Promise&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">1000</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=\"mtk11\">aync1</span><span class=\"mtk1\">().</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">resp</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">alert</span><span class=\"mtk1\">(</span><span class=\"mtk12\">resp</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p>If something is going wrong, you want to catch and handle it, <a href=\"https://jsfiddle.net/j26ka27w/\">Fiddle it here.</a></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=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk11\">aync2</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</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 class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Promise</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">resolve</span><span class=\"mtk1\">, </span><span class=\"mtk12\">reject</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk3\">// Wait 2s and alert</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk11\">setTimeout</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk3\">// pretend we got something wrong.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk11\">reject</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;error&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        }, </span><span class=\"mtk7\">1000</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=\"mtk11\">aync2</span><span class=\"mtk1\">().</span><span class=\"mtk11\">then</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">resp</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">alert</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;This will not be called&quot;</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=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">alert</span><span class=\"mtk1\">(</span><span class=\"mtk12\">err</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span></code></pre>\n<p>Here I have quickly demonstrated the basic usage of Promise, you may think \"Oh callbacks can do the same thing as well\". You are not wrong, but in next blog I will show the real power of Promise, thanks for reading.</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 .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"January 05, 2016","updated_date":null,"description":null,"title":"How to Promise","tags":["JavaScript","Promise"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/05707517353767f5f43e5a285bd216f7/630fb/promise-300x300.png","srcSet":"/static/05707517353767f5f43e5a285bd216f7/69585/promise-300x300.png 200w,\n/static/05707517353767f5f43e5a285bd216f7/630fb/promise-300x300.png 300w","sizes":"(max-width: 300px) 100vw, 300px"}}},"author":{"id":"Solomon Yu","github":null,"avatar":null}}}},{"node":{"excerpt":"When you work for a tech company in an office capacity, it feels like everyone around you is speaking another language. Which they are, most…","fields":{"slug":"/engineering/learning-how-to-code/"},"html":"<p>When you work for a tech company in an office capacity, it feels like everyone around you is speaking another language. Which they are, most of their work exists in coding language. To feel more relevant, I signed up on <a href=\"https://www.codecademy.com/\">codecademy.com</a> and started working on their beginner courses (for free! you should try it!).</p>\n<p>Here are some things I have learned about coding:</p>\n<ol>\n<li>There are many different ways to code. Not every website or app is made using the same terms or patterns, programmers and developers have options for how they want to format their content, and how they want to communicate with their computer.</li>\n<li>Coding is more about seeing what you want in your head than about math. Deciding exactly what you want and communicating it is the big struggle. Having your website/app be capable of computing things is optional, but the layout is mandatory. (Not to mention the most noticeable aspect of your site).</li>\n<li>Code is like a language. The words and punctuation must be learned for each coding language. Though they can be linked to English words (like “p” for a new paragraph), you have to be able to pull them up quick in your mind. As with any language, repetition is key to recognition.</li>\n<li>You don’t have to start from scratch (but you can). There are frameworks available, like Bootstrap, which have some existing templates you can draw from. This helps you when you are constructing your site, so that you can set up your layout quicker, and have more time to work on your content.</li>\n<li>\n<p>There are some areas of knowledge that you don’t need to memorize, but having an understanding of what they do will be helpful in coding:</p>\n<ol>\n<li>The hexi-decimal system (and how it relates to color)</li>\n<li>Binary code</li>\n<li>ASCII</li>\n</ol>\n</li>\n<li>Once you learn some of the basics, websites you see every day will start to seem simpler. You will be able to pick out some of their elements, and if you look at their bare code, you will recognize how they come together.</li>\n<li>The world of coders is large and easy to access. If you have questions, there is someone online who is willing and eager to answer. This is not a skill that anyone was born with, and due to new languages etc, everyone is still learning. </li>\n</ol>\n<p>I hope that this list has contributed to your knowledge, and would encourage you to check online for available resources to expand (or begin) your abilities in coding.</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</style>","frontmatter":{"date":"December 29, 2015","updated_date":null,"description":null,"title":"Learning How to Code","tags":["Learning","Coding","Learning resources"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/26a66e05ab78493dc6d84d3afe0d8a82/630fb/begin-code-300x300.png","srcSet":"/static/26a66e05ab78493dc6d84d3afe0d8a82/69585/begin-code-300x300.png 200w,\n/static/26a66e05ab78493dc6d84d3afe0d8a82/630fb/begin-code-300x300.png 300w","sizes":"(max-width: 300px) 100vw, 300px"}}},"author":{"id":"Carling","github":null,"avatar":null}}}},{"node":{"excerpt":"Delete A Node Click to View the Orginal Question To remove the given node，which means whoever is asking the value for this node should get…","fields":{"slug":"/engineering/delete-a-node-is-same-tree-move-zeroes/"},"html":"<h3 id=\"delete-a-node\" style=\"position:relative;\"><a href=\"#delete-a-node\" aria-label=\"delete a node 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>Delete A Node</h3>\n<p><a href=\"https://leetcode.com/problems/delete-node-in-a-linked-list/\">Click to View the Orginal Question</a></p>\n<p>To remove the given node，which means whoever is asking the value for this node should get the value of the next node. Plus, the next node of this removing one should be the next next node.</p>\n<p>In diagram, with the following node list, we want to remove node 2.</p>\n<p>1 -> 2 -> 3 -> 4</p>\n<p>We update original Node 2 to Node 3 and skip the original Node 3, which gives out the list after removing node 2.</p>\n<p>1 -> 3 ------> 4</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=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* Definition for singly-linked list.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* function ListNode(val) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* this.val = val;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* this.next = null;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">*/</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">{ListNode}</span><span class=\"mtk3\"> </span><span class=\"mtk12\">node</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* </span><span class=\"mtk4\">@return</span><span class=\"mtk3\"> </span><span class=\"mtk10\">{void}</span><span class=\"mtk3\"> Do not return anything, modify node in-place instead.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">*/</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk11\">deleteNode</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">node</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">node</span><span class=\"mtk1\">.</span><span class=\"mtk12\">val</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">node</span><span class=\"mtk1\">.</span><span class=\"mtk12\">next</span><span class=\"mtk1\">.</span><span class=\"mtk12\">val</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">node</span><span class=\"mtk1\">.</span><span class=\"mtk12\">next</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">node</span><span class=\"mtk1\">.</span><span class=\"mtk12\">next</span><span class=\"mtk1\">.</span><span class=\"mtk12\">next</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<h3 id=\"is-same-tree\" style=\"position:relative;\"><a href=\"#is-same-tree\" aria-label=\"is same tree 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>Is Same Tree</h3>\n<p><a href=\"https://leetcode.com/problems/same-tree/\">Click to View the Original Question</a></p>\n<p><strong>Note</strong>: My solution is not efficient enough based on the performance, but I think it's fairly clean.</p>\n<p>I use recursion to solve the problem, first to define the basic cases, and recursively loop through both trees from left to right. If it hits one <code>false</code>, the whole result will be <code>false</code>.</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=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* Definition for a binary tree node.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* function TreeNode(val) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* this.val = val;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* this.left = this.right = null;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">*/</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">{TreeNode}</span><span class=\"mtk3\"> </span><span class=\"mtk12\">p</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">{TreeNode}</span><span class=\"mtk3\"> </span><span class=\"mtk12\">q</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* </span><span class=\"mtk4\">@return</span><span class=\"mtk3\"> </span><span class=\"mtk10\">{boolean}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">*/</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk11\">isSameTree</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">p</span><span class=\"mtk1\">, </span><span class=\"mtk12\">q</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\">p</span><span class=\"mtk1\"> === </span><span class=\"mtk12\">q</span><span class=\"mtk1\"> ) </span><span class=\"mtk15\">return</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=\"mtk15\">if</span><span class=\"mtk1\">(!</span><span class=\"mtk12\">p</span><span class=\"mtk1\"> || !</span><span class=\"mtk12\">q</span><span class=\"mtk1\"> || </span><span class=\"mtk12\">p</span><span class=\"mtk1\">.</span><span class=\"mtk12\">val</span><span class=\"mtk1\"> !== </span><span class=\"mtk12\">q</span><span class=\"mtk1\">.</span><span class=\"mtk12\">val</span><span class=\"mtk1\">) </span><span class=\"mtk15\">return</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=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk11\">isSameTree</span><span class=\"mtk1\">(</span><span class=\"mtk12\">p</span><span class=\"mtk1\">.</span><span class=\"mtk12\">left</span><span class=\"mtk1\">, </span><span class=\"mtk12\">q</span><span class=\"mtk1\">.</span><span class=\"mtk12\">left</span><span class=\"mtk1\">) ? </span><span class=\"mtk11\">isSameTree</span><span class=\"mtk1\">(</span><span class=\"mtk12\">p</span><span class=\"mtk1\">.</span><span class=\"mtk12\">right</span><span class=\"mtk1\">, </span><span class=\"mtk12\">q</span><span class=\"mtk1\">.</span><span class=\"mtk12\">right</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<h3 id=\"move-zeroes\" style=\"position:relative;\"><a href=\"#move-zeroes\" aria-label=\"move zeroes 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>Move Zeroes</h3>\n<p><a href=\"https://leetcode.com/problems/move-zeroes/\">Click to View the Original Question</a></p>\n<p>Here I have create two indices one called <code>z</code> to index the position for zeroes, another is <code>i</code> to loop through the nums array. They both increment by one when they see a non-zero value, but when it is zero, z stays at position and get ready to swap the position with next non-zero value <code>i</code> meets. By keep doing it, it will fill a consecutive row of zeroes, till the end.</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=\"mtk1\">&lt;!--</span><span class=\"mtk3\">/**</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">{number[]}</span><span class=\"mtk3\"> </span><span class=\"mtk12\">nums</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">* </span><span class=\"mtk4\">@return</span><span class=\"mtk3\"> </span><span class=\"mtk10\">{void}</span><span class=\"mtk3\"> Do not return anything, modify nums in-place instead.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">*/</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk11\">moveZeroes</span><span class=\"mtk1\"> = </span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">nums</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">z</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=\"mtk15\">for</span><span class=\"mtk1\">(</span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">0</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\"> </span></span></code></pre>\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 .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"December 22, 2015","updated_date":null,"description":null,"title":"Delete a Node, Is Same Tree, Move Zeroes","tags":["Data Structure","JavaScript","Linked List"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/4dbfe94040c20cde6c3a395142bd3009/630fb/code-js-300x300.png","srcSet":"/static/4dbfe94040c20cde6c3a395142bd3009/69585/code-js-300x300.png 200w,\n/static/4dbfe94040c20cde6c3a395142bd3009/630fb/code-js-300x300.png 300w","sizes":"(max-width: 300px) 100vw, 300px"}}},"author":{"id":"Lucius Yu","github":null,"avatar":null}}}},{"node":{"excerpt":"What's one thing virtually every website has? If you said navigation (you did) you're absolutely right! Go ahead and enjoy that wonderful…","fields":{"slug":"/engineering/csshtml-animated-dropdown-navigation/"},"html":"<p>What's one thing virtually every website has? If you said navigation (you did) you're absolutely right! Go ahead and enjoy that wonderful feeling of being right for a moment... and now that we're feeling like a champ, let's get to it.</p>\n<p>Navigation buttons, depending on your site of course, are likely going to be some of the most commonly used items on your web site. Typically they're found near the top so people can quickly and easily... well navigate of course! With this in mind it's worth it to make sure your navigation is both visually appealing and provides an enjoyable user experience.</p>\n<p>A common featured for navigation menus is the drop down functionality for displaying sub options. This can be achieved through Javascript if you really feel like it (you don't), but why bother with that when CSS3 offers a much more elegant solution!</p>\n<p>First we start out building a simple un-ordered list, and give it some list items each of which contain a link that point nowhere in particular.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 630px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 67.30158730158729%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABIUlEQVQoz42R4U7FIAyF9xaupUBp2dhYFnO3GX/4/u9l0Ru9U3OvDSGHhI9zWroyzdtUXrMkcomoB2cLAQGwtx3RVN9ftTtXV2tl5pV5yTLluA6kCYh9ZMoJYkTHXhglYQwOz9XNtS7j+JKF2TPjIKAJXfSB2ysxNJ0iGv8HvKzrolpHSYWLwqCOiCwzfsaGm9iAP+F928h7U7NI4mh9D5rGsWTV6Ok3cIKP/YghAMCsatmd0JB1LCXnHL2/y2K3bVtoMFYRMWdrVZKR7RQC3ocvl0v4uDTdwC2EqiZ+AB/HYfBTD7MxKVLrWa3nxlqih7ANqkiyeXvnkJC+yrkHztu+P8/z2zi4Ntur033Db1izWmx/9vgvbGPy9iXwz/unegd3qFlcbCazsAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen1\"\n        title=\"dropdownscreen1\"\n        src=\"/static/4d73eddb787ac320f85c2e9a1d005f82/f058b/dropdownScreen1.png\"\n        srcset=\"/static/4d73eddb787ac320f85c2e9a1d005f82/f058b/dropdownScreen1.png 630w\"\n        sizes=\"(max-width: 630px) 100vw, 630px\"\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>By the way, if you're on Sublime Text there's a great shortcut for making lists: ul>li+li+li+li and then \"Tab\" creates an un-ordered list with 4 list item tags inside of it. For more excellent Sublime tips check out my amigo Lucius' <a href=\"/beginners-guide-for-sublime-text/\">blog post</a> on the topic.</p>\n<p>Now that we've got the bare bones, let's give this skeleton a spine. We're now going to put another ul inside of those list items, and once again more list items inside of those lists which contain, you guessed it, links to nowhere.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 556px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 119.78417266187051%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAYCAIAAAB1KUohAAAACXBIWXMAAAsTAAALEwEAmpwYAAACkUlEQVQ4y5VUCW7jMAz0KxrdB0VJvh0njuO47e7/f7W0e6Bo0l0sEQSwKB4zHKqo66aryt8pVNa0RltjuRBSSrEbF99NfrGiadsIMHiXrfHeZqucURRLPiWFUttP7h9qOxQfaTcruq5z3pfOnZ2FCC2qJssKmULrUFeRZeQKtA26Rp6Qg1ef7RRVXbc5P0fQ6JzlwXPvpVLyW7dbwPczUYzjiABoTaqwRI2egaVzxZjk94i/BV+vs3PuwDhBK513ZdCVO3VpmZtxqKkb/nOO4nK5eO8F54xv16oI56Ysj9ie7DqP0+U6HYdTmZOz7C5LMU2T944cWuscIDlnqGcpGLWutDaGhme0VlI+qLwHe8aYt7bDIJxWTsbgAwRKqqUkF/uh9WKeZwomLxM8aKItQBP6FpYZp7HKMVJVu1fmjzF/sPLEWPRuqSocU+zdeplu68vLMs9t3QS4r/5WeQtWSiWACjxoI62SRoAj+fgYI5B+jLkHXSzLQjcOjNGNY0LptbAigsdAmMFbw9jhaYct/tI2uR0VrzH16TTiuuD13LbNpnywlvTOH4nk+kYYif/AebBmTtn2GFq7nE/z9XabL5embhB+IGzH/BZfgu8RCTpke+y7vh8GWp2cavDibtTFdN5FQnM2tovotaYlIIhPB35g/1D3+5x3hakGwCSvs+mreDrWTZPR2jc6+A+L8Y6Z3KSEnGDoymYMx8mul2E8nYe27WIkLh5oe13XT8JoJFRqLSs/ZhzgZbmuz6+/ntdb35FqHlS+3W40i/fKSmXwHaIvAUp7pEF1/XEY2pRK7x48BsS2s9ujR3qqQyAlbXn4x99fKSuu85xi7GgZ99zsn8/H1+DzeWqq6jUh7pRI8R/2B+Ses911k0eEAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen2\"\n        title=\"dropdownscreen2\"\n        src=\"/static/8f8aecc68ec3595359bda468281df807/96638/dropdownScreen2.png\"\n        srcset=\"/static/8f8aecc68ec3595359bda468281df807/96638/dropdownScreen2.png 556w\"\n        sizes=\"(max-width: 556px) 100vw, 556px\"\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>That's all the HTML we have to write for this example, so now we move on to the CSS.</p>\n<p>The first few things on the ul's and links are just to remove some default styles that I don't care for.</p>\n<p>The first actually relevant style is the inline-block display property on the list items to make them spread out horizontally. If you're unfamiliar with using inline-block for positioning I highly recommend reading up on it because it's an awesome alternative to floats or sometimes even flex-box. Next up we give these list items a relative position, so that the later absolutely positioned sub menu will use this as a reference point.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 403px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 44.91315136476427%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8ElEQVQoz4WRy3LDIAxF/RcJ6IGweRibAIntZrrI//9WyUyXraPR9s45uhpCCOuykBslRI0MLMAGjAViMIhM+v8Z5nmutYoI+wWnhH7FkNFnsg4Xa5KDk3CM8ZYzeyfBI4AC7KtBaQa4KnVVH8iPxwMQaT349pTUYswQxJRAhPp03uFSChNR2rm+bCrNWer8y1V3YzgNd+1Wq3UOppGsAL5xoJTuwpdP2r2t4zhABHKT+jRhBS+YHaaJ13E6L+x+v+/b1mGUNm4vLt+cbtwa1rLGcQ8TMyv1N3/Y9+3rOH5f5RK6hazB2cJs2dve/snZPxwTQeyg3DYnAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen3\"\n        title=\"dropdownscreen3\"\n        src=\"/static/4d82753330425342c1f42b96cb22083d/045fd/dropdownScreen3.png\"\n        srcset=\"/static/4d82753330425342c1f42b96cb22083d/045fd/dropdownScreen3.png 403w\"\n        sizes=\"(max-width: 403px) 100vw, 403px\"\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>To quote every MTV cribs star ever, here's where the magic happens. We put a max-height (that is at least as tall as all of the list items on the sub menu) and a height of auto on the sub menu. Note the ul li:hover, meaning these styles only apply when the first level of list items are hovered over. This might seem weird now, but it'll hopefully make sense with the styles we make use of in a bit.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 509px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 77.99607072691552%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAABoklEQVQoz41TCY7iMBDML+Lbbt+E3CGBJAMz/3/VNqyEdnZXA21L7avULle5+Nh3CJ7Vg5pPchr9MUx9dHUUnLNXUSzLYsFIX0lf8+BVBEMZo9jYG+B5sTFwH6R1gjFNmeFcCM7eAV9vN9BKNKsev8ZD+mrcFJ0S8q3K5/PZOSdtFD6qDLIFpiUpyVuVz8g5eO6daCp5TJA8d1qCxj3+eLMfCBTrtuG1abXk3K5I3koGkitBCKGPwETIc/aNTbFtu9EK2stxvOzJjykqbYw2AGCdA2OCUjg25nc338Af16u1Frerqsp1u6/bclq6vhuGcd+v8zjeUjhNp3meu66fpklK+axfrOtqjeah4XmUhynXyVVBCCm4wHNSoGqoHI4xc1zgf5jnDvY5qRhExu5YNCoYJFg+2LK7X9iT7d+cL+sFrBWHXvWLams1HCEmy3nSSgtBX9rzoTOaLFMIFLwwNoPpUvTGEPoT/H5t/Bj8cFRdXTV+aJLVqiSk/EeY/4Bvn5/eggy1iK2LOXSVcRZh75i7GPoBpWKUMPQkJWVJXhZ8xi9mK3cU9EyKPQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"dropdownscreen4\"\n        title=\"dropdownscreen4\"\n        src=\"/static/1d5e9e4972575f8d4caad87fa0fc90d1/71554/dropdownScreen4.png\"\n        srcset=\"/static/1d5e9e4972575f8d4caad87fa0fc90d1/71554/dropdownScreen4.png 509w\"\n        sizes=\"(max-width: 509px) 100vw, 509px\"\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>Next up we just give the links some padding, which is highly preferable to giving the list item padding because then you can end up with a small hitbox for the actual link and a bunch of dead space around it. Only other thing to note here is the display block on the link which is required for the absolute positioning used later.</p>\n<p>The .sub-menu styles are pretty basic, just give it a position of absolute and then top: 100%, left: 0 and width: 100% to make it sit flush below the first level of list items. Finally throw on a transition to really allow the animation to shine, and fine tune the timing if you'd like.</p>\n<p>Still on the .sub-menu we give it a max-height of 0 and overflow: hidden. What this does is it hides the element from our view, similar to display:none or visibility:hidden... but for our animation we have to do it this way!</p>\n<p>Lastly we give the sub menu list items and links a display of block and some colors because pretty.</p>\n<p>That's it, you've now got a simple dropdown navigation with a neat little animation! You can add a height of 0 to the ul .sub-menu as well for a slightly different effect, or play around with the transition time and effect. Much to the same effect, increasing the value of the max-height on the sub menu hover will have an effect on the time it takes the dropdowns to make it to the end.</p>\n<p><a href=\"https://codepen.io/anon/pen/bVKEwK\">Check it out on Codepen.</a></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</style>","frontmatter":{"date":"December 15, 2015","updated_date":null,"description":null,"title":"CSS/HTML Animated Dropdown Navigation","tags":["HTML","CSS","UI","CSS Animation"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/501f7fa9187224569eb6e51827f87931/630fb/drop-anim-300x300.png","srcSet":"/static/501f7fa9187224569eb6e51827f87931/69585/drop-anim-300x300.png 200w,\n/static/501f7fa9187224569eb6e51827f87931/630fb/drop-anim-300x300.png 300w","sizes":"(max-width: 300px) 100vw, 300px"}}},"author":{"id":"Zakary Hughes","github":null,"avatar":null}}}},{"node":{"excerpt":"In this tutorial I will demonstrate how to build a custom login form scratch. This time instead of using the default function call Wordpress…","fields":{"slug":"/engineering/part-2-creating-a-custom-login-form/"},"html":"<p>In this tutorial I will demonstrate how to build a custom login form scratch. This time instead of using the default function call Wordpress provides us, we will create this login form and the styling from scratch, making it a very customized form. I will be providing the CSS I am using, however you may style this however you wish.</p>\n<h2 id=\"building-a-custom-login-form\" style=\"position:relative;\"><a href=\"#building-a-custom-login-form\" aria-label=\"building a custom 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>Building a Custom Login Form</h2>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 574px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 79.79094076655052%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAACqUlEQVQoz3WT+0/TUBTH9zf5s3+C/uoP/qI/GcXEGEw0RoOGRQQEnYowg6hBTciiJC5KFCW8ApOBymMPxrpH6R5tt/be3tt7uz7Weruhos6Tkyb3tJ/z7TnnnoD2f6MYGTrWoAahfwRAU1XInmYDER2xYKAjBlvkyHzq4uuNiqz6GVo8w3SMou/LsXXJoOgAZu9YygMFCJngDi+dm4qffL4SXtjVFISwVqmCuYVqLC6duZC60pMBbWXG6DpqOpgSBABkUaRp+2J9eDYZ/LQ1OcstLolM80bf3u1hrncge38sf/5SWiipAUYSggq8Gp0pc3mFUl3TECHYMommo69JKZdV1zakdEYJDnCR6f3vW7IkweBgVigDH8YYhUbzE5PF/ntcOoM9z6vVGwBagmBcu8nt5Ug6ow89KOSLdHScn1uo9PZnI9NCw0ABhFi1sG+YW1oVRx7nhx7mKizxQLbvbuFlpNLVvatqlut5K3EgVI13H+UXU/x2osZIVm9bWSuV1a7u1OmzydAYz/ztjLyZ0B6N8+Gn++vfgOc1Lcumpu00bdfVKUUQ+K0NtAYIHVv/si6GJ4Rnr0rT0dLok2LwTm5+WWm67nYSQWSzWj7M1Y+f2Pw8XzUMDH7B7W4XimpwkIu8KVPWQETlmsGAxWXlyNG1WJyJe7xAwhN+w9hQ2kP9fUlY8bbFALfZ9J2Z7TgAmrG4iglTdqlqEt20bUz+hSGEhFLTtAmhhDYIMRzHcVmvPC+xh0/1pI5dT9wK5QdDuWxO+ft6MphS6rmu5ZttmRbTZ6SqWpd7s1ejfGhLxKa5siruJGt+zzrAh6wtqwIrkcbtiOPYloU6/PahLD+Xo7VPbBMoxXVFU/w48hcLHnz5B4wQqss1sSrWanVZkplLoiSLsqKAjsv3AxaRT4JDSnKaAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"wp-login-boring\"\n        title=\"wp-login-boring\"\n        src=\"/static/e6f31dc6cf2ee195c1d37e9a67322d0c/86389/wp-login-boring.png\"\n        srcset=\"/static/e6f31dc6cf2ee195c1d37e9a67322d0c/86389/wp-login-boring.png 574w\"\n        sizes=\"(max-width: 574px) 100vw, 574px\"\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>This is what WordPress gives us out of the box.. Boring, right?</p>\n<p>I am going to show this part once again because it is probably the easiest to implement for beginners. I covered this in Part 1, but we'll go through it again just in case you're skipping ahead</p>\n<p>To start our page theme you will need to do the following</p>\n<p>1. Install WordPress\n2. Navigate to your wp-content/themes folder and choose a theme to edit or install a new one\n3. create a file called page-login-custom.php in the theme directory (Notice we are now making a new Page Theme)\n4. Next open that file with a text editor of your choosing and add the following at the top of the php file</p>\n<p>--></p>\n<p>To initialize this page template make sure to activate the theme you've selected and then navigate to a page or post. On the right hand side of your page/post editor you should now see a dropdown available for template. Change your template to Login Custom and that will attach that page theme to this page/post.</p>\n<p>Now for the custom code. Below I have provided an example of some code that I have customized to make my custom login form.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">form</span><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 class=\"mtk12\">action</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;wp-user-form&quot;</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=\"mtk17\">&lt;</span><span class=\"mtk4\">input</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 class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;log&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">size</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;20&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">id</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;user_login&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tabindex</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;11&quot;</span><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>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">Remember me</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;submit&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;user-submit&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">tabindex</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;14&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;user-submit&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">input</span><span class=\"mtk1\"> </span><span class=\"mtk12\">type</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;hidden&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">name</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;redirect_to&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk12\">value</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\"> </span><span class=\"mtk17\">/&gt;</span></span></code></pre>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 743px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 30.153846153846153%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAIAAABM9SnKAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAUklEQVQY053PSw6AMAhAQe5/Vpu0hM9CW6xF3WBjdLbkBQC7tMGCNgd9rKoi4mUNbO6IETGX4vEaPJ5zxn2WByLaao23vWxOaWFmf8++gB/NbQe5NGSblvZQtAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"login-2-custom\"\n        title=\"login-2-custom\"\n        src=\"/static/4fa351920dfdb37fdbc4cac1f740f52e/f2793/login-2-custom.png\"\n        srcset=\"/static/4fa351920dfdb37fdbc4cac1f740f52e/a6d36/login-2-custom.png 650w,\n/static/4fa351920dfdb37fdbc4cac1f740f52e/f2793/login-2-custom.png 743w\"\n        sizes=\"(max-width: 743px) 100vw, 743px\"\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 take a look at that custom form</p>\n<h2 id=\"handling-the-login-form-response\" style=\"position:relative;\"><a href=\"#handling-the-login-form-response\" aria-label=\"handling the login form 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>Handling the Login Form response</h2>\n<p>To handle the Login Form response use the exact same method we used in part 1. Remember to place that function within your functions.php file within your theme unless you're building a plugin.</p>\n<p>In this example we have built a custom WordPress login form that you could customize and style to your desire. In the next section I will be demonstrating how to build a lost password form that is fully customized. Our custom lost password form will send an email to the user as well as handle creating a new password for the user.</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 .mtk17 { color: #808080; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"December 08, 2015","updated_date":null,"description":null,"title":"Part 2 - Creating a Custom Login Form","tags":["Engineering","Login"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/3e9f0e12bae5ff4eea3aa1dae7083c47/6d161/cust-login-2-150x150.png","srcSet":"/static/3e9f0e12bae5ff4eea3aa1dae7083c47/6d161/cust-login-2-150x150.png 150w","sizes":"(max-width: 150px) 100vw, 150px"}}},"author":{"id":"Zoie Carnegie","github":null,"avatar":null}}}},{"node":{"excerpt":"Authentication systems are the backbone of many websites. It allows users to log in to your site and preserving data between visits. It is…","fields":{"slug":"/engineering/website-authentication-protocols/"},"html":"<p>Authentication systems are the backbone of many websites. It allows users to log in to your site and preserving data between visits. It is crucial in offering a robust user experience, which rewards your users for providing their details. Authentications often provide access to personal private data which if made public, it could harm your user. To prevent these, authentication protocols were created to secure the requests while allowing users to still safely login to your system from any environment.</p>\n<p><strong>Basic SSL Auth</strong></p>\n<p>Basic auth is the simplest form of web authentication. It utilizes standard HTTP headers in place of more complicated solutions that rely on cookies, session identifiers, and login pages. There is very little security built into the basic auth system. Credentials are transmitted with only Base64 encoding and are not encrypted or hashed. Due to the ingrained insecurities in the system, these requests are most often made via HTTPS.</p>\n<p>The authorization information should be compiled into the following format and included in the header:</p>\n<p>Format:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"http\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">&lt;!--Authorization: Basic --&gt;</span></code></pre>\n<p>Full details on the Basic Authentication protocol can be found here: <a href=\"http://www.w3.org/Protocols/HTTP/1.0/spec.html#AA\">Authentication Protocol</a></p>\n<p><strong>Digest Auth</strong></p>\n<p>Digest Auth works similar to basic SSL authentication with the exception that the password is encrypted using a one-way hash. It utilizes MD5 cryptographic hashing with a nonce(a server-generated value that prevents replay attacks).</p>\n<p>The typical flow of a Digest Auth request is :</p>\n<ol>\n<li>A user navigates to a page that requires user authentication.</li>\n<li>The server responds with a 401 message that signifies that a user is not currently authorized to access the content. In the response, it also includes the nonce which will be used during the authorization to prevent replay attacks,</li>\n<li>The site then displays an authentication interface to gather the required details( username and password )</li>\n<li>The provided details are re-sent to the server with an authentication header included in the request that has a response code.</li>\n<li>The server would then verify the provided credentials and accept the authentication or return a 401 message if the credentials are incorrect, which would cause the user to be again prompted with the authentication interface.</li>\n</ol>\n<p>You can find full details on the Digest Auth protocol can be found here: <a href=\"https://www.ietf.org/rfc/rfc2617.txt\">Digest Auth Protocol</a></p>\n<p><strong>OAuth 1.0</strong></p>\n<p>The OAuth 1.0 protocol relies on having a shared secret between the server and the site. This shared secret is used to generate a signature that is included in the request. The generated signature is used to verify the validity of the authentication request on the server-side. The process for authorizing the user is generally handled in three steps (3-legged OAuth):</p>\n<ol>\n<li>Site obtains Request Token.</li>\n<li>User authorizes the Request Token.</li>\n<li>Site exchanges Request token for Access Token.</li>\n</ol>\n<p>The process of completing a 3-legged OAuth request will generally be handled as follows:</p>\n<ol>\n<li>\n<p>The site will send a signed request for the Request token. This request should contain the following parameters:</p>\n<ol>\n<li>oauth_consumer_key</li>\n<li>oauth_timestamp</li>\n<li>oauth_nonce</li>\n<li>oauth_signature</li>\n<li>oauth_signature_method</li>\n<li>oauth_version</li>\n<li>oauth_callback</li>\n</ol>\n</li>\n</ol>\n<p>This request will be validated on the server.  If validated, it will return the request token in the following format:</p>\n<ol>\n<li>oauth_token</li>\n<li>oauth_token_secret</li>\n<li>and any other additional parameters returned by your server.</li>\n<li>The next step after retrieving the request token is to prompt your user to input their login credentials. These are then formatted into a signature with the oauth_token request token. Then they are sent with a request back to the server for validation. Upon successful validation from this request, the server will return the following:</li>\n<li>oauth_token</li>\n<li>oauth_verifier</li>\n</ol>\n<p>These will be used in the next step to retrieve an access token.</p>\n<ol>\n<li>The final step is exchanging the retrieved details from step 2 for an access token, which will be used to access the server's resources. To exchange your request token for an access token, you can make a request to the server with the following signed request</li>\n<li>oauth_token -returned from step 2</li>\n<li>oauth_consumer_key</li>\n<li>oauth_nonce</li>\n<li>oauth_signature</li>\n<li>oauth_signature_method</li>\n<li>oauth_version</li>\n<li>oauth_verifier -returned from step 2</li>\n</ol>\n<p>This will return you an access token to be used in conjunction with your secret in order to make requests for information from the server.</p>\n<p>You can find full details on the OAuth 1.0 protocol here: <a href=\"https://tools.ietf.org/html/rfc5849\">OAuth 1.0 protocol</a></p>\n<p><strong>OAuth 2.0</strong></p>\n<p>This is similar to the OAuth 1.0 protocol, it relies on a client id and secret in order to format request, but simplifies much of the complicated signing process that is inherent in the OAuth 1.0 system. The process for authorizing a user using the 3-legged OAuth 2.0 protocol is as follows:</p>\n<ol>\n<li>\n<p>User is directed to the service for authorization with the following details included in the authorization URL:</p>\n<ol>\n<li>client_id</li>\n<li>redirect_uri</li>\n<li>response_type</li>\n<li>scope</li>\n</ol>\n</li>\n<li>\n<p>The user would then authenticate with the service and grant the application access to their details. On successful authentication, the user is redirected back to the redirect_uri with the following parameters:</p>\n<ol>\n<li>code</li>\n<li>state</li>\n</ol>\n</li>\n<li>\n<p>The code returned in step 2 is then used by the application to make a request for an access token. Included in this request should be:</p>\n<ol>\n<li>client_id</li>\n<li>client_secret</li>\n<li>code</li>\n<li>redirect_uri</li>\n<li>grant_type - This should be set to “authorization_code”</li>\n</ol>\n</li>\n</ol>\n<p>The server will verify these details and then return an access token with an expiration time if they are valid. These get generally returned in the following format:</p>\n<ol>\n<li>access_token</li>\n<li>expires_in</li>\n<li>refresh_token</li>\n</ol>\n<p>You can find full details on the OAuth 2.0 protocol here: <a href=\"http://oauth.net/2/\">OAuth 2.0 protocol</a></p>\n<p>Authentication protocols allow you to secure your data with varying levels of security. Depending on the data being accessed and your desired level of security, implementing one of the above protocols allows you to be confident that your data is safe and can only being accessed by users that are permitted to your system.</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</style>","frontmatter":{"date":"December 01, 2015","updated_date":null,"description":null,"title":"Website Authentication Protocols","tags":["Authentication","Oauth"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5625,"src":"/static/2777d4b53aa6128513f070b7f78f3651/ee604/server-proc-150x150.png","srcSet":"/static/2777d4b53aa6128513f070b7f78f3651/69585/server-proc-150x150.png 200w,\n/static/2777d4b53aa6128513f070b7f78f3651/497c6/server-proc-150x150.png 400w,\n/static/2777d4b53aa6128513f070b7f78f3651/ee604/server-proc-150x150.png 800w,\n/static/2777d4b53aa6128513f070b7f78f3651/f3583/server-proc-150x150.png 1200w,\n/static/2777d4b53aa6128513f070b7f78f3651/5707d/server-proc-150x150.png 1600w,\n/static/2777d4b53aa6128513f070b7f78f3651/6e0a6/server-proc-150x150.png 2256w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Karl Wittig","github":null,"avatar":null}}}}]},"markdownRemark":{"excerpt":"Identity is evolving, and developers are at the forefront of this transformation. Every day brings a new learning—adapting to new standards…","fields":{"slug":"/identity/developer-first-identity-provider-loginradius/"},"html":"<p>Identity is evolving, and developers are at the forefront of this transformation. Every day brings a new learning—adapting to new standards and refining approaches to building secure, seamless experiences.</p>\n<p>We’re here to support developers on that journey. We know how important simplicity, efficiency, and well-structured documentation are when working with identity and access management solutions. That’s why we’ve redesigned the <a href=\"https://www.loginradius.com/\">LoginRadius website</a>—to be faster, more intuitive, and developer-first in every way.</p>\n<p>The goal? Having them spend less time searching and more time building.</p>\n<h2 id=\"whats-new-and-improved-on-the-loginradius-website\" style=\"position:relative;\"><a href=\"#whats-new-and-improved-on-the-loginradius-website\" aria-label=\"whats new and improved on the loginradius website 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’s New and Improved on the LoginRadius Website?</h2>\n<p>LoginRadius’ vision is to give developers a product that simplifies identity management so they can focus on building, deploying, and scaling their applications. To enhance this experience, we’ve spent the last few months redesigning our interface— making navigation more intuitive and reassuring that essential resources are easily accessible.</p>\n<p>Here’s a closer look at what’s new and why it’s important:</p>\n<h3 id=\"a-developer-friendly-dark-theme\" style=\"position:relative;\"><a href=\"#a-developer-friendly-dark-theme\" aria-label=\"a developer friendly dark theme 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 Developer-Friendly Dark Theme</h3>\n<p><img src=\"/f46881583c7518a93bb24e94c32320de/a-developer-friendly-dark-theme.webp\" alt=\"This image shows how LoginRadius offers several authentication methods like traditional login, social login, passwordless login, passkeys and more in a dark mode.\">    </p>\n<p>Developers spend long hours working in dark-themed IDEs and terminals, so we’ve designed the LoginRadius experience to be developer-friendly and align with that preference.</p>\n<p>The new dark mode reduces eye strain, enhances readability, and provides a seamless transition between a coding environment and our platform. Our new design features a clean, modern aesthetic with a consistent color scheme and Barlow typography, ensuring better readability. High-quality graphics and icons are thoughtfully placed to enhance the content without adding visual clutter.</p>\n<p>So, whether you’re navigating our API docs or configuring authentication into your system, our improved interface will make those extended development hours more comfortable and efficient.</p>\n<h3 id=\"clear-categorization-for-loginradius-capabilities\" style=\"position:relative;\"><a href=\"#clear-categorization-for-loginradius-capabilities\" aria-label=\"clear categorization for loginradius capabilities 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>Clear Categorization for LoginRadius Capabilities</h3>\n<p><img src=\"/e5358b82be414940f3fb146013845933/capabilities.webp\" alt=\"This image shows a breakdown of all the LoginRadius CIAM capabilities, including authentication, security, UX, scalability and multi-brand management.\"></p>\n<p>We’ve restructured our website to provide a straightforward breakdown of our customer identity and access management platform capabilities, helping you quickly find what you need:</p>\n<ul>\n<li>Authentication: Easily understand <a href=\"https://www.loginradius.com/blog/identity/authentication-option-for-your-product/\">how to choose the right login method</a>, from traditional passwords and OTPs to social login, federated SSO, and passkeys with few lines of code.</li>\n<li>Security: Implement no-code security features like bot detection, IP throttling, breached password alerts, DDoS protection, and adaptive MFA to safeguard user accounts.</li>\n<li>User Experience: Leverage AI builder, hosted pages, and drag-and-drop workflows to create smooth, branded sign-up and login experiences.</li>\n<li>High Performance &#x26; Scalability: Confidently scale with sub-100ms API response times, 100% uptime, 240K+ RPS, and 28+ global data center regions.</li>\n<li>Multi-Brand Management: Efficiently manage multiple identity apps, choosing isolated or shared data stores based on your brand’s unique needs.</li>\n</ul>\n<p>This structured layout ensures you can quickly understand each capability and how it integrates into your identity ecosystem.</p>\n<h3 id=\"developer-first-navigation\" style=\"position:relative;\"><a href=\"#developer-first-navigation\" aria-label=\"developer first navigation 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>Developer-First Navigation</h3>\n<p><img src=\"/a8c155c2b6faf3d5f4b4de4e2b14d763/developers-menu.webp\" alt=\"This image shows the LoginRadius menu bar, highlighting the developer dropdown.\">   </p>\n<p>We’ve been analyzing developer workflows to identify how you access key resources. That’s why we redesigned our navigation with one goal in mind: to reduce clicks and make essential resources readily available.</p>\n<p>The new LoginRadius structure puts APIs, SDKs, and integration guides right at the menu bar under the Developers dropdown so you can get started faster. Our Products, Solutions, and Customer Services are also clearly categorized, helping development teams quickly find the right tools and make informed decisions.</p>\n<h3 id=\"quick-understanding-of-integration-benefits\" style=\"position:relative;\"><a href=\"#quick-understanding-of-integration-benefits\" aria-label=\"quick understanding of integration benefits 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>Quick Understanding of Integration Benefits</h3>\n<p><img src=\"/b2f9a964a2da0ea83e2f8596b833bba7/we-support-your-tech-stack.webp\" alt=\"This image shows a list of popular programming languages and frameworks offered by LoginRadius.\"></p>\n<p>Developers now have a clear view of the tech stack available with LoginRadius, designed to support diverse business needs.</p>\n<p>Our platform offers pre-built SDKs for Node.js, Python, Java, and more, making CIAM integration seamless across popular programming languages and frameworks.</p>\n<h2 id=\"over-to-you-now\" style=\"position:relative;\"><a href=\"#over-to-you-now\" aria-label=\"over to you now 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>Over to You Now!</h2>\n<p>Check out our <a href=\"https://www.loginradius.com/\">revamped LoginRadius website</a> and see how the improved experience makes it easier to build, scale, and secure your applications.</p>\n<p>Do not forget to explore the improved navigation and API documentation, and get started with our free trial today. We’re excited to see what you’ll build with LoginRadius!</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</style>","frontmatter":{"date":"February 21, 2025","updated_date":null,"description":"LoginRadius’ vision is to give developers a product that simplifies identity management so they can focus on building, deploying, and scaling their applications. To enhance this experience, we’ve redesigned our website interface, making navigation more intuitive and reassuring that essential resources are easily accessible.","title":"Revamped & Ready: Introducing the New Developer-First LoginRadius Website","tags":["Developer tools","API","Identity Management","User Authentication"],"pinned":true,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7857142857142858,"src":"/static/80b4e4fbe176a10a327d273504607f32/58556/hero-section.webp","srcSet":"/static/80b4e4fbe176a10a327d273504607f32/61e93/hero-section.webp 200w,\n/static/80b4e4fbe176a10a327d273504607f32/1f5c5/hero-section.webp 400w,\n/static/80b4e4fbe176a10a327d273504607f32/58556/hero-section.webp 800w,\n/static/80b4e4fbe176a10a327d273504607f32/99238/hero-section.webp 1200w,\n/static/80b4e4fbe176a10a327d273504607f32/7c22d/hero-section.webp 1600w,\n/static/80b4e4fbe176a10a327d273504607f32/1258b/hero-section.webp 2732w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Rakesh Soni","github":"oyesoni","avatar":"rakesh-soni.jpg"}}}},"pageContext":{"limit":6,"skip":912,"currentPage":153,"type":"///","numPages":161,"pinned":"ee8a4479-3471-53b1-bf62-d0d8dc3faaeb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}