{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/46","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"In this blog, I will cover some of my favorite Sublime features. Use of these plugins will dramatically reduce the amount of tedious tasks…","fields":{"slug":"/engineering/beginners-guide-for-sublime-text-3-part-2/"},"html":"<p>In this blog, I will cover some of my favorite Sublime features. Use of these plugins will dramatically reduce the amount of tedious tasks you have to perform, and make your worktime really fun. I will start with some of the most basic features that come with fresh installation of Sublime. There are lots of good tutorials on Sublime shortcuts and plugins on the internet, but I feel there should be more about these fundamental features. I have seen many people who are familiar with the plugins but not with these cool built-in features. In this article we will be introducing \"Snippets\", \"Project\" and \"Macros\".</p>\n<p>Here we go:</p>\n<h3 id=\"snippets\" style=\"position:relative;\"><a href=\"#snippets\" aria-label=\"snippets 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>Snippets</h3>\n<p><img src=\"/3e21aab686b29a54a248ccd545aca465/snippet-demo.gif\" alt=\"snippet-demo\"></p>\n<p>Back when i introduced Sublime editor to my friends,\"Snippets\" was among the first few features which really intrigued them. To give a quick peek what a snippet looks like:  </p>\n<p>This is definitely the feature you will use the most! To start using snippets, you can either create your own snippets according to your needs or download some ready-made snippets created by others to fulfill some generic coding needs. Like the one I demonstrated, it is pre-made from a plugin called <code>Html Page Snippets</code>, and command <code>docjq</code> will create a boiler template for a Html page that contains bootstrap and jQuery.</p>\n<p><img src=\"/0300880eed77c65d2c7b959aca04ee17/new-snippet.webp\" alt=\"new-snippet\"></p>\n<p>To create your own snippet, go to \"Tools\" => \"New Snippet\", an interface to create your own snippet will pop up, it would look something like this:  </p>\n<ul>\n<li>Replace the default line with your snippet, the default one looks like this:</li>\n</ul>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\">Hello, ${1:this} is a ${2:snippet}.</span></code></pre>\n<p>Note: The dollar sign \"$\" allows you to use tab key to jump between, so set it wisely!</p>\n<ul>\n<li>Uncomment this line to set up a tab trigger for the shortcut</li>\n</ul>\n<p>Now save it, but keep in mind putting it in the correct location is important!</p>\n<p>If you can not find it, go to \"Sublime\" - > \"Preferences\" -> \"Browse Packages\", and create a folder called \"User\" if there isn't one already, and save it there.</p>\n<p><img src=\"/30a6ed6b40f11c0e5690a68bda1f31ef/browse-package.webp\" alt=\"browse-package\"></p>\n<h3 id=\"project\" style=\"position:relative;\"><a href=\"#project\" aria-label=\"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>Project</h3>\n<p>Using \"Project\" feature to organize your projects is super easy and handy. It saves a lot of time that you'd normally waste finding different folders and then dragging and dropping to your Sublime each time. Additionally, it saves your previous location so you can just pick up where you left off. Let's see a quick demo:</p>\n<p>Saving and using your projects is very straightforward.</p>\n<ul>\n<li>First drag some folders and files that you want to open into Sublime</li>\n<li>\n<p>Then go to the menu, click \"Project\" -> \"Save Project As\"  </p>\n<p><img src=\"/70e0570d0894195bc9d3e2e1c5e52dfb/save-proj.webp\" alt=\"save-proj\"></p>\n</li>\n<li>Note the extension is \".sublime-project\" and you may want to put all your project files in one central location</li>\n</ul>\n<p>That's it! You're done! Super easy right?</p>\n<h3 id=\"macros\" style=\"position:relative;\"><a href=\"#macros\" aria-label=\"macros 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>Macros</h3>\n<p><img src=\"/e8a218bdc92e2c8c118faeb6fec384e0/without-macro.gif\" alt=\"without-macro\"></p>\n<p>Do you always feel frustrated by repeating the same tedious task again &#x26; again? Hmm... at least that's how I feel when I need to covert a vertical line of data into an array. Tasks like these are pretty common when you need to copy a line of data from spreadsheets. Using shortcuts, the best way I can come up with to accomplish this would be like so:  </p>\n<p>It takes about 8 shortcuts to finish each process, that's including the first paste action and then adding a space character after each comma. Imagine having to do this for each line of a table, and for every single spreadsheet you have to work on. It would be hundreds of shortcuts you need to press and each time you are just repeating the exact same sequence of keys.</p>\n<p><img src=\"/b799f564f4bd2661de161e21af25fea4/start-macro.webp\" alt=\"start-macro\"></p>\n<p>Well you might think there must be a better way! You bet there is! \"Macros\" are designed to handle this kind of nasty situation and save you from all that boring work. Here I made a very quick and easy example, it converts a vertical line of data into an array:  </p>\n<p>Magic! Lots of time and lives will be saved by this little gadget. So now, how to make your very own macros. First of all I would recommend trying out your set of operations several times to make sure it will get recorded correctly. When you are ready, open a new window/tab in Sublime, clear your mind, take several deep breaths, and here we go.</p>\n<ul>\n<li>\n<p>Go to \"Tools\" -> \"Record Mac  </p>\n<p><img src=\"/b799f564f4bd2661de161e21af25fea4/start-macro1.webp\" alt=\"start-macro1\"></p>\n</li>\n<li>Do your operations</li>\n</ul>\n<p>Usually you would have something copied in your clipboard, so it could start with a \"Paste\" command. Now it's your time to shine, do a clean and precise set of operations to format the data.</p>\n<ul>\n<li>\n<p>Stop your macro  </p>\n<p><img src=\"/eb5135b0cb78399916eda6245eb93e69/stop-macro.webp\" alt=\"stop-macro\"></p>\n</li>\n<li>Playback</li>\n</ul>\n<p>You can find it under the same \"Tools\" menu. Just use it to make sure it did what you want, sometimes even though you recorded it properly, the macro doesn't recognize the operations correctly. For this reason it's important to make sure everything is correct and smooth, and if it's not, try find some alternatives for your operations.</p>\n<ul>\n<li>Save It!</li>\n</ul>\n<p>Similar to other Sublime tools, it will be saved with an extension called \".sublime-macro\", after it gets saved you will be able to find it in your Macro User List.</p>\n<h3 id=\"to-be-continued-\" style=\"position:relative;\"><a href=\"#to-be-continued-\" aria-label=\"to be continued  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>To Be Continued ..</h3>\n<p>I hope you had fun and learned something new about Sublime. Next time we will cover some really good packages/plugins that you should consider using to make your life and work even simpler.\nHappy 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  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n</style>","frontmatter":{"date":"November 10, 2015","updated_date":null,"description":"Getting started with one of the lightweight Code Editor Sublime Text and introduction to Snippets, Project and Macros","title":"Beginner's Guide for Sublime Text 3 Plugins","tags":["SublimeText","CodeEditor"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/296e569fc8dd1576c6df798847aaf8ad/7fbdd/Beginner-Guide-Sublime-Text.webp","srcSet":"/static/296e569fc8dd1576c6df798847aaf8ad/61e93/Beginner-Guide-Sublime-Text.webp 200w,\n/static/296e569fc8dd1576c6df798847aaf8ad/1f5c5/Beginner-Guide-Sublime-Text.webp 400w,\n/static/296e569fc8dd1576c6df798847aaf8ad/7fbdd/Beginner-Guide-Sublime-Text.webp 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}},{"node":{"excerpt":"In order to display your LoginRadius Login Interface in a pop-up you can leverage Jquery-ui which is a well documented, easy-to-use library…","fields":{"slug":"/engineering/displaying-the-loginradius-interface-in-a-pop-up/"},"html":"<p>In order to display your LoginRadius Login Interface in a pop-up you can leverage Jquery-ui which is a well documented, easy-to-use library that allows you to handle some common functionality such as pop-up dialogs and other UI features. In this article we go over the steps to use Jquery-ui to display a pop-up on your page with a LoginRadius login interface using the LoginRadius HTML SDK.</p>\n<p>1. Get the required references this guide relies on: Jquery and Jquery-ui. You can include the hosted reference files in the header of your page:</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=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>2. Include the LoginRadius Interface Javascript and HTML5 SDK reference:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">options</span><span class=\"mtk1\">={};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">options</span><span class=\"mtk1\">.</span><span class=\"mtk12\">login</span><span class=\"mtk1\">=</span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk12\">util</span><span class=\"mtk1\">.</span><span class=\"mtk11\">ready</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=\"mtk12\">$ui</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk12\">lr_login_settings</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">interfacesize</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apikey</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">callback</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">lrinterfacecontainer</span><span class=\"mtk1\"> =</span><span class=\"mtk8\">&quot;interfacecontainerdiv&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">(</span><span class=\"mtk12\">options</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">});</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>3. Create the HTML structure for your page. Below we have created a button to trigger our pop-up display as well as the dialog container that will be displayed in the custom pop-up which is hidden by default. We have also included a div to display profile data after successfully authenticating.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span><span class=\"mtk12\">Login</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\"> --&gt;</span></span></code></pre>\n<p>4. Create a JavaScript function to handle the display of the pop-up dialog. The below function utilizes Jquery-ui functions to display the dialog and the LoginRadius login interface initialization function to render the login interface on the popup:</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\">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=\"mtk11\">$</span><span class=\"mtk1\">( </span><span class=\"mtk8\">&quot;#dialog&quot;</span><span class=\"mtk1\"> ).</span><span class=\"mtk11\">dialog</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">(</span><span class=\"mtk12\">options</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>5. Include the JavaScript callback script to handle a successful authentication and display the profile data.</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\">LoginRadiusSDK</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setLoginCallback</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Successfullylogin</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Successfullylogin</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">LoginRadiusSDK</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getUserprofile</span><span class=\"mtk1\">( </span><span class=\"mtk4\">function</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\">$</span><span class=\"mtk1\">( </span><span class=\"mtk8\">&quot;#dialog&quot;</span><span class=\"mtk1\"> ).</span><span class=\"mtk11\">dialog</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;close&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><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;profile&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk12\">innerHTML</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    });</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>Full Example:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">options</span><span class=\"mtk1\">={};</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">options</span><span class=\"mtk1\">.</span><span class=\"mtk12\">login</span><span class=\"mtk1\">=</span><span class=\"mtk4\">true</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk12\">util</span><span class=\"mtk1\">.</span><span class=\"mtk11\">ready</span><span class=\"mtk1\">(</span><span class=\"mtk4\">function</span><span class=\"mtk1\"> () {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$ui</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk12\">lr_login_settings</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">interfacesize</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">apikey</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">callback</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">$ui</span><span class=\"mtk1\">.</span><span class=\"mtk12\">lrinterfacecontainer</span><span class=\"mtk1\"> =</span><span class=\"mtk8\">&quot;interfacecontainerdiv&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">(</span><span class=\"mtk12\">options</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=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><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=\"mtk11\">$</span><span class=\"mtk1\">( </span><span class=\"mtk8\">&quot;#dialog&quot;</span><span class=\"mtk1\"> ).</span><span class=\"mtk11\">dialog</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">LoginRadius_SocialLogin</span><span class=\"mtk1\">.</span><span class=\"mtk11\">init</span><span class=\"mtk1\">(</span><span class=\"mtk12\">options</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=\"mtk12\">LoginRadiusSDK</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setLoginCallback</span><span class=\"mtk1\">(</span><span class=\"mtk12\">Successfullylogin</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">Successfullylogin</span><span class=\"mtk1\">(){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">LoginRadiusSDK</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getUserprofile</span><span class=\"mtk1\">( </span><span class=\"mtk4\">function</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\">$</span><span class=\"mtk1\">( </span><span class=\"mtk8\">&quot;#dialog&quot;</span><span class=\"mtk1\"> ).</span><span class=\"mtk11\">dialog</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;close&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><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;profile&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk12\">innerHTML</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>\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=\"mtk12\">Login</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 class=\"mtk1\">--&gt;</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 .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"November 09, 2015","updated_date":null,"description":null,"title":"Displaying the LoginRadius interface in a pop-up","tags":["HTML","Login","UI","LoginRadius Interface"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/b457f6215159c9dcc593ccf7c891be5b/e7487/simplepop-150x150.webp","srcSet":"/static/b457f6215159c9dcc593ccf7c891be5b/e7487/simplepop-150x150.webp 150w","sizes":"(max-width: 150px) 100vw, 150px"}}},"author":{"id":"Karl Wittig","github":null,"avatar":null}}}},{"node":{"excerpt":"Almost every active website worldwide uses jQuery, you can check stats here , but using it without optimization might make the DOM very slow…","fields":{"slug":"/engineering/optimize-jquery-sizzle-element-selector/"},"html":"<p>Almost every active website worldwide uses jQuery, you can check stats <a href=\"http://trends.builtwith.com/javascript/jQuery\">here</a> , but using it without optimization might make the DOM very slow. The same goes for other javascript libraries, such as SizzleJS. To ensure the performance of your DOM, you have to follow some best practices for it.</p>\n<p>In this article I am going to list down some of the most critical factors that you need to watch out. Even though this not a complete list; taking care of these will help you optimize those jQuery Selector.</p>\n<h3 id=\"lets-start\" style=\"position:relative;\"><a href=\"#lets-start\" aria-label=\"lets start 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><strong>Let's start!</strong></h3>\n<h4 id=\"always-cache-your-selector\" style=\"position:relative;\"><a href=\"#always-cache-your-selector\" aria-label=\"always cache your selector 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>Always cache your selector</h4>\n<p>Whenever you apply any selector in jQuery or <a href=\"http://sizzlejs.com/\">SizzleJS</a>,  the selector engine goes through the whole DOM to find the specified element.</p>\n<p>For example, if you use the code below, it will go through the whole DOM twice in order to find \".myClass\" selector.</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=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.myClass&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">show</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.myClass&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">addClass</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;anotherClass&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>But instead of that, if you make all the methods in a chained format like this. It will only try to find that class once.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.myClass&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">show</span><span class=\"mtk1\">().</span><span class=\"mtk11\">addClass</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;anotherClass&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Or if you want to use this element in other places; you can do so by doing it in this way.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">myElem</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.myClass&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">myElem</span><span class=\"mtk1\">.</span><span class=\"mtk11\">show</span><span class=\"mtk1\">();</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">myElem</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addClass</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;anotherCLass&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>In both of these cases, the selector will be executed only once. Some selectors are very slow to traverse and passing them again and again will make your DOM very slow.</p>\n<p>Read on the next point to understand,  how the type of selector affects performance.</p>\n<h4 id=\"prioritizing-selectors-based-on-their-performance\" style=\"position:relative;\"><a href=\"#prioritizing-selectors-based-on-their-performance\" aria-label=\"prioritizing selectors based on their 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>Prioritizing selectors based on their performance</h4>\n<p>Selector's type affects the performance of your site. SizzleJS is a smart selector engine that also uses native js APIs for finding specific element. This is the main reason why ID selector and tag selector perform faster than others. But, if you prefer using jQuery, it’s pretty much the same. Modern browsers also have an API to find an element by class name but, let’s just focus on jQuery and SizzleJS.</p>\n<ul>\n<li>The order of selector's performance (fast -> slow) is</li>\n<li>ID selector ($(\"#ID\")) = Fastest</li>\n<li>Tag ($(\"Tag\")) = Fast</li>\n<li>Class ($(\".Class\")) = Average</li>\n<li>Attribute ($(\"[Attribute='Value']\")) = Slow</li>\n<li>Pseudo ($(\":pseudo\")) = Slower</li>\n</ul>\n<p>You can verify performance. In some exceptional cases, the selection of those tags does not matter; It’s all in the combination of the selectors. Because, it affects the performance of your site, let's discuss this on next point.</p>\n<h4 id=\"selecting-id-selector-first-and-then-other-ones\" style=\"position:relative;\"><a href=\"#selecting-id-selector-first-and-then-other-ones\" aria-label=\"selecting id selector first and then other ones 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>Selecting ID selector first and then other ones</h4>\n<p>If you have the combination of selectors, then the sequence of selectors matter for optimization. For example:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;#someId div .someClass&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>The same code can be written as:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;#someId&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">find</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;div .someClass&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Both of these variant represent the same thing but in the term of performance, second one is better. The reason for that is because in the first code, Sizzle will go through the DOM 3 times to find #someId, div, and .someClass.</p>\n<p>In the second one, the selector engine will go through the DOM again but, this time, it’ll only look for #someId and then find the rest inside that element without going through the DOM again.</p>\n<p>See how this will affect performance.</p>\n<h4 id=\"being-more-specific-in-right-hand-side-instead-of-left-hand-side\" style=\"position:relative;\"><a href=\"#being-more-specific-in-right-hand-side-instead-of-left-hand-side\" aria-label=\"being more specific in right hand side instead of left hand side 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>Being more specific in right hand side instead of left hand side</h4>\n<p>Sizzle executes selector from right to left so it will definitely  improve performance if applied in right except left.</p>\n<p><strong>Unoptimized code:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">( </span><span class=\"mtk8\">&quot;div.myclass .myChildClass&quot;</span><span class=\"mtk1\"> );</span></span></code></pre>\n<p><strong>Optimized code:</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">( </span><span class=\"mtk8\">&quot;.myclass td.myChildClass&quot;</span><span class=\"mtk1\"> );</span></span></code></pre>\n<p>If you don’t see the difference, find the div and td.</p>\n<h4 id=\"selection-inside-a-parent-always-improves-performance\" style=\"position:relative;\"><a href=\"#selection-inside-a-parent-always-improves-performance\" aria-label=\"selection inside a parent always improves 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>Selection inside a parent always improves performance</h4>\n<p>When you have a context, or any level of parent, then you can select an element inside that parent. It will perform better this way than selecting it directly. Because, in this case, the selector engine goes through the DOM once to find the parent.</p>\n<p>For example, assuming you are trying to find “.child” class:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.child&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Is slower than</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">parent</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;#parent&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">parent</span><span class=\"mtk1\">.</span><span class=\"mtk11\">find</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.child&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">show</span><span class=\"mtk1\">();</span></span></code></pre>\n<p>You can also specify context by following syntax</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"9\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.child&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">parent</span><span class=\"mtk1\">).</span><span class=\"mtk11\">show</span><span class=\"mtk1\">();</span></span></code></pre>\n<h4 id=\"excessive-selector-slows-down-your-query\" style=\"position:relative;\"><a href=\"#excessive-selector-slows-down-your-query\" aria-label=\"excessive selector slows down your query 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>Excessive selector slows down your query</h4>\n<p>The selector engine always checks every selector you have specified and it might traverse slowly. That being said, always make sure to specify minimum selectors in order to maintain the performance.</p>\n<p>For example, you are  trying to find “.myClass” using both of these code variants,</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"10\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;#div div span.myClass&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Is slower than</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"11\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;#div&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">find</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.myClass&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<h4 id=\"\" style=\"position:relative;\"><a href=\"#\" aria-label=\" 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></h4>\n<p><strong>The .children() tag is quicker than .find()</strong></p>\n<p>In case, you are trying to find a children element, it is recommended to use .children() instead of .find(). Using .find() will tell jQuery to look on every level of children, while .children() will find only the first level children. Therefore .children() is faster than .find().</p>\n<p>For example, you are trying to find “.child” inside $parent and it is the first level children of the $parent.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"12\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">parent</span><span class=\"mtk1\">.</span><span class=\"mtk11\">find</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.child&quot;</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>Is slower than</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"13\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk12\">parent</span><span class=\"mtk1\">.</span><span class=\"mtk11\">children</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.child&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">show</span><span class=\"mtk1\">();</span></span></code></pre>\n<h4 id=\"-1\" style=\"position:relative;\"><a href=\"#-1\" aria-label=\" 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></h4>\n<p>Use minimum DOM append</p>\n<p>DOM manipulation is very heavy so always try to ignore or minimize using it.</p>\n<p>For example, by using the code below, it will make the process sluggish because you didn’t apply any selector caching. Resulting in going through  the DOM ten times and appending an element.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"14\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><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\"> &lt; </span><span class=\"mtk7\">10</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.myClass&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">append</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p>But instead of using the above code, using the code below will solve the whole issue of appending and traversal. Not only that, it will merge the 10 times manipulation of DOM into a single call.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"js\" data-index=\"15\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">myClassInnerHtml</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><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\"> &lt; </span><span class=\"mtk7\">10</span><span class=\"mtk1\">; </span><span class=\"mtk12\">i</span><span class=\"mtk1\">++ ){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">myClassInnerHtml</span><span class=\"mtk1\"> += </span><span class=\"mtk8\">&quot;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">$</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;.myClass&quot;</span><span class=\"mtk1\">).</span><span class=\"mtk11\">append</span><span class=\"mtk1\">(</span><span class=\"mtk12\">myClassInnerHtml</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>All the tips I have mentioned above is highly dependant on your requirement but one thing is for sure; Optimization will definitely improve your process.  ‘SizzleJS’ is most the powerful and quick element selector. But, without writing optimized code you can’t prevent the DOM from freezing. With that being said,  jQuery is awesome but without optimized code it can get more DOM freezes and frustrate your users.</p>\n<p>I hope this help you optimize your element selecting. Thank you and have a great 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  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n</style>","frontmatter":{"date":"November 05, 2015","updated_date":null,"description":null,"title":"Optimize jQuery & Sizzle Element Selector","tags":["Engineering","JQuery"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/4eb8d5a3c886c469b47f2341713e60af/e7487/jquery-sizzle-element-selector-150x150.webp","srcSet":"/static/4eb8d5a3c886c469b47f2341713e60af/e7487/jquery-sizzle-element-selector-150x150.webp 150w","sizes":"(max-width: 150px) 100vw, 150px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},{"node":{"excerpt":"Hi guys! When you write test cases, do you face the problem of sharing your test cases with your team members or having to use multiple…","fields":{"slug":"/engineering/how-to-maintain-test-cases-in-excel-sheets/"},"html":"<p>Hi guys! When you write test cases, do you face the problem of sharing your test cases with your team members or having to use multiple colors for test cases?<br>\nI have a solution for these problems that is to maintain your test cases in an excel sheet.</p>\n<p><strong>Definition</strong><br>\nTest cases are the part of testing by which a product can be tested properly according to a set of requirements.</p>\n<p><strong>Advantages of using test cases in excel sheets</strong></p>\n<ol>\n<li>Easily handle the test cases in the sheet.</li>\n<li>Easily attach links.</li>\n<li>Easily share sheets with team members.</li>\n<li>Easily use multiple colors in a sheet.</li>\n</ol>\n<p><strong>Standard format of Test Cases</strong><br>\nSome common fields that are used in test case writing are:  </p>\n<p><img src=\"/b1bc390ecfae97bd0b9dc225d2a551e5/1.webp\" alt=\"1\"></p>\n<ol>\n<li>\n<ol>\n<li>\n<p><strong>Test Case Id:</strong> This field is defined by what type of system we are testing. Below are the standard rules:</p>\n<ul>\n<li>If we are making a test case for any application which doesn’t belong to any specific module then ID would start as TEST_ID 1.</li>\n<li>If we are making test cases for any specific module then ID would be used as MOD_ID 1.</li>\n<li>If test case has more than one expected result then we can use test cases as TEST_ID 1.1,TEST_ID 1.2 etc. All these test cases are a sub-part of TEST_ID 1.</li>\n</ul>\n</li>\n</ol>\n</li>\n</ol>\n<p>In this way we can maintain all the test case IDs and if in the future we can get any requirement or change logs then easily add or change the test case using the following  standard rules without changing the test case IDs of previously written test cases.</p>\n<p><strong>Note:</strong> Test Case Id always uses capital letters.</p>\n<ol>\n<li><strong>Feature Of Product:</strong> This field defines the feature of a product for the type of product we are using.The main advantage of maintaining this field is, in the future if any requirements change then we can easily calculate how many test cases are affected by this and we will change or remove the test cases.**</li>\n<li><strong>Feature Description:</strong> This field explains what type of feature we will test on which condition.**</li>\n<li><strong>Steps To Execute:</strong> These are the steps to be executed on the system being tested to get the expected results. Steps should be understandable and correct. They are written and executed according to a sequence.**</li>\n<li><strong>Expected Result:</strong> These are the wanted outputs from the execution steps performed. Results should be clearly defined for every step. It specifies what are the specifications and what we will get from a particular specification.</li>\n<li><strong>Actual Result:</strong> This field has the real result after the performed execution steps on the system under testing. If the result matches with the expected result then we can write as expected.</li>\n<li><strong>Pass/Fail:</strong> If the result is showing according to the expected result, mark as pass and if not get the output according to the expected, result mark as fail. You are using color for status. Use the green color for Pass and red color for Fail.</li>\n<li><strong>Comment:</strong> This column is for additional information for e.g. if status is set to “cannot be tested”,  then tester can give the reason in this column.**</li>\n</ol>\n<p>Here I have explained a very general format, this will cover almost all the scenarios but we can not assure that all the requirements have been covered, you can proceed the following way to cover all requirements.</p>\n<p><strong>Knowing that all the Requirements have been covered</strong><br>\nTo know that all the requirements have been covered, you need to maintain a Traceability Matrix documentation. Let's take a look on how to create this document.</p>\n<p>Traceability Matrix is a document which provides linking between the requirements and the product which we have developed.<br>\nTraceability Matrix can be divided into 2 parts:-</p>\n<ul>\n<li>Summary</li>\n<li>Traceability Matrix</li>\n<li>\n<p><strong>Summary</strong> :-\nThis section contains a summary of requirements like</p>\n<p>1.1 <strong>Item</strong>: This field contains short descriptions of the items which will be tested.<br>\n1.2 <strong>Product Name</strong>: It contains the product name which you want to test.<br>\n1.3 <strong>Product Version</strong>: It contains the product version which you want to test.<br>\n1.4 <strong>Prerequisites</strong>: Prerequisites are the requirement of a system which are<br>\nneeded before we start testing. Prerequisites could be:</p>\n</li>\n<li>A certain page that a user needs to be on</li>\n<li>A certain data that should be in the system</li>\n<li>\n<p>A certain action to be performed before execution steps are performed.  </p>\n<p>Prerequisites should be satisfied before the test case execution starts.</p>\n<p>1.5 <strong>Change Prerequisites</strong>: Changes that were not necessary before but now are necessary for the system.<br>\n1.6 <strong>Exit Criteria</strong>: This field contains the requirements that must be fulfilled<br>\nin order to announce the completion of testing.<br>\n1.7 <strong>Test Summary</strong>: This field contains the status of the product: how many test<br>\ncases are passed, how many are failed, how many are on hold or how many   are  Invalid etc.  </p>\n</li>\n</ul>\n<p><img src=\"/2c6688ba069851b8588d2aefe99326cb/2.webp\" alt=\"2\"></p>\n<ol start=\"2\">\n<li>\n<p><strong>Traceability Matrix</strong> :  </p>\n<p>Traceability Matrix covers all the product requirements.We can say that it is a document which maps and traces requirements with test cases. Prime fields of this traceability matrix are</p>\n<p>2.1 <strong>Requirement Id</strong>: This field identifies all the testable requirements.<br>\n2.2 <strong>Requirement Description</strong>:  This field contains the short<br>\ndescription of requirements.<br>\n2.3 <strong>Test Case Id</strong>: According to requirements description which test case id is<br>\ncovered.<br>\n2.4 <strong>Status</strong>: Mention here the status of test cases such as passed, failed, on hold or<br>\ninvalid.</p>\n</li>\n</ol>\n<p>As per the image below:  </p>\n<p><img src=\"/dde58b4583bb0f3246c9a33065b8be4d/3.webp\" alt=\"3\"><br>\nRequirement ID REQ_ID 1 covered in Test Case Id TEST_ID 1 and TEST_ID 2<br>\nRequirement ID REQ_ID 2 covered in Test Case Id TEST_ID 3 ,TEST_ID 4, TEST_ID 5</p>\n<p><strong>Advantages of using Traceability Matrix</strong></p>\n<ol>\n<li>Easily identify missing functionality.</li>\n<li>Easily cover all customer requirements.</li>\n<li>Make sure that all requirements are covered by developers in test cases</li>\n<li>If any change request is made we can easily change in test cases.</li>\n</ol>\n<p>So we can say that test cases are easily handled in excel sheets. We can use multiple colors in excel sheets for test cases, easily attach links with test cases and easily trace test cases.</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":"November 03, 2015","updated_date":null,"description":"Learn how to maintain test cases in Excel sheets","title":"Maintain Test Cases in Excel Sheets","tags":["Excel","Tes"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.7699115044247788,"src":"/static/e0fafb559e2ab74897544f5b5e92f003/58556/test_cases.webp","srcSet":"/static/e0fafb559e2ab74897544f5b5e92f003/61e93/test_cases.webp 200w,\n/static/e0fafb559e2ab74897544f5b5e92f003/1f5c5/test_cases.webp 400w,\n/static/e0fafb559e2ab74897544f5b5e92f003/58556/test_cases.webp 800w,\n/static/e0fafb559e2ab74897544f5b5e92f003/99238/test_cases.webp 1200w,\n/static/e0fafb559e2ab74897544f5b5e92f003/135cd/test_cases.webp 1280w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Shefali Yaduvanshi","github":null,"avatar":null}}}},{"node":{"excerpt":"Are you afraid of hackers and feel unsafe for admin and front user to login through same area? No need to worry as in this article, I am…","fields":{"slug":"/engineering/separate-login-page-for-admin-and-user/"},"html":"<p>Are you afraid of hackers and feel unsafe for admin and front user to login through same area?<br>\nNo need to worry as in this article, I am going to guide you with how to create separate login area for admin. Along with that, I will also provide the required steps to disable administrator login through user/login page.</p>\n<p>Please follow the following implementation steps.</p>\n<p><strong>Step by step Guide:</strong></p>\n<ol>\n<li>In the first step, you need to implement <a href=\"https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7.x\">hook_menu</a> in your module file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Admin Login Page&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;page callback&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;yourmodule_admin_login_page&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;page arguments&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk11\">array</span><span class=\"mtk1\">(),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;access arguments&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk11\">array</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;access content&#39;</span><span class=\"mtk1\">),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;type&#39;</span><span class=\"mtk1\"> =&gt; MENU_CALLBACK,</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 class=\"mtk12\">$menu_items</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<ol start=\"2\">\n<li>After adding menu in module file, the next step is to define the page callback function yourmodule<em>admin</em>login_page. In this function, we’ll define the layout of admin login page using theme.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">yourmodule_admin_login_page</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\">theme</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;yourmodule_admin_login_template&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<ol start=\"3\">\n<li>Now that you have defined page callback function, the next step is to implement hook_theme in your module file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">array</span><span class=\"mtk1\">(</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&#39;template&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;yourmodule-admin_login&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&#39;render element&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;form&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk8\">&#39;path&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk12\">$path</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 class=\"mtk12\">$theme</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<ol start=\"4\">\n<li>After implementation of hook theme in module file, the next step is to implement preprocess function for template file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk8\">&#39;hidden&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;#value&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;admin_login&#39;</span><span class=\"mtk1\">,</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;#name&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;hidden_admin_login_form&#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 class=\"mtk12\">$variables</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;rendered&#39;</span><span class=\"mtk1\">] = </span><span class=\"mtk11\">drupal_render</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$form</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<p><strong>Note</strong> : In the above code, we have used the hidden element to identify the admin login page.</p>\n<ol start=\"5\">\n<li>After adding menu in module file, the next step is to define the page callback function yourmodule_admin_login_page. In this function, we’ll define the layout of admin login page using theme.</li>\n</ol>\n<p>'yourmodule-admin_login.tpl.php'</p>\n<ol start=\"6\">\n<li>Now paste the following code in yourmodule-admin_login.tpl.php file.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<ol start=\"7\">\n<li>After that, clear your website’s cache and check the following url for your admin login page</li>\n</ol>\n<p>URL : <strong>your-site-domain/admin/login</strong></p>\n<p>All above steps are used to show admin login page. But if you want that only administrator can login through page admin/login then follow the following the next steps.</p>\n<ol>\n<li>In this step, you need to implement <a href=\"https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_form_alter/7.x\">hook_form_alter</a> function. In this function we will add custom validation.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">yourmodule_form_alter</span><span class=\"mtk1\">(&amp;</span><span class=\"mtk12\">$form</span><span class=\"mtk1\">, &amp;</span><span class=\"mtk12\">$form_state</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $form_id</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\">$form_id</span><span class=\"mtk1\"> == </span><span class=\"mtk8\">&#39;user_login&#39;</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$form</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;#validate&#39;</span><span class=\"mtk1\">][] = </span><span class=\"mtk8\">&#39;yourmodule_external_validate&#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></code></pre>\n<ol start=\"2\">\n<li>After that, add the following code to define the custom validation in which only administrator can login.</li>\n</ol>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">roles);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$access_granted</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\">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=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only site administrator can login.&#39;</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\">FALSE</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\">}--&gt;</span></span></code></pre>\n<p><strong>Note</strong>: If you want that administrator can’t login through user login page then add following code to do this.</p>\n<p>Add the mentioned code in function <strong>yourmodule_external_validate</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"7\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">roles);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$user_access_granted</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only front user can login.&#39;</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\">FALSE</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\">else</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\">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\">}--&gt;</span></span></code></pre>\n<p>Complete code of function yourmodule_external_validate looks like:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"8\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">roles);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$access_granted</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\">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=\"mtk15\">else</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only site administrator can login.&#39;</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\">FALSE</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\">else</span><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\">user_load</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$form_state</span><span class=\"mtk1\">[</span><span class=\"mtk8\">&#39;uid&#39;</span><span class=\"mtk1\">]);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$user_access_granted</span><span class=\"mtk1\"> = </span><span class=\"mtk11\">in_array</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;administrator&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$user</span><span class=\"mtk1\">-&gt;</span><span class=\"mtk12\">roles</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\">$user_access_granted</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">      </span><span class=\"mtk11\">form_set_error</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">t</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;Only front user can login.&#39;</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\">FALSE</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\">else</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\">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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}--&gt;</span></span></code></pre>\n<p>If you are searching over the web and can’t find anything to create separate admin login page in drupal, Please follow the mentioned above steps and you are done. Also create different layout for this  admin login page.</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 .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n</style>","frontmatter":{"date":"October 29, 2015","updated_date":null,"description":null,"title":"Separate Drupal Login Page for Admin and User","tags":["Drupal","Admin Panel"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.9047619047619047,"src":"/static/9e0cd76a1ad2ed809f396189f3db918c/58556/drupal.webp","srcSet":"/static/9e0cd76a1ad2ed809f396189f3db918c/61e93/drupal.webp 200w,\n/static/9e0cd76a1ad2ed809f396189f3db918c/1f5c5/drupal.webp 400w,\n/static/9e0cd76a1ad2ed809f396189f3db918c/58556/drupal.webp 800w,\n/static/9e0cd76a1ad2ed809f396189f3db918c/99238/drupal.webp 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Versha Gupta","github":"vershagupta","avatar":null}}}},{"node":{"excerpt":"This tutorial provides a solution to get email alerts, when a unhandled error occurs. For this tutorial, we are using WordPress. Imagine you…","fields":{"slug":"/engineering/how-to-get-email-alerts-for-unhandled-php-exceptions/"},"html":"<p>This tutorial provides a solution to get email alerts, when a unhandled error occurs. For this tutorial, we are using WordPress.</p>\n<p>Imagine you created a php application and it’s running fine.  A couple of days later, a user complains about an error which you’re totally unaware of. Such unhandled errors are very common in php applications. So, to find these issues, we are going to send email notifications whenever an error occurs.</p>\n<p><strong>Step 1.</strong> First of all we need to identify a common application file that include at top of application. in this case the file is “wp-config.php” at the root of your wordpress hosting directory.  </p>\n<p><strong>Step 2.</strong> Let’s add the following line of code in this file under php tag.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk11\">set_error_handler</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;errorHandler&#39;</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// this line of code sets an error handler custom function to handle any php error. And here we pass our custom function that name “errorHandler”</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\">createTable</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$array</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\">is_array</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$array</span><span class=\"mtk1\">) && </span><span class=\"mtk11\">count</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$array</span><span class=\"mtk1\">)&gt;</span><span class=\"mtk7\">0</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&quot;&lt;table border = 1&gt;&lt;tr&gt;&lt;td&gt;&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">foreach</span><span class=\"mtk1\"> (</span><span class=\"mtk12\">$array</span><span class=\"mtk1\"> as </span><span class=\"mtk12\">$key</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk12\">$val</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk12\">$key</span><span class=\"mtk1\"> . </span><span class=\"mtk8\">&quot;&lt;/td&gt;&lt;td&gt;&quot;</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\">is_array</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</span><span class=\"mtk1\">) && </span><span class=\"mtk11\">count</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</span><span class=\"mtk1\">)&gt;</span><span class=\"mtk7\">0</span><span class=\"mtk1\">){</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk11\">createTable</span><span class=\"mtk1\">(</span><span class=\"mtk11\">json_decode</span><span class=\"mtk1\">(</span><span class=\"mtk11\">json_encode</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</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\">else</span><span class=\"mtk1\">{</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">                </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$val</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>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">$errorContent</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&quot;</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=\"mtk12\">$errorContent</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 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=\"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\">type</span><span class=\"mtk3\"> $errorNumber        // This parameter returns error number.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorString           // This parameter returns error string.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorFile               // This parameter returns path of file in which error found.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorLine              // This parameter returns line number of file in which you get an error.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> * </span><span class=\"mtk4\">@param</span><span class=\"mtk3\"> </span><span class=\"mtk10\">type</span><span class=\"mtk3\"> $errorContext         // This parameter return error context.</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\"> */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">function</span><span class=\"mtk1\"> </span><span class=\"mtk11\">errorHandler</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorNumber</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorString</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorFile</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorLine</span><span class=\"mtk1\">,</span><span class=\"mtk12\"> $errorContext</span><span class=\"mtk1\">) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailAddress</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;example@example.com&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailSubject</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;Error on my Application&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;&lt;h2&gt;Error Reporting on :- &lt;/h2&gt;[&#39;</span><span class=\"mtk1\"> . </span><span class=\"mtk11\">date</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Y-m-d h:i:s&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk11\">time</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 class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error Number :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorNumber</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</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 class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error String :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorString</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</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 class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error File :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorFile</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</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 class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error Line :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">print_r</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorLine</span><span class=\"mtk1\">, </span><span class=\"mtk4\">true</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 class=\"mtk12\">$emailMessage</span><span class=\"mtk1\"> .= </span><span class=\"mtk8\">&quot;&lt;h2&gt;Error Context :- &lt;/h2&gt;&quot;</span><span class=\"mtk1\">.</span><span class=\"mtk11\">createTable</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$errorContext</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 class=\"mtk8\">&quot;MIME-Version: 1.0&quot;</span><span class=\"mtk1\"> . </span><span class=\"mtk8\">&quot;rn&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 class=\"mtk8\">&quot;Content-type:text/html;charset=UTF-8&quot;</span><span class=\"mtk1\"> . </span><span class=\"mtk8\">&quot;rn&quot;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk11\">mail</span><span class=\"mtk1\">(</span><span class=\"mtk12\">$emailAddress</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$emailSubject</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$emailMessage</span><span class=\"mtk1\">, </span><span class=\"mtk12\">$headers</span><span class=\"mtk1\">); </span><span class=\"mtk3\">// you may use SMTP, default php mail service OR other email sending process</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Step 3.</strong> Now save the file and upload on server.</p>\n<p>Whenever we got any error in wordpress then above code will send an email to given email-address (example@example.com). You can use the above code on production websites to improve application performance and track all errors that’s are missed.</p>\n<p>Similarly we can use above code in drupal, joomla, and many other content management systems.<br>\nCommon config files on other platforms are listed below:</p>\n<table>\n<thead>\n<tr>\n<th><strong>CMS/application name</strong></th>\n<th><strong>Location of common file</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>4Images Gallery</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>B2 Evolution</td>\n<td>/conf/_basic_config.php</td>\n</tr>\n<tr>\n<td>Boonex Dolphin</td>\n<td>/inc/header.inc.php</td>\n</tr>\n<tr>\n<td>Concrete5</td>\n<td>/config/site.php</td>\n</tr>\n<tr>\n<td>Coppermine Photo Gallery</td>\n<td>/include/config.inc.php</td>\n</tr>\n<tr>\n<td>Crafty Syntax Live Help</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Cube Cart</td>\n<td>/includes/global.inc.php</td>\n</tr>\n<tr>\n<td>dotProject</td>\n<td>/includes/config.php</td>\n</tr>\n<tr>\n<td>Drupal</td>\n<td>/sites/default/settings.php</td>\n</tr>\n<tr>\n<td>e107</td>\n<td>/e107_config.php</td>\n</tr>\n<tr>\n<td>FAQMasterFlex</td>\n<td>/faq_config.php</td>\n</tr>\n<tr>\n<td>Gallery</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Geeklog</td>\n<td>/db-config.php or /siteconfig.php or /lib-common.php</td>\n</tr>\n<tr>\n<td>glfusion</td>\n<td>/private/db-config.php</td>\n</tr>\n<tr>\n<td>Hotaru</td>\n<td>/hotaru_settings.php</td>\n</tr>\n<tr>\n<td>Joomla</td>\n<td>/configuration.php</td>\n</tr>\n<tr>\n<td>LiveSite</td>\n<td>/livesite/config.php</td>\n</tr>\n<tr>\n<td>LifeType</td>\n<td>/config/config.properties.php</td>\n</tr>\n<tr>\n<td>Mambo</td>\n<td>/configuration.php</td>\n</tr>\n<tr>\n<td>Marketecture</td>\n<td>/include/config.php</td>\n</tr>\n<tr>\n<td>MODx</td>\n<td>/manager/includes/config.inc.php</td>\n</tr>\n<tr>\n<td>Moodle</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>MyBB</td>\n<td>/inc/config.php</td>\n</tr>\n<tr>\n<td>Noahs Classifieds</td>\n<td>/app/config.php</td>\n</tr>\n<tr>\n<td>Nucleus</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>ocPortal</td>\n<td>/info.php</td>\n</tr>\n<tr>\n<td>OpenCart</td>\n<td>/config.php or /admin/config.php</td>\n</tr>\n<tr>\n<td>osCommerce</td>\n<td>/includes/configure.php or /admin/includes/configure.php</td>\n</tr>\n<tr>\n<td>Oxwall</td>\n<td>/ow_includes/config.php</td>\n</tr>\n<tr>\n<td>PHP-Nuke</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>phpBB</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>phpFormGenerator</td>\n<td>/index.php or /mysql.class.php</td>\n</tr>\n<tr>\n<td>phpFreeChat</td>\n<td>/forms/admin/config.inc.php (only if you have saved form input to a database)</td>\n</tr>\n<tr>\n<td>PHPlist</td>\n<td>/config/config.php</td>\n</tr>\n<tr>\n<td>phpMyDirectory</td>\n<td>/defaults.php</td>\n</tr>\n<tr>\n<td>phpWCMS</td>\n<td>/include/inc_conf/conf.inc.php</td>\n</tr>\n<tr>\n<td>phpWebSite</td>\n<td>/conf/config.php</td>\n</tr>\n<tr>\n<td>PhpWiki</td>\n<td>/admin.php or /lib/config.php</td>\n</tr>\n<tr>\n<td>Pligg</td>\n<td>/libs/dbconnect.php</td>\n</tr>\n<tr>\n<td>Post-Nuke</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>PrestaShop</td>\n<td>/config/settings.inc.php</td>\n</tr>\n<tr>\n<td>Saurus CMS</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>ShopSite</td>\n<td>/includes/configure.php or /admin/includes/configure.php</td>\n</tr>\n<tr>\n<td>Siteframe</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Simple Machines Forum</td>\n<td>/Settings.php</td>\n</tr>\n<tr>\n<td>Soholaunch</td>\n<td>/sohoadmin/config/isp.conf.php</td>\n</tr>\n<tr>\n<td>SugarCRM</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Textpattern</td>\n<td>/textpattern/config.php</td>\n</tr>\n<tr>\n<td>TikiWiki</td>\n<td>/db/local.php</td>\n</tr>\n<tr>\n<td>Tomato Cart</td>\n<td>/includes/configure.php</td>\n</tr>\n<tr>\n<td>TYPO3</td>\n<td>/typo3conf/localconf.php</td>\n</tr>\n<tr>\n<td>WebCalendar</td>\n<td>/includes/settings.php</td>\n</tr>\n<tr>\n<td>WHMCS</td>\n<td>/configuration.php</td>\n</tr>\n<tr>\n<td>WordPress</td>\n<td>/wp-config.php</td>\n</tr>\n<tr>\n<td>X7 Chat</td>\n<td>/config.php</td>\n</tr>\n<tr>\n<td>Xoops</td>\n<td>/mainfile.php</td>\n</tr>\n<tr>\n<td>Zen Cart</td>\n<td>/includes/configure.php or /admin/includes/configure.php</td>\n</tr>\n<tr>\n<td>Zikula</td>\n<td>/config.php</td>\n</tr>\n</tbody>\n</table>\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 .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n</style>","frontmatter":{"date":"October 26, 2015","updated_date":null,"description":null,"title":"How to Get Email Alerts for Unhandled PHP Exceptions","tags":["PHP","Email"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/7cc01786c805c6dabe755c22c0e6b3fb/7fbdd/email-alerts-unhandled-php.webp","srcSet":"/static/7cc01786c805c6dabe755c22c0e6b3fb/61e93/email-alerts-unhandled-php.webp 200w,\n/static/7cc01786c805c6dabe755c22c0e6b3fb/1f5c5/email-alerts-unhandled-php.webp 400w,\n/static/7cc01786c805c6dabe755c22c0e6b3fb/7fbdd/email-alerts-unhandled-php.webp 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}}]},"markdownRemark":{"excerpt":"Introduction Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT…","fields":{"slug":"/engineering/how-to-integrate-jwt/"},"html":"<h2 id=\"introduction\" style=\"position:relative;\"><a href=\"#introduction\" aria-label=\"introduction 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>Introduction</h2>\n<p>Ever wondered how apps like Spotify, Netflix, or Slack manage seamless login experiences across devices? Many of them use JWT, or JSON Web Tokens, a compact, stateless method for securely transmitting user identity and session data across services.</p>\n<p>With JWT token authentication, identity information is embedded in a signed token, allowing you to maintain user sessions without server-side storage. This approach is highly scalable and ideal for modern architectures like SPAs, mobile apps, and microservices.</p>\n<p>In this blog, we’ll walk you through what is JWT, why use it, and how to implement JWT authentication using LoginRadius. </p>\n<p>You’ll learn what JWT is, why it’s effective, and how it works in real-world applications. We'll cover both integration methods (IDX and Direct API), generating your signing key, managing sessions, storing the JWT token securely, and applying best practices throughout.</p>\n<p>Whether you're a developer, product manager, or IAM architect, this guide offers a complete foundation for implementing JWT token authentication into your application stack.</p>\n<h2 id=\"what-is-jwt\" style=\"position:relative;\"><a href=\"#what-is-jwt\" aria-label=\"what is jwt 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 JWT?</h2>\n<p><a href=\"https://www.loginradius.com/blog/engineering/jwt/\">JSON Web Token (JWT)</a> is an open standard (RFC 7519) used to transmit information securely between parties as a JSON object. It’s compact, self-contained, and digitally signed, making it a reliable format for authentication and authorization across modern applications.</p>\n<p>A JWT consists of three parts:</p>\n<ol>\n<li><strong>Header –</strong> Contains metadata like the type of token and signing algorithm (e.g., HS256).</li>\n<li><strong>Payload –</strong> Stores the actual data or “claims,” such as user ID, roles, and token expiry.</li>\n<li><strong>Signature –</strong> A cryptographic hash that ensures the token hasn’t been tampered with.</li>\n</ol>\n<p><em>Example of a token structure:</em></p>\n<p>&#x3C;base64Header>.&#x3C;base64Payload>.&#x3C;signature></p>\n<h2 id=\"why-use-jwt\" style=\"position:relative;\"><a href=\"#why-use-jwt\" aria-label=\"why use jwt 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 Use JWT?</h2>\n<ul>\n<li><strong>Stateless Authentication</strong>: No server-side session storage is needed — the token holds all necessary user info. </li>\n<li><strong>Portable</strong>: Works seamlessly across domains, services, and APIs. </li>\n<li><strong>Scalable</strong>: Ideal for microservices, SPAs, mobile apps, and serverless functions. </li>\n<li><strong>Interoperable</strong>: JWTs are supported across many languages and frameworks.</li>\n</ul>\n<h2 id=\"how-jwt-works\" style=\"position:relative;\"><a href=\"#how-jwt-works\" aria-label=\"how jwt works 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>How JWT Works?</h2>\n<p><img src=\"/f29edbf2978577390c7ffa02e9bc4dda/lr-JWT-authentication.webp\" alt=\"Flowchart illustrating LoginRadius JWT authentication via Identity Provider (IDP), showing user redirection from login icon to login page, authentication with IDP, JWT token validation, and subsequent redirection to the customer&#x27;s website or error page based on validation results.\"></p>\n<ol>\n<li>A user logs in with credentials. </li>\n<li>Your app (or identity provider like LoginRadius) issues a signed JWT. </li>\n<li>The client stores the token and sends it with each request (usually in the Authorization header). </li>\n<li>The server validates the token’s signature and claims. </li>\n<li>If valid, access is granted — without any session stored on the backend.</li>\n</ol>\n<p>JWT simplifies identity verification, especially when you're building apps that talk to APIs or need to scale without centralized session storage.</p>\n<h2 id=\"jwt-authentication-with-loginradius-overview\" style=\"position:relative;\"><a href=\"#jwt-authentication-with-loginradius-overview\" aria-label=\"jwt authentication with loginradius overview 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>JWT Authentication with LoginRadius: Overview</h2>\n<p>LoginRadius provides robust support for JWT (JSON Web Token) authentication, which allows for flexible and secure access control across different digital platforms. Whether you're building a fully custom identity flow or using a pre-built interface, the platform supports various integration approaches depending on your architecture.</p>\n<p>If you're looking to understand how to implement JWT token authentication effectively, LoginRadius offers two primary implementation models that cater to different levels of customization and control:</p>\n<h3 id=\"1-idx-implementation--jwt-through-a-hosted-login-page\" style=\"position:relative;\"><a href=\"#1-idx-implementation--jwt-through-a-hosted-login-page\" aria-label=\"1 idx implementation  jwt through a hosted 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>1. IDX Implementation – JWT through a Hosted Login Page</h3>\n<p>The IDX-hosted login approach enables secure, standards-compliant, JWT-based authentication without requiring you to build a custom login interface. This is a strategic option for fast, compliant, and user-friendly deployments.</p>\n<ul>\n<li>The Identity Experience Framework (IDX) comes with a fully custom branded hosted login page.</li>\n<li>Once the user logs in and gets enrolled, the user’s JWTs are automatically generated and issued. These tokens can be utilized for managing user sessions and accessing the APIs.</li>\n<li>This approach simplifies deployment without compromising on user experience and security standards.</li>\n</ul>\n<h3 id=\"configuration-steps\" style=\"position:relative;\"><a href=\"#configuration-steps\" aria-label=\"configuration steps 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><strong>Configuration Steps:</strong></h3>\n<ol>\n<li>Enable JWT Login</li>\n<li>Go to <a href=\"https://console.loginradius.com/authentication/authentication-configuration\">authentication configuration settings</a> and enable JWT Login in the Admin Console.</li>\n</ol>\n<p><img src=\"/9fb19dd9c88c7916aeebd03ab6e661b7/lr-admin-console.webp\" alt=\"Screenshot of LoginRadius Admin Console showing JWT Custom IDP configuration interface with options for provider name, algorithm (HS256), key entry, clock skew, and expiration time settings.\"></p>\n<ol start=\"2\">\n<li>Specify your signing algorithm and expiry policy, and define your JWT Secret Key.</li>\n<li>Input a secure JWT signing key.</li>\n<li>Specify token expiry duration (e.g., 15–60 minutes)</li>\n<li>Select the desired algorithm —HS256 for symmetric signing (same key signs and verifies)</li>\n<li>RS256 for asymmetric signing, where LoginRadius securely stores the private key used to sign the JWT.</li>\n<li>Your app or backend service uses the public key to validate the token signature.</li>\n<li>LoginRadius provides a JWKS (JSON Web Key Set) endpoint to dynamically fetch and rotate public keys, ensuring trust without key exposure.</li>\n<li>Update IDX Template for Callback</li>\n<li>Modify your IDX login page template to retrieve the JWT post-login. You can access the token via redirect URL parameters or secure JavaScript callbacks.</li>\n</ol>\n<h3 id=\"example-response\" style=\"position:relative;\"><a href=\"#example-response\" aria-label=\"example 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>Example Response:</h3>\n<p>{</p>\n<p>  \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR...\",</p>\n<p>  \"expires_in\": 1800</p>\n<p>}</p>\n<p>This integration approach works best for all teams that want effective identity workflows without the complexity of building proprietary login screens, something that is crucial for customer portals, onboarding of mobile applications, and even managing access for business partners.</p>\n<h3 id=\"2-direct-api-implementation--self-managed-login\" style=\"position:relative;\"><a href=\"#2-direct-api-implementation--self-managed-login\" aria-label=\"2 direct api implementation  self managed login 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>2. Direct API Implementation – Self Managed Login</h3>\n<p>If you’re building a custom login UI or working in a headless environment, LoginRadius lets you generate and handle JWTs directly through its <a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/\">Authentication APIs</a>. Here’s how you can programmatically perform token authentication using the classic method:</p>\n<ul>\n<li>For custom front-end applications, LR offers an API to authenticate users and issue JWT tokens.</li>\n<li>In response to the login request, the developers are provided with signed tokens that can be validated on the client’s side or by downstream services.</li>\n<li>This method is best fit for enterprise applications that have complex custom workflows or are designed to be embedded into other applications.</li>\n</ul>\n<h3 id=\"configuration-steps-1\" style=\"position:relative;\"><a href=\"#configuration-steps-1\" aria-label=\"configuration steps 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><strong>Configuration Steps:</strong></h3>\n<h4 id=\"step-1-authenticate-via-api\" style=\"position:relative;\"><a href=\"#step-1-authenticate-via-api\" aria-label=\"step 1 authenticate via 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>Step 1: Authenticate via API:</h4>\n<ul>\n<li>\n<p>Send a POST login request to the LR Authentication URL: </p>\n<p>POST /identity/v2/auth/login</p>\n</li>\n</ul>\n<p>Include the user’s credentials (email + password) in the request body.</p>\n<h4 id=\"step-2-get-jwt-in-response\" style=\"position:relative;\"><a href=\"#step-2-get-jwt-in-response\" aria-label=\"step 2 get jwt in 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>Step 2: Get JWT in Response</h4>\n<ul>\n<li>If the user credentials are authentic, then the JWT token will be available in response.</li>\n</ul>\n<p>{</p>\n<p> \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",</p>\n<p> \"expires_in\": 3600</p>\n<p>}</p>\n<h4 id=\"step-3-jwt-decoding-and-validation\" style=\"position:relative;\"><a href=\"#step-3-jwt-decoding-and-validation\" aria-label=\"step 3 jwt decoding and validation 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>Step 3: JWT Decoding and Validation</h4>\n<ul>\n<li>Use any JWT library (e.g., jsonwebtoken for Node.js or pyjwt for Python) to decode the token.</li>\n<li>Validate the signature using your configured secret key.</li>\n<li>Confirm claims like exp, iat, aud, and iss.</li>\n</ul>\n<h4 id=\"step-4-set-custom-claims-optional\" style=\"position:relative;\"><a href=\"#step-4-set-custom-claims-optional\" aria-label=\"step 4 set custom claims optional 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>Step 4: Set Custom Claims (Optional)</h4>\n<p>With LoginRadius, it is possible to customize the payload to include user roles and/or any additional metadata. You can set custom JWT claims on the Admin Console.</p>\n<p>With this method, you have complete customization over login flows while using LoginRadius to issue signed JWTs for user session management.</p>\n<p><strong>NOTE-</strong> With either method, LoginRadius ensures that JWTs are securely signed, optionally short-lived, and compatible with standard token validation libraries, making integration seamless for everyone.</p>\n<p>To get started with JWT implementation, you can<a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\"> read our complete developer documentation</a>. </p>\n<h2 id=\"hosted-login-vs-direct-api\" style=\"position:relative;\"><a href=\"#hosted-login-vs-direct-api\" aria-label=\"hosted login vs direct 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>Hosted Login vs Direct API</h2>\n<p><img src=\"/15ec02ac98d24a9f1f28e5d0f06b9174/IDX-vs-Direct-API-JWT.webp\" alt=\"Illustration showing IDX vs Direct API JWT flow diagram comparing LoginRadius JWT authentication methods via Hosted Login Page (IDX) and Custom Login UI using Direct API, illustrating user login, JWT issuance, and token return process.\"></p>\n<h2 id=\"what-is-session-management-and-how-it-works-with-jwt\" style=\"position:relative;\"><a href=\"#what-is-session-management-and-how-it-works-with-jwt\" aria-label=\"what is session management and how it works with jwt 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 Session Management and How It Works with JWT</h2>\n<p><a href=\"https://www.loginradius.com/blog/identity/user-session-management/\">Session management </a>is how your app keeps track of a user after they log in so they don’t have to prove who they are with every request.</p>\n<p>In traditional apps, sessions are stored on the server using session IDs. Every time a request comes in, the server checks that session ID to verify the user.</p>\n<p>In modern apps, especially SPAs and APIs, JWTs are used to manage sessions without needing server-side storage; this is called stateless session management. The token itself carries the user’s identity, roles, and expiration details. As long as the token is valid, the user stays logged in.</p>\n<p>Good session management ensures:</p>\n<ul>\n<li>Security against session hijacking</li>\n<li>Fast user validation without hitting a database</li>\n<li>Smooth experiences with token refresh strategies</li>\n</ul>\n<h2 id=\"how-loginradius-handles-session-management-with-jwt\" style=\"position:relative;\"><a href=\"#how-loginradius-handles-session-management-with-jwt\" aria-label=\"how loginradius handles session management with jwt 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>How LoginRadius Handles Session Management with JWT:</h2>\n<ol>\n<li>\n<p>User Logs In </p>\n<ul>\n<li>LoginRadius returns an access token (JWT) and, optionally, a refresh token.</li>\n</ul>\n</li>\n<li>\n<p>Client Stores the Token </p>\n<ul>\n<li>Access tokens are stored in memory, sessionStorage, or secure cookies. </li>\n<li>They’re sent on every request via the Authorization: Bearer header. </li>\n</ul>\n</li>\n<li>\n<p>Access Token Expiry </p>\n<ul>\n<li>These tokens are short-lived by design (e.g., 15–30 minutes). </li>\n<li>Once expired, the client can use the refresh token to request a new access token. </li>\n</ul>\n</li>\n<li>\n<p>Token Renewal </p>\n<ul>\n<li>LoginRadius validates the refresh token and issues a new JWT, i.e., no user re-authentication is needed. </li>\n<li>Refresh tokens can be revoked at any time.</li>\n</ul>\n</li>\n<li>Logout and Token Revocation Strategy</li>\n</ol>\n<p>When the user logs out, both the access token and refresh token should be cleared from client storage.</p>\n<ul>\n<li>The refresh token can be explicitly revoked via the LoginRadius API, terminating the ability to renew sessions. </li>\n<li>\n<p>However, access tokens are stateless and cannot be revoked mid-lifecycle unless: </p>\n<ul>\n<li>You maintain a blacklist of token IDs (jti claims) and check them on each request. </li>\n<li>You use short-lived access tokens to limit exposure naturally. </li>\n<li>Or, you rotate your JWT signing key, invalidating all previously issued tokens. </li>\n</ul>\n</li>\n</ul>\n<p>Combining these strategies gives you greater control over token misuse and enables a robust, enterprise-grade logout flow. </p>\n<p><a href=\"https://www.loginradius.com/resource/whitepaper/secure-api-using-oauth2\"><img src=\"/e55ae4bbc8ce62e13f03e46e29ebe7cc/api-economy.webp\" alt=\"illustration showing LoginRadius free downloadable resource named API economy is transforming digitization: how to secure it using oauth 2.0.\"></a></p>\n<h2 id=\"how-to-store-jwt-tokens\" style=\"position:relative;\"><a href=\"#how-to-store-jwt-tokens\" aria-label=\"how to store jwt tokens 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>How to Store JWT Tokens?</h2>\n<p>When you implement JWT-based authentication, the client (browser or mobile app) needs a way to store the access token and, optionally, the refresh token after they are issued by the authentication server. This stored token is then attached to every subsequent request to prove the user's identity.</p>\n<p>Choosing where to store the JWT is a crucial security decision. The most common storage options are:</p>\n<ul>\n<li>localStorage</li>\n<li>sessionStorage</li>\n<li>HTTP-only cookies</li>\n</ul>\n<p>Each option has trade-offs between security, accessibility, and persistence, and the right choice depends on your application's architecture and threat model.</p>\n<h4 id=\"recommended-storage-strategy\" style=\"position:relative;\"><a href=\"#recommended-storage-strategy\" aria-label=\"recommended storage strategy 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>Recommended Storage Strategy</h4>\n<ul>\n<li>\n<p>Access Tokens </p>\n<ul>\n<li>For SPAs: store in memory or sessionStorage for short-term access </li>\n<li>If stored in the browser, protect against XSS </li>\n</ul>\n</li>\n<li>\n<p>Refresh Tokens</p>\n<ul>\n<li>Always store the JWT refresh token in HTTP-only secure cookies to prevent JavaScript access. This adds a critical layer of protection against XSS attacks.</li>\n<li>Combine with SameSite=Strict or SameSite=Lax attributes to mitigate CSRF risks and ensure the JWT refresh token is only sent in intended contexts.</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"best-practices-for-storing-jwts\" style=\"position:relative;\"><a href=\"#best-practices-for-storing-jwts\" aria-label=\"best practices for storing jwts 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>Best Practices for Storing JWTs</h2>\n<ol>\n<li>Never store sensitive tokens (like refresh tokens) in localStorage or sessionStorage.</li>\n<li>Use Secure and HttpOnly flags with cookies to prevent JavaScript access and ensure transmission only over HTTPS.</li>\n<li>Set the SameSite=Strict or Lax attribute on cookies to protect against CSRF.</li>\n<li>Use short-lived access tokens and rotate refresh tokens regularly.</li>\n<li>Implement CSP (Content Security Policy) to reduce XSS risk.</li>\n<li>Avoid storing any tokens in frontend code (e.g., hardcoded in JS files).</li>\n</ol>\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>JWT authentication with LoginRadius offers a modern, stateless approach to managing sessions across distributed systems. The IDX integration is ideal for rapid deployment, while the Direct API model is best for organizations needing deep customization and integration flexibility.</p>\n<p>With robust token signing, refresh capabilities, and centralized control, LoginRadius provides a future-ready foundation for secure, scalable identity architecture. <a href=\"https://www.loginradius.com/contact-us?utm_source=blog&#x26;utm_medium=web&#x26;utm_campaign=how-to-integrate-jwt\">Contact us</a> to know more about JWT authentication and implementation guide. </p>\n<h2 id=\"faqs\" style=\"position:relative;\"><a href=\"#faqs\" aria-label=\"faqs 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>FAQs</h2>\n<h3 id=\"1-what-is-jwt-authentication-used-for\" style=\"position:relative;\"><a href=\"#1-what-is-jwt-authentication-used-for\" aria-label=\"1 what is jwt authentication used for 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>1. What is JWT authentication used for?</h3>\n<p><strong>A:</strong> JWT authentication securely verifies user identities, enabling stateless session management across web, mobile apps, and microservices without server-side session storage.</p>\n<h3 id=\"2-how-does-loginradius-simplify-jwt-integration\" style=\"position:relative;\"><a href=\"#2-how-does-loginradius-simplify-jwt-integration\" aria-label=\"2 how does loginradius simplify jwt integration 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>2. How does LoginRadius simplify JWT integration?</h3>\n<p><strong>A:</strong> LoginRadius simplifies JWT integration by offering hosted <a href=\"https://www.loginradius.com/docs/single-sign-on/federated-sso/jwt-login/jwt-implementation-guide/\">IDX login pages </a>and direct API-based authentication methods, enabling rapid deployment and deep customization.</p>\n<h3 id=\"3-is-jwt-authentication-secure\" style=\"position:relative;\"><a href=\"#3-is-jwt-authentication-secure\" aria-label=\"3 is jwt authentication secure 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>3. Is JWT authentication secure?</h3>\n<p><strong>A:</strong> Yes, JWT authentication is secure when implemented with best practices like short-lived tokens, secure storage methods, signature validation, and refresh token rotation.</p>\n<h3 id=\"4-can-jwt-tokens-be-revoked-with-loginradius\" style=\"position:relative;\"><a href=\"#4-can-jwt-tokens-be-revoked-with-loginradius\" aria-label=\"4 can jwt tokens be revoked with 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>4. Can JWT tokens be revoked with LoginRadius?</h3>\n<p><strong>A:</strong> Yes, LoginRadius allows<a href=\"https://www.loginradius.com/docs/api/v2/customer-identity-api/refresh-token/revoke-refresh-token/?q=revoke+jwt\"> revocation of JWT</a> refresh tokens explicitly, and supports strategies like short-lived tokens and key rotation to manage token lifecycles securely.</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":"April 15, 2025","updated_date":null,"description":"Discover JWT (JSON Web Token) authentication, its advantages, and how to integrate it seamlessly using LoginRadius' hosted IDX and Direct API methods for secure, scalable identity management.","title":"JWT Authentication with LoginRadius: Quick Integration Guide","tags":["JWT","JSON Web Token","Authentication","Authorization"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":0.7782101167315175,"src":"/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp","srcSet":"/static/4cedb7829f98208cbc6d5a9aea4e983d/61e93/how-to-integrate-jwt.webp 200w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1f5c5/how-to-integrate-jwt.webp 400w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/58556/how-to-integrate-jwt.webp 800w,\n/static/4cedb7829f98208cbc6d5a9aea4e983d/1cc9f/how-to-integrate-jwt.webp 896w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},"pageContext":{"limit":6,"skip":270,"currentPage":46,"type":"//engineering//","numPages":53,"pinned":"5c425581-f474-5ae9-abe7-cf5342db2aaa"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}