{"componentChunkName":"component---src-templates-blog-list-template-js","path":"/engineering/48","result":{"data":{"allMarkdownRemark":{"edges":[{"node":{"excerpt":"Did you ever want to customize your registration or login page on Drupal 7, but did not know how? Customizing these pages by adding new text…","fields":{"slug":"/engineering/customize-user-login-register-and-forgot-password-page-in-drupal-7/"},"html":"<p>Did you ever want to customize your registration or login page on Drupal 7, but did not know how? Customizing these pages by adding new text or changing theme is not a difficult task.</p>\n<p>To help you out with that, I have compiled some simple steps to customize your registration or login page. All that you need to do is to add the following code :</p>\n<h3 id=\"steps\" style=\"position:relative;\"><a href=\"#steps\" aria-label=\"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>Steps:</h3>\n<ol>\n<li>In the first step of customization, you need to implement <a href=\"https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_theme/7.x\">hook_theme</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\">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;user_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=\"mtk11\">drupal_get_path</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;module&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;yourmodule&#39;</span><span class=\"mtk1\">) . </span><span class=\"mtk8\">&#39;/templates&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;user_pass&#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;template&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;user_pass&#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=\"mtk11\">drupal_get_path</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;theme&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;yourmodule&#39;</span><span class=\"mtk1\">) . </span><span class=\"mtk8\">&#39;/templates&#39;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    ),</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk8\">&#39;user_register&#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;template&#39;</span><span class=\"mtk1\"> =&gt; </span><span class=\"mtk8\">&#39;user_register&#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=\"mtk11\">drupal_get_path</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;theme&#39;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&#39;yourmodule&#39;</span><span class=\"mtk1\">) . </span><span class=\"mtk8\">&#39;/templates&#39;</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<p>Now that you have implemented hook theme in module file, the next step is to implement three pre-process functions. These functions are used if module needs to override or you want to add something in theme pre-processing.</p>\n<p>In the third step, you need to create following template files for login/register/forgot password.</p>\n<ol>\n<li>user_login.tpl.php</li>\n<li>user_register.tpl.php</li>\n<li>user_pass.tpl.php</li>\n</ol>\n<p>Now paste the following code into user_login.tpl.php. Also, don’t forget to modify user_register.tpl.php and user_pass.tpl.php template files accordingly.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"php\" data-index=\"1\"><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\">  </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">--&gt;</span></span></code></pre>\n<p>Now your login page will contain new intro text <strong>This is my awesome login form</strong>. Customization of registration page in Drupal 7 is not difficult and if you follow above mentioned tips, you can design an amazing registration / login / forgot password page according to your audience.</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</style>","frontmatter":{"date":"August 11, 2015","updated_date":null,"description":null,"title":"Customize User Login, Register and Forgot Password  Page in Drupal 7","tags":["Drupal"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/26f698c9942b635d0137bd4039e85ba7/7d145/drupal-custom-login-register-password-pages1.png","srcSet":"/static/26f698c9942b635d0137bd4039e85ba7/69585/drupal-custom-login-register-password-pages1.png 200w,\n/static/26f698c9942b635d0137bd4039e85ba7/497c6/drupal-custom-login-register-password-pages1.png 400w,\n/static/26f698c9942b635d0137bd4039e85ba7/7d145/drupal-custom-login-register-password-pages1.png 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Versha Gupta","github":"vershagupta","avatar":null}}}},{"node":{"excerpt":"QQ is the most popular ID provider for Chinese people since the 90s, it is always the first choice for websites who want to provide social…","fields":{"slug":"/engineering/best-practice-reviewing-qq-app/"},"html":"<p>QQ is the most popular ID provider for Chinese people since the 90s, it is always the first choice for websites who want to provide social login functionality for their Chinese users. But similar to other ID providers from China, the app you created needs to be reviewed before actually launching it. Reading Chinese and using Google translate for each line is not that much of fun, and in this tutorial we will go through step by step to figure out how to submit a QQ app for review. Do note: You can always download a Google translate extension for your browser to translate each page to English, it would probably be the easiest way for you, but here I decide to keep it Chinese, Let's go.</p>\n<ol>\n<li>\n<h3 id=\"navigatetoqq-connect\" style=\"position:relative;\"><a href=\"#navigatetoqq-connect\" aria-label=\"navigatetoqq connect 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>Navigate to <a href=\"http://connect.qq.com/\">QQ Connect</a></h3>\n<p>And click the 4th tab (in orange box)  </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 6.923076923076923%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAIAAABR8BlyAAAACXBIWXMAAAsTAAALEwEAmpwYAAAASElEQVQI1wE9AML/AOre2Mu8s9PW2NDQ0O/v7/////z8/Pf39/T09PPz8/Py8pzQ7rHW7vj08vb3+Pr6+vn5+f39/fn5+f///2uxN0VcL5Y7AAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"homepage\"\n        title=\"homepage\"\n        src=\"/static/d2c40003bfa59e2135ccfcfc4fd01ee7/e5715/Homepage.png\"\n        srcset=\"/static/d2c40003bfa59e2135ccfcfc4fd01ee7/a6d36/Homepage.png 650w,\n/static/d2c40003bfa59e2135ccfcfc4fd01ee7/e5715/Homepage.png 768w,\n/static/d2c40003bfa59e2135ccfcfc4fd01ee7/c27e7/Homepage.png 2144w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n</li>\n<li>\n<h3 id=\"registration\" style=\"position:relative;\"><a href=\"#registration\" aria-label=\"registration 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>Registration</h3>\n<p>After being redirected to <a href=\"http://connect.qq.com/manage/login\">QQ connect login page</a>, it asks you to fill in your credentials, since I do not have one, I will register for one and feel free to skip this step if you have already got one.</p>\n<p>Click \"register a new account\", like shown:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 61.53846153846154%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAChUlEQVQoz2OIj4v3dHb0CQj08gsIiYhMy8iMT07X9433iUxMTEqOTUiOSwSilPikFCAjITk1AcyIByMGefswI5dgQ5cQfecQbccgdVt/LXt/DVt/dVs/TTs/LTs/HQd/bXt/IAlC9v4GLiEmHhEmHuGmHhEMIpahXmEJ3lGpHhGJSdnFda09VU2dNS1dtS1dda1dje3dTW1dDS3tTa3tza3trR1dOfmFQeHRIdGJAZHxDAqOUT7hcWEB/u6W9ouWr/7////fv3//YwMQ8XXr1nn7BUbEpQRFJTA4hCRHxCb6WGvoKGvPXbLq/79/N2/duv/g4bu3b4FKf/z88e79uy9fv3z9+vXHz59AkdVr1gBDB6g5Ki6JQc8r0Tc83jkoWMvJf9GKde/evWtqqJ/Y233y1GmQbX/+/vz298uX75+/fIZoXrV6tZuPX1hscjDQZg23BKDmkJgUN9/QZavWvXn7tqO1oaW+4vDRo0ClH76/ePjp9Pc/H4HsP3/+AMn58+dZ2diFRseDNIs7xOi4R+p7Rsta+fXPW/7zx7eDhw/vO7D/0eOHQKUPPpzeeq/h2eerQPbvvyDNE+culbf0MvCKBupiYDAJ57CK5LSJZtDzq5+xAmQD1gD79+/Prx9AunHOGgYdP1bLaKBGBk2vWH2fOD2fOEWnsLq+GU8fP7p589ZtMLhz587t27du3b557dq1C0cPHd207s61K7V9M4AqDf0Stb3jGHIz01OSEpIT4vKy0jPSUpPBICUlOTUlGQ5SgPyUlKRkEJmRlpaXlZGTmQ5EDCmpaUkpqbGJKSExyYlgaSAAxkRwTApYTypQT1x8UkIiyBCgbGJyamRsdFxiIpABALv+g1MrHZQzAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"qq-register-1024x630\"\n        title=\"qq-register-1024x630\"\n        src=\"/static/52e1d77254054ed5be6de222675042b2/e5715/qq-register-1024x630.png\"\n        srcset=\"/static/52e1d77254054ed5be6de222675042b2/a6d36/qq-register-1024x630.png 650w,\n/static/52e1d77254054ed5be6de222675042b2/e5715/qq-register-1024x630.png 768w,\n/static/52e1d77254054ed5be6de222675042b2/2bef9/qq-register-1024x630.png 1024w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>It will link you to <a href=\"http://zc.qq.com/en/index.html?from=pt\">this page</a>, it is written in English, sweet! I am pretty sure you can register an account by yourself. After filling in the information, it will send a confirmation email to your email box. After your email is verified go back to the <a href=\"http://connect.qq.com/manage/login\">login page</a>, and use the QQ number you just got to log in with.</p>\n</li>\n<li>\n<h3 id=\"creating-the-app\" style=\"position:relative;\"><a href=\"#creating-the-app\" aria-label=\"creating the app permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Creating the app</h3>\n<p>Click the big green button on the right side of your screen to create an app, and here we will create a website type app.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 47.69230769230769%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUElEQVQoz41RTUvDQBDdP+1Zf4rgQeilZxGLKFSIFalCKVWKxdqkMZvsV7JfycaXFGrxIH2HZebtzpt5s+T+5ip6fHoYjzOatW3bNI0xRmsthLSlnKzFyShdJNzpUhvjncMt3lhrQwiE0e+MUppRZ/yu2PfAtbNWVG7FrNLWeweyCcHXABLbNDVZxzGaxNvPt2TiatP+i0byYPQ+JXlelKUWim/ZSttqN5JzDvqIf+tC6A5K53fn0WIQzS7fP24JKGMshkHgfY24KBjnHAooDz2g0s1ad76m08FwdDa8Po2eLwjnAutRSllrhBBVVe08C8GRQgIbAom1IMVujNSa2zxmrW3JfPlijZNSYlpIQKgoCjxN4iRN0yzrtgmAhBfGmCxlpStVKlc7svxa9o7C3t1uEHRDT3RTqgTq3tchuq/KN5v2aBz26IrXs9c/7PFCP/kxPifyfEclAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"create_app_button\"\n        title=\"create_app_button\"\n        src=\"/static/ad1c174a28bc545fb5ca17cc0aac5629/e5715/create_app_button.png\"\n        srcset=\"/static/ad1c174a28bc545fb5ca17cc0aac5629/a6d36/create_app_button.png 650w,\n/static/ad1c174a28bc545fb5ca17cc0aac5629/e5715/create_app_button.png 768w,\n/static/ad1c174a28bc545fb5ca17cc0aac5629/f238d/create_app_button.png 2078w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 58.46153846153847%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAACHElEQVQoz12Ry27aQBSGebmmagVBEDVQ29SYjE2ygxj6IukzNJu0pYrpCihlkSdgF0uAXeMLvmGbmw2eHuO2VD36R5qR5jv/P2cy+eJ58U0hf5Gv169brTbf4m95vnnbbDSbzXYb3XAVRDd4nm+/bzQatdrVn0IIsRm6WqWrdKlc/nh/b1mW4zgu1BKWY8lTS5qa0gTkaXNRFAE48qiW0GyGqlSYWq1wUXz4/IAx3u/3cRwfYhxHYexau/U6cOxou8HBcqHrLFevczfX9UQsyyXO0OaydNn52gF4vdmMx+NnUYyjCPueOJl+6nyRlDnebQxNqyGUK2TPi7lsIVtlmAxiWUhAkFS32wU4DEOIN1dVvE9gwzRHo5HjLvF2DfAVYl/nX51lX7zMnSXwO5qG/KVSWRAEgKMoWi7d7W4Xh2Hk2Ic4Xq1X8AoceLo6h8ss4hiGQdAGcRkIDOnL5beps6Iohm6omm4vDOfnTNV1XdMUVd0stIWuwXQYWEkdB0ZSFHwSQUDsbwBPJhNZlmeSbOqaNZtIcJCkqSStdNU0koFBTDAD8giTBMAkSQlC4qxpmmPbruf5ruMqsuMHnu8vg2Bnm7qqIpZLf/g3TFFkCqfO+/0BpwUDswy8CfDKi9c+9mzLXKTOJxjeADFounp39+Hp6WkwGA6HP1J97/UT9fuDXm80HD4+Cn+xE5zugCcIEiKcRFX+FUVV/oN/ATWFyvw8n61fAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"app_for_website\"\n        title=\"app_for_website\"\n        src=\"/static/bc9023962ef111fd723baa7ff9d86905/e5715/app_for_website.png\"\n        srcset=\"/static/bc9023962ef111fd723baa7ff9d86905/a6d36/app_for_website.png 650w,\n/static/bc9023962ef111fd723baa7ff9d86905/e5715/app_for_website.png 768w,\n/static/bc9023962ef111fd723baa7ff9d86905/0ff19/app_for_website.png 2084w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>After choosing the type, you need to fill in some basic information for your website, in case if you do not use Google translate to translate the page, I did a little translations for you, there you go.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 58.30769230769231%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB/UlEQVQoz22RT4/SQBiH+832YLxoJErWLGSnlU6h/GlXvbguBC7eSLSUj6EnDxz4AiasIZhsNJ52zS5Z2sKWtrbQ6ZQOvrRmownPNNPpNE9/0/flcrknMCQJDwaD89FoPB6fp3xNgcVoNMp2JpPJcDisVqvlFFmWOYzFYrHYbDYjQkgYkpBs98EYg9k0TUVRJEmqVCqyXOEQ4nmETk/fkAgGcZwl4Lpu/C+bHSAbhvHq5eua3FDqaq1a50RR5Hm+2WqSKILvh+u153ngg8L+B2TLnPPS89zRg6fFhwUhz9VqNUEQ2u12BPJ2CwmgUUqTJMlOm5E9gozw4aP8weP8QYF/xpVKJUg+e3sGMph+ym/PWxNK6AakiMYhLNLk2WymNFTxhSSWJLlS5Y4Kh+C3Wi2QKQk913FcL1gFxp0zWzgQGcWJF8aB72f/XK83RCyWyxIUnDtGCGPc6XTgqAvHt2xntbQdy3Qt07+bB8tlEoZss/uRrNonJyqUGhoGMyfwCGoGchSRmG29FbVvptav28XUtq7n1FhslzajlKUNA1lVVcj8KyN0nCVDm+F1GDMniGa2+WN68f364mZxdV+2PTLGUpacyQnbVfXW/flx/O7zt/dfLj+BtUmS/bIoYrjBlqZpuq73enABuqb1NO2D3tPv6ff73W4XWiungPUHGHYMMhGA++kAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"form_with_english_translations\"\n        title=\"form_with_english_translations\"\n        src=\"/static/172606c234c6775b86bb3f66d13bdfba/e5715/form_with_english_translations.png\"\n        srcset=\"/static/172606c234c6775b86bb3f66d13bdfba/a6d36/form_with_english_translations.png 650w,\n/static/172606c234c6775b86bb3f66d13bdfba/e5715/form_with_english_translations.png 768w,\n/static/172606c234c6775b86bb3f66d13bdfba/9e7e4/form_with_english_translations.png 2056w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Here is what I have filled in  </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 60.15384615384616%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABiklEQVQoz4WRy07DMBBF85EsWLPnV1gA34DYwgKJgtgAQgIWlDcKojxapUnaOI4d24lf3CRqQVURV2k00fjeOeMGN73du9PD/uVF//JckMSWVGRJmSUkHuXxKBsPd66/zp4+RTpik1hkKZ/Gik75NKkLEhzdPu7dvT+Gg6eXsKyN9l5oZ503tlFt7OFAPE+U99ZY55x3vn3w8z5YudKrF/z+dZAmKWFS1IaKytq2+Z+Cg0ifxEZqZNpKKSGE1tq5HzNy3B9RgWLZ8CMM30LKC855FEUwd8xumcxMOBDs9be3jtc3emv7/U2EGa2LoiCEVFWFo3amOUtd10opdOEPmCAvbw8TGpWKdr2yLEWrqtVS4A4rwM1KWVnT3iMmG4Ng8MM85+6KuRM1zjSTFyI7VDRmrh9svPWvhZvJC2YpRJ7ntChQU2VKCWyXS/wBHheJXbGXlDKnFPWimbOCMwY/IVmUpEgBh9JWSInZ8CIZYpwvmTxMSZqzxk8pAprNQdiSo4vP8XgMp1QKIN9+HbGVtuCDKwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"lucius_fillin_info\"\n        title=\"lucius_fillin_info\"\n        src=\"/static/3f366e572e6becffefbe1cdb08ecaee1/e5715/lucius_fillin_info.png\"\n        srcset=\"/static/3f366e572e6becffefbe1cdb08ecaee1/a6d36/lucius_fillin_info.png 650w,\n/static/3f366e572e6becffefbe1cdb08ecaee1/e5715/lucius_fillin_info.png 768w,\n/static/3f366e572e6becffefbe1cdb08ecaee1/38116/lucius_fillin_info.png 2086w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Please note, when you fill in your website address, it will ask you to verify your website, so you need to copy and paste the javascript code under your website page, and then click the button beside to verify it.<br>\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 56.15384615384615%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACAElEQVQoz22SQY/SUBSF+7dcuNHNqImRGIZpgZYWUurAEOA/sBETF5qYzACyMi5YmRjjxIEZEocFU0UTjSsEA9FQ+vpaStsHbcdbiqw8aZrX9+7Xc+9pqf396N07e5FIhKYPWq1Wu93udi86G52fB1e7fQab4brTgdNupVJhWTabzVKCwHMcm4gncrmcZVuErEC+71//T57nwb3RaDBxRpICWGAYhuO4fP7Qtm1CHE1DiqIYhrEOtVrD67yN4GkDv0xxwuGjHJXJZASe51i2cHTkOA6c2baFMQYYqv2NQsOd89Pnj2/du8FwUUoUxawogn+pVArh0MRzvV23uym28LMnt/duJlMMBaPTNM2x0HaeELJeEYw1FaQpc/xHRYq+QHhpukEX27ZPjk9i0QMpK1FMnH7w8L4gpIvFIsCOYyMNI01XVGU0HY5/jWfqDJuGbphIn6toDnC9XoeYgrRD53Q6XS6XAUWmoypTE/3E8zGajQw0MfF0gSZYGdlLHexDOJlMSpJE8TxPx2IhbFlLODP1GZ4P7YXurX2PrCEIizjXHoROXNeFglqtlkgkAljgBViF8DYwP6j49vvj+++1Dz+aE33ohan9C6zZbG5hwFIpAT5YoVDo9XqyLF/J/S+Dr6fdN6/evnj97vji8uyT/DnYluV+vz8YDKrVKvwXMPNf0Cbq1Rmr4OgAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"verify_successfully\"\n        title=\"verify_successfully\"\n        src=\"/static/443daae7eb0473185304a49e29295c47/e5715/verify_successfully.png\"\n        srcset=\"/static/443daae7eb0473185304a49e29295c47/a6d36/verify_successfully.png 650w,\n/static/443daae7eb0473185304a49e29295c47/e5715/verify_successfully.png 768w,\n/static/443daae7eb0473185304a49e29295c47/b75f8/verify_successfully.png 2124w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Once all the information is filled, then move on to next step, click the blue text link, it asks you to upload different sizes of the images about your company.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.769230769230774%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABiklEQVQoz41S20rEMBDt1/sLvgo++iwogoqg4Iqi4t3VdZVu2jTbNGmSprnVSbsqyooe0iGdzMmcmUlysLN5en5xPBpRSruu8963WjdNw+vaqHo0rVb2EKa8UVJrba01xjjnwEJwMp6+vszw49NzhgvtOmm80BaOIS44S6S5zhttrHfOfyCEADaS95/Ea4poSZiQyvjGOGVd9z8kl9M5KUtKS8YqAaiFafXncejXD4Cotm0hfzL8a+VcuwgL4Y+EvOY5xnBFcouOzt92rtD+OD8rY35WVRU0j/WoenDOwX55WNXoJsree1jfulndfVg7mWzmOCNkDsjzvCgKQkiGUJZlGGOE0OCBTZqmcEMkg3TFLSzBNTCLAgMTgqCqOBcf/DLloUckCwFDBWlRFHy0h+whYErOh1+QEPHGlJDaeu8G19Iky8ln0+37dDLDTCkplYK39Z25vOELsqrbGWGU1VKIqBNq4HywSqnfprUgH443rid3KJtjnENjodVDV6HDsOnLj6MCD9gf5Hc4t+l+RX194wAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"add_assets\"\n        title=\"add_assets\"\n        src=\"/static/1c6abeed43cc1b132fcf8716aba885a0/e5715/add_assets.png\"\n        srcset=\"/static/1c6abeed43cc1b132fcf8716aba885a0/a6d36/add_assets.png 650w,\n/static/1c6abeed43cc1b132fcf8716aba885a0/e5715/add_assets.png 768w,\n/static/1c6abeed43cc1b132fcf8716aba885a0/f238d/add_assets.png 2078w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 59.53846153846154%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABS0lEQVQoz4WRS0vDQBSF86/8R67c6N6l+4JuXHSlK/eCiOATrViUQomtiNS+qG1qkpnk3nmPY5JCSkr7Mcxi7pw5d871ns5PH2+v7+4fOp13a60SkgEklJA4iqOo9hxcdgKRxAjIEQVjbknOrdYM0Tvw4agd9r77g9E4Qkm5okzZBSCN1LaMccu4zSIyb6clDrtAot80TQEZcs6FsGspxIx5NMHJzzwMiVI6CAJCSF5eiV5QiOfh7OOrO5oO3W+ca0LphKJUumqolJJSioxCfOEfnzT2643dz1nTHQlXZWiUrLaqSxTiBMgkGFGMpXbPShf0APRLqECZPJ4c50YpBYAsk4XzUmPZ3e1X3Loi7fg/c23WBlY+za/Wu3HNJ0M0G8RuztUaAjC+YVoO171Xnn7OXoud9cWcL/25ijZmhfPNOHmbpr0INoi1/gNOQ7ToqskKJgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"upload_different_assets\"\n        title=\"upload_different_assets\"\n        src=\"/static/5f8cf9267cdfee8e942f194c3fe06b17/e5715/upload_different_assets.png\"\n        srcset=\"/static/5f8cf9267cdfee8e942f194c3fe06b17/a6d36/upload_different_assets.png 650w,\n/static/5f8cf9267cdfee8e942f194c3fe06b17/e5715/upload_different_assets.png 768w,\n/static/5f8cf9267cdfee8e942f194c3fe06b17/d50e7/upload_different_assets.png 2280w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span><br>\nThen, it is time to submit by clicking that big green button in the middle.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 58.61538461538461%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAAAsTAAALEwEAmpwYAAABs0lEQVQoz3VSS0/cMBDOT+bWE+qtf6BnLhx66aWVqhZV4oCQaNGKrZCqImDzIu+H4yR2/IrtMN5FLaLL6Mt4LM/n+WZib1Ovjy4Oji/ffFy/+7A6PPpxcOWf5mkZP0RZlsVxFEZRkiTg4zjO8xwWPwjKqlyWxdNm7klbo6LFVdXmeZ3UTYkQIoQopaRUatbGGG2c3wUutsZa68EFgsuuxT0eUIvbpququqwqjDEZx5EKrsyyzxwZ7pqNsrBZXjX7ink9Ky+Dr2GKER4EZ9M0aa1fUB32Vh54vQpPCpDZIZAK6kEsIeOwNWjS5fFpMXoPGbPyYvOlQoxvy3JY4BNCKTtLVxDmQdY/Jedqnu0zCY7MFUnQbT8QSmnf9+DJRGnd3Nyc/fr97frP9+L2mnbdQCkoekm2//Xj9ng4W73/fP720/lhE1wtwk30b+fPBjaQqmmEmuF/AnYB43IWegsjmORCPZ1KODX/yJhwPLKeypEpwmRHxCRmRCQVepJ6FAqCflKEK8pVO3DClLW712K8LC+3KNKsSHN4lcndJgjCeBNEfhDd3fv3fgA+jB5cWubSkvQJj1Y4poW0G83sAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"app_submit\"\n        title=\"app_submit\"\n        src=\"/static/3920bf6485419cf07bd9184e670c0969/e5715/app_submit.png\"\n        srcset=\"/static/3920bf6485419cf07bd9184e670c0969/a6d36/app_submit.png 650w,\n/static/3920bf6485419cf07bd9184e670c0969/e5715/app_submit.png 768w,\n/static/3920bf6485419cf07bd9184e670c0969/1ffbd/app_submit.png 2108w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>Confirm it by clicking the right button again.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 768px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 54%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB4klEQVQoz2WSQYvTQBTH83UEQfAqIgpeXLbJbtJ0kpnJZDKTSerRi19A2EO2vSzsxZMHF2ytvXgR2i609BO4oJYVD7UVZClIy9KlZOvr1ByKPx7hzeP937y8N0aZlB6U7jw07z4+vP/Iugf+nvsEY4I8z8fY8/2KB54PBhGMMQTBAeOcGzIWjFPKcMAIC2nASchZFEVCCKWJlUoK4CjjeGuAkagEMgMahGHouhXLOjBNs1Tat0zLdmzbcZzy5m4AIcQY29ZIdF0DCmzOaSqEzLLjZqP5QdNqtd4XNDXtdrtWq0FT2xY24lDQQ2+PBNx2yv3B+Xq9zvPb9X/keQ7ffr9PCEnTtBBH9MB7FnIJY+n2Pv1Z/BqPx9PpZLGYr1arpeZaA+Jut7sjZhHed58Syh3H7vXOr65mFxefR99Go68/Li+/T6Y/ASg3m81A3Ol0dsRcsDIxYWZuxR0Oh5Bxs7y5Xs6/TD5Of48W8+Wm6dt/bQ8Ggx0x/H21+rxahYGJer0Oc2pojk5eHJ28PD599frNaeNd8+zsLcwsy7KdgUkQiUjFsE7FAubrrcBTIJgiVHGRg5CLfR8MXopelYoLDEyZTyjjIuSwrDiMpIxVwMGFpETIJFYJBIVUEbwnIWEvquAv1QlU6soQK5cAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"confirm_submit\"\n        title=\"confirm_submit\"\n        src=\"/static/4910e773cf01becfee8b5ffd4741a081/e5715/confirm_submit.png\"\n        srcset=\"/static/4910e773cf01becfee8b5ffd4741a081/a6d36/confirm_submit.png 650w,\n/static/4910e773cf01becfee8b5ffd4741a081/e5715/confirm_submit.png 768w,\n/static/4910e773cf01becfee8b5ffd4741a081/d8d63/confirm_submit.png 2026w\"\n        sizes=\"(max-width: 768px) 100vw, 768px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n</li>\n</ol>\n<p>If everything works well, you will get you app approved in a week, just remember to check it back periodically, good luck!</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":"August 04, 2015","updated_date":null,"description":null,"title":"Best practice for reviewing QQ app","tags":["SocialLogin","QQ"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/d2af27cda772fc4638659b578c92beb0/7d145/qq-app-review-best-practices.png","srcSet":"/static/d2af27cda772fc4638659b578c92beb0/69585/qq-app-review-best-practices.png 200w,\n/static/d2af27cda772fc4638659b578c92beb0/497c6/qq-app-review-best-practices.png 400w,\n/static/d2af27cda772fc4638659b578c92beb0/7d145/qq-app-review-best-practices.png 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Kundan Singh","github":null,"avatar":null}}}},{"node":{"excerpt":"What’s up, my neighbor? This is your boy, Darryl Tec. I am here to teach you how to create a responsive and awesomely scalable icon using…","fields":{"slug":"/engineering/css3-responsive-icons/"},"html":"<p>What’s up, my neighbor? This is your boy, Darryl Tec. I am here to teach you how to create a responsive and awesomely scalable icon using CSS sprites. On top of that, we will also add a fallback for browsers that do not support SVG files.</p>\n<h3 id=\"quick-faq\" style=\"position:relative;\"><a href=\"#quick-faq\" aria-label=\"quick faq permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Quick FAQ.</h3>\n<p>SVG - Stands for Scalable Vector Graphics. In short it scales perfectly and you don’t need to worry about having a pixelated image anymore.</p>\n<p>Sprite - Google said it’s a fairy. This is not a fairy. It’s just a bunch of different icons in 1 image. Use it as background image and shift the positioning to show 1 icon. This saves you a lot of loading time. Because instead of loading, say 10 images, you’re loading just 1.</p>\n<p>CSS - Cascading Style Sheet. If you don’t know what this is, I have bad news for ya.</p>\n<h3 id=\"lets-begin\" style=\"position:relative;\"><a href=\"#lets-begin\" aria-label=\"lets begin 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>Let's Begin</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 51px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 288.2352941176471%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAA6CAIAAAA/Te4cAAAACXBIWXMAAAsTAAALEwEAmpwYAAABbElEQVRIx+WX23LDIAxE8/8f68Z317fkTHZKKfXEEs4k6VQPNpZYI9AKxOlyQE56LcsyDMOnTb7B67ryGsexKIoPg5RluQHGcDbIU8ByMgfMZ9d1mJqmiU1WMKa+7xP9Ppi2QoK1rmvfyLTxFj2/SKZtXTBNmPjngDElq+UAs9rJhH1x/q18f3oeBefPmX5t27pJQhtW02B7SehtAqMhyIxMtN1ZRSeGnaYpJ6sgJg6j941MA4fJJ1Kiqioabre1E/MEn7OTKEiZifF3uZ0D3twGrHGGGBBzE+8AS+ljGNwAL3rSIbbug/kEyS/mecYF+sAzK5hkUhEAHoZTN4Q92AoeboLGAUZwsryJvA0+W+P877j9sBMjSZJ9MD34DBsgVA3nxj5YDIEY0BMrnLGCxe24uhVJrWCVQkHiysS0YLiqHsmJYxoZjdIjpw6La+x3ZpiCceeCEA6wjQuKioD2S+J2rPxxQXnA1egF4Csc/w4l/URccwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"icons\"\n        title=\"icons\"\n        src=\"/static/9dcf447eeec21d2bbbedb5047cb2bd9d/7cda0/icons.png\"\n        srcset=\"/static/9dcf447eeec21d2bbbedb5047cb2bd9d/7cda0/icons.png 51w\"\n        sizes=\"(max-width: 51px) 100vw, 51px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>First things first, we need a sprite image that consists four icons – or more, it’s up to you. Luckily, I have one in my digital pocket.  </p>\n<p>We’re just going to use a normal PNG file at first and change it later. Make sure it has a transparent background.</p>\n<p>Now, let’s make their placeholder. The icons you see above is using a grid of 32px by 32px and it’s lining up vertically. I made it like that so it’s easier to find anything, you’ll see why later.</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 class=\"mtk12\">pre</span><span class=\"mtk1\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">div</span><span class=\"mtk1\"> </span><span class=\"mtk12\">class</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;frame&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">div</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">pre</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>Now we need to style them.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.icon</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">32px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">height</span><span class=\"mtk1\">: </span><span class=\"mtk7\">32px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#eee</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">float</span><span class=\"mtk1\">: </span><span class=\"mtk8\">left</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-image</span><span class=\"mtk1\">: </span><span class=\"mtk11\">url</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;[ put your image here ]&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-size</span><span class=\"mtk1\">: </span><span class=\"mtk7\">100%</span><span class=\"mtk1\"> </span><span class=\"mtk8\">auto</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk3\">/*extra fluff*/</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin</span><span class=\"mtk1\">: </span><span class=\"mtk7\">10px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">border-radius</span><span class=\"mtk1\">: </span><span class=\"mtk7\">5px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<p><strong>Explanation</strong></p>\n<p>Looks simple right? But the one thing that’s very important here is the background-size, which makes our sprite responsive. When you put 100% as the value, it will stretch the image depending on what width and height you have. So, be very careful when putting a value on both X and Y axis, because this will distort the image. To stop it from distorting, you should only put a value on one axis and put the other on ‘auto’ so the image scales proportionally.</p>\n<p>If you look at the image I provided, there’s only one icon on X-axis. That means we can just say 100% on X and auto on Y.</p>\n<p>So, we get background-size: 100% auto.</p>\n<p>Cool, right? No crazy percentage. Your icon should look like this:</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 636px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 21.540880503144656%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAIAAAABPYjBAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAW0lEQVQI14WNQQrAIAwE/f9PmwgKmhC10i4KpbUH5xAyYZe460trrdbae8c8B29dwm7xlFKM0cxCCCKSc34U+6aMnKriP5o2wALFsZSyKU9UlJmJ2HtPdPxrkxtQxes+qKbsSAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"facebook-icon\"\n        title=\"facebook-icon\"\n        src=\"/static/285fb8a2043639c416e2a33aa44eecc9/9be90/facebook-icon.png\"\n        srcset=\"/static/285fb8a2043639c416e2a33aa44eecc9/9be90/facebook-icon.png 636w\"\n        sizes=\"(max-width: 636px) 100vw, 636px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>It’s time to map those icons properly. Facebook is not a problem because it’s first on the list. But for defaults sake, let’s add a code for it.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> </span><span class=\"mtk6\">.icon.facebook</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">background-position</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">   </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#3b5998</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> }</span></span></code></pre>\n<p>The positioning of 0 0 will map it to the top left of the element.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 202px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 81.1881188118812%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAsTAAALEwEAmpwYAAAA8ElEQVQoz6WSWwtFQBzEff8PJN6VojwqSoQ8yP22HJdzJlvanGXPZWpr/fMzs2Ol5x+SsLZtO03phBBS1/U8z49d769JLEB1PMZx7Lpu27ZlWRZFMU0TB4bDsiwHTydJkoBZ17Vpmr7vEWEcxzOMVLqu+76fpimsgiAIw1CW5WEY6OcA3zkriqKqqqZptm2bppnnuWEYURR9BDuOY1mW53nYIDAmyEk3EOCu6/ixsTBFmWztbLGAq6qCOd+ZZeierR1tIzPOIoC5AoxTwJ8P3wsY+N/hLMsuYwthNI/C+W0L4csbJoTxF8kueoW/g2/0AmPSqSE3ibfjAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"here-icon\"\n        title=\"here-icon\"\n        src=\"/static/c1cfab56ff8d6707145ed83661f038d6/2e687/here-icon.png\"\n        srcset=\"/static/c1cfab56ff8d6707145ed83661f038d6/2e687/here-icon.png 202w\"\n        sizes=\"(max-width: 202px) 100vw, 202px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>For the background-color, you can get almost all of the official social icon colors in hex <a href=\"/social-media-colors-hex/\">here</a>.</p>\n<p>How about the rest? Well, there’s a simple formula for that.</p>\n<h3 id=\"the-raw-css-way\" style=\"position:relative;\"><a href=\"#the-raw-css-way\" aria-label=\"the raw css way permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The raw CSS way</h3>\n<p>Since we’re making this responsive, we need to use percentage. We need to get the height of the image via percentage. Remember what I said earlier about x and y and scaling proportionally? Since the icons are lined up vertically, we need to get the Y-axis, which is the height. The easy way to do that is to just use 100% and never touch x axis again.</p>\n<p>Now, we have to get the position of the icons. Let’s start by counting the icons starting with 0 (zero).</p>\n<p>0 = Facebook</p>\n<p>1 = Google</p>\n<p>2 = LinkedIn</p>\n<p>3 = Twitter</p>\n<p>Facebook isn’t really a problem because we already know where it is. So, let’s exclude it from the count. That gives us 3 icons. We can now use those numbers to get the icon position.</p>\n<p>imageHeight = 100%<br>\niconCount = 3<br>\niconPosition = [1,  2 or 3]<br>\nWe need to go downwards on the sprite. That means it’s negative.</p>\n<p>-imageHeight / iconCount * iconPosition<br>\n-100% / 3 / 1 = 33.33% is Google’s position<br>\n-100% / 3 / 2 = 66.66% is LinkedIn’s position<br>\n-100% / 3 / 3 = 99.99% is Twitter’s position<br>\nThat gives us this code</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.icon.twitter</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-position</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk7\">-33.33%</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#55acee</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.icon.linkedin</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-position</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk7\">-66.66%</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#007bb6</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk6\">.icon.google</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-position</span><span class=\"mtk1\">: </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk7\">-99.99%</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-color</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#F90101</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">}</span></span></code></pre>\n<h2 id=\"the-stylus-way\" style=\"position:relative;\"><a href=\"#the-stylus-way\" aria-label=\"the stylus way permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The Stylus way</h2>\n<p>If you use stylus you can just do this:<br>\nCreate the mixin</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=\"mtk11\">getPos</span><span class=\"mtk1\">(</span><span class=\"mtk12\">imageHeight</span><span class=\"mtk1\">, </span><span class=\"mtk12\">iconCount</span><span class=\"mtk1\">, </span><span class=\"mtk12\">iconPosition</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">imageHeight</span><span class=\"mtk1\"> / </span><span class=\"mtk12\">iconCount</span><span class=\"mtk1\"> * </span><span class=\"mtk12\">iconPosition</span></span></code></pre>\n<p>Then call it.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">.</span><span class=\"mtk12\">icon</span><span class=\"mtk1\">.</span><span class=\"mtk12\">twitter</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">-</span><span class=\"mtk12\">position</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getPos</span><span class=\"mtk1\">(-</span><span class=\"mtk7\">100</span><span class=\"mtk1\">%, </span><span class=\"mtk7\">3</span><span class=\"mtk1\">, </span><span class=\"mtk7\">1</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">-</span><span class=\"mtk12\">color</span><span class=\"mtk1\"> #55</span><span class=\"mtk12\">acee</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">.</span><span class=\"mtk12\">icon</span><span class=\"mtk1\">.</span><span class=\"mtk12\">linkedin</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">-</span><span class=\"mtk12\">position</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getPos</span><span class=\"mtk1\">(-</span><span class=\"mtk7\">100</span><span class=\"mtk1\">%, </span><span class=\"mtk7\">3</span><span class=\"mtk1\">, </span><span class=\"mtk7\">2</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">-</span><span class=\"mtk12\">color</span><span class=\"mtk1\"> #007</span><span class=\"mtk12\">bb6</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">.</span><span class=\"mtk12\">icon</span><span class=\"mtk1\">.</span><span class=\"mtk12\">google</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">-</span><span class=\"mtk12\">position</span><span class=\"mtk1\"> </span><span class=\"mtk7\">0</span><span class=\"mtk1\"> </span><span class=\"mtk11\">getPos</span><span class=\"mtk1\">(-</span><span class=\"mtk7\">100</span><span class=\"mtk1\">%, </span><span class=\"mtk7\">3</span><span class=\"mtk1\">, </span><span class=\"mtk7\">3</span><span class=\"mtk1\">)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">-</span><span class=\"mtk12\">color</span><span class=\"mtk1\"> #</span><span class=\"mtk12\">F90101</span></span></code></pre>\n<p>By now your icon should look like this.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 644px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 16.304347826086957%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAIAAAAcOLh5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjElEQVQI12P4jwT+/v03e82pWSuOXXr6bemlL+effZ+x73rX/ntfTh//1FL689wJiCK4egYI9e8fiPz1609U+crIwsUbL7+v2/dhzeWPSbMPBS68+GLp/FdWil/WLAKp/PMbXTMc3Hrw+vrdlx+//7326te7b3+vP3t/6dmnP+/e/rpw6u+7Nwh7wAAA4+GfO6qUrmcAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"color-icons\"\n        title=\"color-icons\"\n        src=\"/static/dbde29abe640e8c397f80b3324234398/78274/color-icons.png\"\n        srcset=\"/static/dbde29abe640e8c397f80b3324234398/78274/color-icons.png 644w\"\n        sizes=\"(max-width: 644px) 100vw, 644px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>It’s time to change that PNG background to an SVG background.</p>\n<p>and link it to your background image</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"css\" data-index=\"6\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk6\">.icon</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">width</span><span class=\"mtk1\">: </span><span class=\"mtk7\">32px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">height</span><span class=\"mtk1\">: </span><span class=\"mtk7\">32px</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background</span><span class=\"mtk1\">: </span><span class=\"mtk8\">#eee</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">float</span><span class=\"mtk1\">: </span><span class=\"mtk8\">left</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-image</span><span class=\"mtk1\">: </span><span class=\"mtk11\">url</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;</span><span class=\"mtk14\">[ put your PNG image here ]”);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-image:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">linear-gradient(transparent,</span><span class=\"mtk1\"> </span><span class=\"mtk12\">transparent</span><span class=\"mtk1\">), </span><span class=\"mtk11\">url</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;</span><span class=\"mtk14\">[ &lt;b&gt;put your SVG image here&lt;/b&gt; ]”);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">background-size:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">100%</span><span class=\"mtk1\"> </span><span class=\"mtk12\">auto;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">/*extra</span><span class=\"mtk1\"> </span><span class=\"mtk12\">fluff*/</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">margin:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">10px;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk12\">border-radius:</span><span class=\"mtk1\"> </span><span class=\"mtk12\">5px;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">}</span></span></code></pre>\n<p>If you’re wondering why we’re adding 2 background images is because not all browsers support SVG file. The linear-gradient(transparent, transparent) tricks the CSS into falling back to the PNG image if it doesn’t support it.</p>\n<p>Now, Rescale your width and height and see the magic of responsive icons.</p>\n<p>Aaaaaand then we’re done. That’s how you create a responsive icon.</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 .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk6 { color: #D7BA7D; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n</style>","frontmatter":{"date":"July 21, 2015","updated_date":null,"description":null,"title":"CSS3 Responsive Icons","tags":["CSS","Responsive","UI"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/35808f86ae877ca92a333571b6b36e6f/630fb/css3-responsive-icons-300x300.png","srcSet":"/static/35808f86ae877ca92a333571b6b36e6f/69585/css3-responsive-icons-300x300.png 200w,\n/static/35808f86ae877ca92a333571b6b36e6f/630fb/css3-responsive-icons-300x300.png 300w","sizes":"(max-width: 300px) 100vw, 300px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}},{"node":{"excerpt":"As my previous blog, I use the python web Crawler library to help crawl the static website. For the Scrapy, there can be customize download…","fields":{"slug":"/engineering/write-a-highly-efficient-python-web-crawler/"},"html":"<p>As my previous blog, I use the python web Crawler library to help crawl the static website. For the Scrapy, there can be customize download middle ware, which can deal with static content in the website like JavaScript.</p>\n<p>However, the Scrapy already helps us with much of the underlying implementation, for example, it uses it own dispatcher and it has pipeline for dealing the parsing word after download.  One drawback for using such library is hard to deal with some strange bugs occurring because they run the paralleled jobs.</p>\n<p>For this tutorial, I want to show the structure of a simple and efficient web crawler.</p>\n<p>First of all, we need a scheduler, who can paralleled the job. Because the most of the time is on the requesting.  I use the  <a href=\"http://www.gevent.org/\">gevent</a> to schedule the jobs. Gevent uses the <a href=\"http://libevent.org/\">libevent</a> as its underlying library, which combines the multithreading and event-based techniques to parallel the job.</p>\n<p>There is the sample code:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"python\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk15\">import</span><span class=\"mtk1\"> gevent</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> gevent </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> Greenlet</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> gevent </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> monkey</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk15\">from</span><span class=\"mtk1\"> selenium </span><span class=\"mtk15\">import</span><span class=\"mtk1\"> webdriver</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">monkey.patch_socket()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">class</span><span class=\"mtk1\"> </span><span class=\"mtk10\">WebCrawler</span><span class=\"mtk1\">:</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">__init__</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">,</span><span class=\"mtk12\">urls</span><span class=\"mtk1\">=[],</span><span class=\"mtk12\">num_worker</span><span class=\"mtk1\"> = </span><span class=\"mtk7\">1</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.url_queue = Queue()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.num_worker = num_worker</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">worker</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">,</span><span class=\"mtk12\">pid</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        driver = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.initializeAnImegaDisabledDriver()  </span><span class=\"mtk3\">#initilize the webdirver</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">#</span><span class=\"mtk4\">TODO</span><span class=\"mtk3\"> catch the exception</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">while</span><span class=\"mtk1\"> </span><span class=\"mtk4\">not</span><span class=\"mtk1\"> </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.url_queue.empty():</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            url = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.url_queue.get()</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.driver.get(url)</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">            elem = </span><span class=\"mtk4\">self</span><span class=\"mtk1\">.driver.find_elements_by_xpath(</span><span class=\"mtk8\">&quot;//script | //iframe | //img&quot;</span><span class=\"mtk1\">) </span><span class=\"mtk3\"># get such element from webpage</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">def</span><span class=\"mtk1\"> </span><span class=\"mtk11\">run</span><span class=\"mtk1\">(</span><span class=\"mtk12\">self</span><span class=\"mtk1\">):</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        jobs = [gevent.spawn(</span><span class=\"mtk4\">self</span><span class=\"mtk1\">.worker,i) </span><span class=\"mtk15\">for</span><span class=\"mtk1\"> i </span><span class=\"mtk4\">in</span><span class=\"mtk1\"> </span><span class=\"mtk12\">xrange</span><span class=\"mtk1\">(</span><span class=\"mtk4\">self</span><span class=\"mtk1\">.num_worker)]</span></span></code></pre>\n<p>The next part is the headless browser part. I use the phantomjs with <code>--webdriver=4444 --disk-cache=true --ignore-ssl-errors=true --load-images=false --max-disk-cache-size=100000</code>. You can get the detailed option from their documents.</p>\n<p>Phantomjs uses selenium webdriver as front-end to handle the request. However phantomjs is using the webkit and QT as its underlying browser and controller. It has memory leak bugs therefore the phantomjs will consume ton of memory and it only can use one core of your CPU but you can deploy many instances of the phantomjs on different ports. I wrote a daemon process to monitor the memory and its situation but later I realize I can use Perl script to get the status of process and when it exceeds the limits like 1G memory and send kill signal to the process.</p>\n<p>To speed up the crawler, I choose to use static browser to verify the website first because the website is bad written, there might be deadlock occurring so just skip them.</p>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n</style>","frontmatter":{"date":"July 14, 2015","updated_date":null,"description":null,"title":"Write a highly efficient python Web Crawler","tags":["Python","Coding"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/87be28baa66b2bfdbec1ee9478ca3d79/7d145/python-web-crawler.png","srcSet":"/static/87be28baa66b2bfdbec1ee9478ca3d79/69585/python-web-crawler.png 200w,\n/static/87be28baa66b2bfdbec1ee9478ca3d79/497c6/python-web-crawler.png 400w,\n/static/87be28baa66b2bfdbec1ee9478ca3d79/7d145/python-web-crawler.png 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Mark Duan","github":null,"avatar":null}}}},{"node":{"excerpt":"The  memcached is one of the most popular open source on-memory key-value caching systems. I will briefly talk about the design of memory…","fields":{"slug":"/engineering/memcach-memory-management/"},"html":"<p>The  <a href=\"https://github.com/memcached\">memcached</a> is one of the most popular open source on-memory key-value caching systems. I will briefly talk about the design of memory management of memcached.</p>\n<h3 id=\"chunk-and-slab\" style=\"position:relative;\"><a href=\"#chunk-and-slab\" aria-label=\"chunk and slab 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>Chunk and Slab</h3>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 428px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 66.58878504672897%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABRklEQVQoz4WS2Y6CQBRE+/8/kJAAARIERdmHVUCPXWIm8zDWQ3u9fZeqos3jQFmWVVVdr9e6rpumcRzn8Q1GP/u+t21Lc1EUTDmfz7+b53kehoHzx2JZlnfzbkHUdV3f93mec7L5dDp9mumEEUMZzQL6tc98KrZtIzuOI9l1XTXxC20phFIYhr7v5xYQYwoLp2ki4HayIJOmaZZlnJSZ2+0GGXYGQUC/53lRFDERkgiREZwskCMsoJKyOI5fzQCdDOMCbWQJLpcLSYb2FozDBdd18ZJAlaawWA/c73fESzYBJxI2CxUggYzKjMjIqtmCGMLSSRLOEkwMeRmhj/feDAcM0EeGNpJKCzLYo/dDgWhrH7qM7OUa5fKJ8fKJv5RqUGVBXjWcL7cXC2gUB2ShWCRJgjeMEAvlBTLm/2dABbSRpyf15/YJ0a/j2yCXnQEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"memcached-1\"\n        title=\"memcached-1\"\n        src=\"/static/85a5e23f4d71f1d3123d2f05c0694caf/47730/memcached1.png\"\n        srcset=\"/static/85a5e23f4d71f1d3123d2f05c0694caf/47730/memcached1.png 428w\"\n        sizes=\"(max-width: 428px) 100vw, 428px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"cpp\" data-index=\"0\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">/* powers-of-N allocation structures */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">typedef</span><span class=\"mtk1\"> </span><span class=\"mtk4\">struct</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">unsigned</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> size;</span><span class=\"mtk3\">      /* sizes of items */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">unsigned</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> perslab;</span><span class=\"mtk3\">   /* how many items per slab */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> *slots;</span><span class=\"mtk3\">           /* list of item ptrs */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">unsigned</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> sl_curr;</span><span class=\"mtk3\">   /* total free items in list */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">unsigned</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> slabs;</span><span class=\"mtk3\">     /* how many slabs were allocated for this class */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> **slab_list;</span><span class=\"mtk3\">       /* array of slab pointers */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">unsigned</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> list_size;</span><span class=\"mtk3\"> /* size of prev array */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">unsigned</span><span class=\"mtk1\"> </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> killing;</span><span class=\"mtk3\">  /* index+1 of dying slab, or zero if none */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">size_t</span><span class=\"mtk1\"> requested;</span><span class=\"mtk3\"> /* The number of requested bytes */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">} </span><span class=\"mtk10\">slabclass_t</span><span class=\"mtk1\">;</span></span></code></pre>\n<p>This is the struct declaration of slabclass_t. Each slab class contains the same size of chunk, but different classes have different chunk sizes. The size is calculated by this algorithm:</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"cpp\" data-index=\"1\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">&lt;!--</span><span class=\"mtk15\">while</span><span class=\"mtk1\"> (++i &lt; POWER_LARGEST && size </span></span></code></pre>\n<p>The content value factor is defined when memcached memory is deployed with -f, which can change the size between slab classes. For this loop, the size is multiplied by a specified factor. </p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 632px; \"\n    >\n      <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 131.32911392405063%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAaCAIAAAA44esqAAAACXBIWXMAAAsTAAALEwEAmpwYAAADfklEQVQ4y4WU609SYRzHDyIqCgdTFOV2QEGngpnai/LSi15Xa6USmvc0c8u50pQUr122LKNGmdMXbrX+Adeb3rS2ZigqEFZb3oaK18pZ+rovPJO5BXr2jD3P4Xx+3+/vcg517eFow4Djuslab7Y3DthqTJMlj6f0jyaL+6bKntpL++3Yl/RNVz2fqXjmxCo3OWvMTsOI0/zyHfXho9VqsYx9Gp8as3xzzNhtzmnb18mJacvniSmrfdwyOWGZcNhs87Mu16Lbt9xLq3Pzq5Rj5svaomNtaWFhzu1aXp93bf5Y+rm8srnqXl9dWVt2ubc2NrZ/b/7a2v67s0fWn5293Z3dWdt3qrq+6UZdbXV17WVd2cUC3ZWSKv3VyksF+vLyisrKqrKyitrautLSiqJCnV5fXFBQqCvS6XT6C+fOD5pHKFVq9rFIOlooZAcFiUSxUqlYIKA5wcFisVgkEgmFQqVSERoaSh24WCwWfk2Db6j0rHyGkcnlcppPKxRKlVoNjM/nJycnq1QquZxJTEwU0DSLFRS8f3E4HMAvh99SmswcqEmlUi6XK5PJEhISYmNjIyIisEFE3FcqlTj+r2we8sKyfRhPQw1uCQwM9xUKRUA4Pdtjm2GYyMhIOITb+Ph4Ho+HjVqthhfA4eHh/uHj2fkKBqkx0dHRB2EoExheUIIjYBSWwHFxcQiUmpqq9hYPpgQCgX9Ym5XHyKVQiIqKglpSUhIKhkApKSmIBZgY8Q+nZZyWSOLxEGBS7ZiYGJICskXxDoM1J3JRbbFYAjU8TVqFPfzDMFIATNN0IDhHKhFLJBKooVU+ZeSMI2AcAxZMm5Url3lyBoDGokgA4ESj0aDOZNqOapWcgYKvVYhF+owhgeeAQ+KDkaoPhgVUm8AYnsB9PnlGqfD0GW7h0wcT27CAJh9RbVIwVBviaA8ZL4RAziAx9gH67Km2p8/ImVQbMPRhG7HgAi9gWFjYIW8VhCWA0VgfDGUcETQQ/ML7PudCGTAGg0wYYMhqtVooE9ivbdOr15Q2M0+tApKIwoLBbCBERkZGWloa5hzi+AahVQCCvBebzcbHBHDPk2Eq+9RZDpsVEhLC5YbxeTzyx+EX4uD3fv8Qdav1Xlu7saO7t6Ozx9jZ3dHV29ntWS2tbTcbGpuaWwx3je3GruY7htvNLViGNmN374OOrp7R92P/AHltP5KD4p8uAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"memcached-2\"\n        title=\"memcached-2\"\n        src=\"/static/944f070fa0ede38d13a4e8ee0277d472/084e2/memcached-2.png\"\n        srcset=\"/static/944f070fa0ede38d13a4e8ee0277d472/084e2/memcached-2.png 632w\"\n        sizes=\"(max-width: 632px) 100vw, 632px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n    </span></p>\n<p>You can get this information by adding -vvv and you can use the command</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"cpp\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\">stats slabs under telnet connection ip port</span></span></code></pre>\n<p>Every time when a new memory needs to be allocated. It will scan the slab class to find the most suitable class to store the chunk.</p>\n<h3 id=\"rebalance-and-reassign-slab-memory\" style=\"position:relative;\"><a href=\"#rebalance-and-reassign-slab-memory\" aria-label=\"rebalance and reassign slab memory 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>Rebalance and reassign slab memory:</h3>\n<p>From memcached’s wiki:</p>\n<p><strong>Overview</strong>: Memcached 1.4.11. Fixes race conditions and crashes introduced in 1.4.10. Adds the ability to rebalance and reassign slab memory.</p>\n<h4 id=\"slab-reassignment\" style=\"position:relative;\"><a href=\"#slab-reassignment\" aria-label=\"slab reassignment 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>Slab Reassignment</h4>\n<p>Long running instances of memcached memory may run into an issue where all available memory has been assigned to a specific slab class (say items of roughly size 100 bytes). Later the application starts storing more of its data into a different slab class (items around 200 bytes). Memcached could not use the 100 byte chunks to satisfy the 200 byte requests, and thus you would be able to store very few 200 byte items.</p>\n<p>1.4.11 introduces the ability to reassign slab pages. This is a <strong>beta</strong> feature and the commands may change for the next few releases, so <strong>please</strong> keep this in mind. When the commands are finalized they will be noted in the release notes</p>\n<h4 id=\"slab-automove\" style=\"position:relative;\"><a href=\"#slab-automove\" aria-label=\"slab automove 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>Slab Automove</h4>\n<p>While slab reassign is a manual feature, there is also the start of an automatic memory reassignment algorithm.</p>\n<p>From the source code in <a href=\"https://github.com/memcached/memcached/blob/master/slabs.c#L232\">slabs.c</a> we can see, memcached uses two threads to monitor the slabs class, one is to do maintenance and another one is to do the re-balance the class.</p>\n<p>Memcached defines a global variable <em>struct slab\\</em>rebalance slab_rebal,_ which is used to store the start, end information of slab. s_clsid is the source slab id and d_clsid is the destination slab id. The detailed blog in Chinese <a href=\"http://blog.chinaunix.net/uid-27767798-id-3404133.html\">memcached源码分析—–slab automove和slab rebalance</a> could be helpful.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"cpp\" data-index=\"3\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk4\">struct</span><span class=\"mtk1\"> </span><span class=\"mtk10\">slab_rebalance</span><span class=\"mtk1\"> {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> *slab_start;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> *slab_end;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">void</span><span class=\"mtk1\"> *slab_pos;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> s_clsid;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> d_clsid;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">int</span><span class=\"mtk1\"> busy_items;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk4\">uint8_t</span><span class=\"mtk1\"> done;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">};</span></span></code></pre>\n<h3 id=\"memory-pool\" style=\"position:relative;\"><a href=\"#memory-pool\" aria-label=\"memory pool 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>Memory Pool</h3>\n<p>Memcached implements its own memory pool, which is used to avoid system memory allocation and memory fragmentation. That will make your memory efficient and easy to manage. Here is a demo implementation of memory pool. Basically it is a large pre-allocated chunk of memory.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"cpp\" data-index=\"4\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk1\"> mem_avail) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk15\">return</span><span class=\"mtk1\"> </span><span class=\"mtk4\">NULL</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">    /* mem_current pointer _must_ be aligned!!! */</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (size % CHUNK_ALIGN_BYTES) {</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    }</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    mem_current = ((</span><span class=\"mtk4\">char</span><span class=\"mtk1\">*)mem_current) + size;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk15\">if</span><span class=\"mtk1\"> (size </span></span></code></pre>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n</style>","frontmatter":{"date":"July 07, 2015","updated_date":null,"description":null,"title":"Memcached Memory Management","tags":["Memory Management"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/de7966e19463e0047c10eea9388c12c4/7d145/memcached-memory-management.png","srcSet":"/static/de7966e19463e0047c10eea9388c12c4/69585/memcached-memory-management.png 200w,\n/static/de7966e19463e0047c10eea9388c12c4/497c6/memcached-memory-management.png 400w,\n/static/de7966e19463e0047c10eea9388c12c4/7d145/memcached-memory-management.png 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Mark Duan","github":null,"avatar":null}}}},{"node":{"excerpt":"HTML 5 is the latest and greatest web technology, although it has some issues in some browsers which don’t have native support for the new…","fields":{"slug":"/engineering/html5-limitation-in-internet-explorer/"},"html":"<p>HTML 5 is the latest and greatest web technology, although it has some issues in some browsers which don’t have native support for the new HTML5 elements. If you want to support some of the older browsers which may still be in use such as IE8 and lower then you are going to have some trouble using HTML5.</p>\n<p>The problem with IE8 and lower versioned IE browsers is that they were created many years ago while HTML5 is new technology and HTML5 tags were newly invented so legacy browsers do not support them. Microsoft will not release any updates for these browsers because they have released new versions of the IE browser.</p>\n<p>As old IE browsers do not know about these tags then it can’t style them so you will find that in IE8 or lower your websites will be rendered without many styles.</p>\n<h4 id=\"how-to-use-html5-in-ie\" style=\"position:relative;\"><a href=\"#how-to-use-html5-in-ie\" aria-label=\"how to use html5 in ie 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 use HTML5 in IE</h4>\n<p>If you want HTML5s new tags to be supported in IE then you need to add some javascript to create the elements:</p>\n<p>Example:</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\">  </span><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    document.createElement(&#39;header&#39;);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    document.createElement(&#39;article&#39;);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    document.createElement(&#39;aside&#39;);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    document.createElement(&#39;footer&#39;);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">  </span><span class=\"mtk17\">&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span></code></pre>\n<p>This is not a very good way, you would need to remember all the tags that you have set and include them on every page of your website. If you add any new tags then you need to add these tags on every page of the website as well. Thankfully Remy Sharp provided a solution for this, Remy Sharp has created a Javascript file which he hosts with google code that will handle this for you.</p>\n<p>add the following at the top of your pages and it will include this code file on your website if the end user is using an IE browser lower than version 9.</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 class=\"mtk12\">if</span><span class=\"mtk1\"> </span><span class=\"mtk12\">lt</span><span class=\"mtk1\"> </span><span class=\"mtk12\">IE</span><span class=\"mtk1\"> </span><span class=\"mtk7\">9</span><span class=\"mtk1\">]&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk17\">&lt;</span><span class=\"mtk4\">script</span><span class=\"mtk1\"> </span><span class=\"mtk12\">src</span><span class=\"mtk1\">=</span><span class=\"mtk8\">&quot;https://html5shim.googlecode.com/svn/trunk/html5.js&quot;</span><span class=\"mtk17\">&gt;&lt;/</span><span class=\"mtk4\">script</span><span class=\"mtk17\">&gt;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">&lt;![</span><span class=\"mtk12\">endif</span><span class=\"mtk1\">]--&gt;</span></span></code></pre>\n<p>IE also does not support some of the most useful new HTML5 methods that are supported by modern browsers:Window.postMessage()</p>\n<p><strong>Window.postMessage</strong></p>\n<p>allows for sending data messages between two windows/frames across domains. Normally, scripts on different pages are allowed to access each other if and only if the pages that executed them are at the same locations with the same protocol (usually both http) and matching host names. The HTML5 postMessage function provides a great way to communicate securely and with high performance and reliability even cross-domain. Unfortunately, the HTML5 postMessage function does not work in IE</p>\n<p>Let’s take a look at how Window.postMessage works:</p>\n<h4 id=\"syntax\" style=\"position:relative;\"><a href=\"#syntax\" aria-label=\"syntax 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>Syntax</h4>\n<p>The below signature is used for postMessage:</p>\n<p><strong>otherWindow.postMessage(message, targetOrigin);</strong></p>\n<p><strong>otherWindow</strong>\nA reference to another window; such a reference may be obtained, for example, using the contentWindow property of an iframe element, the object returned by window.open</p>\n<p><strong>message</strong>\nThis parameter is required for a message to be sent to the other window. The message is serialized using the structured clone algorithm. This means you can pass a broad variety of data objects safely to the destination window without having to serialize them yourself.</p>\n<p><strong>targetOrigin</strong>\nWhen the message is dispatched, the current location of the target document is checked. If it does not match the specified URI, then the message will not be dispatched. This parameter can be useful if you want to be sure of the location of the target document before dispatching the message and you can also specify a literal string “*”  (indicating no preference) or as a URI</p>\n<p>but always provide a specific targetOrigin, not *, if you know where the other window’s document should be located. If you do not set a specific location and use “*” then a malicious site can change the location of the window without your knowledge, and therefore it can intercept the data sent using the postMessage method.</p>\n<p><strong>Example for postMessage</strong></p>\n<p><strong>Sender</strong></p>\n<p>The first part of the process is setting up a “source”.  With the source, we will open a new window (or IFrame), send the new window message (in the our example, we’ll do so every 6 seconds, and create an event listener for any response we receive from the destination window.</p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"2\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//create popup window</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">domain</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;https://www.example.com&#39;</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">myPopup</span><span class=\"mtk1\"> = </span><span class=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk11\">open</span><span class=\"mtk1\">(</span><span class=\"mtk12\">domain</span><span class=\"mtk1\"> + </span><span class=\"mtk8\">&#39;/postmessage.html&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk8\">&#39;myWindow&#39;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//periodical message sender</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk11\">setInterval</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=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">message</span><span class=\"mtk1\"> = </span><span class=\"mtk8\">&#39;Hello!  The time is: &#39;</span><span class=\"mtk1\"> + (</span><span class=\"mtk4\">new</span><span class=\"mtk1\"> </span><span class=\"mtk10\">Date</span><span class=\"mtk1\">().</span><span class=\"mtk11\">getTime</span><span class=\"mtk1\">());</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">    </span><span class=\"mtk12\">myPopup</span><span class=\"mtk1\">.</span><span class=\"mtk11\">postMessage</span><span class=\"mtk1\">(</span><span class=\"mtk12\">message</span><span class=\"mtk1\">,</span><span class=\"mtk12\">domain</span><span class=\"mtk1\">); </span><span class=\"mtk3\">//send the message and target URI</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">},</span><span class=\"mtk7\">6000</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//listen to back</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\"> </span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;message&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">event</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\">event</span><span class=\"mtk1\">.</span><span class=\"mtk12\">origin</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&#39;http://scriptandstyle.com&#39;</span><span class=\"mtk1\">) </span><span class=\"mtk15\">return</span><span class=\"mtk1\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk10\">console</span><span class=\"mtk1\">.</span><span class=\"mtk11\">log</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;received response:  &#39;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">event</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=\"mtk4\">false</span><span class=\"mtk1\">);</span></span></code></pre>\n<p>I have used window.addEventListener which doesn’t work with Internet Explorer so use window.attachEvent</p>\n<p><strong>Receiver</strong></p>\n<p>In the destination window we should validate the message origin and if it is not valid then we will not send the message to the sender, otherwise we send a response back to the sender:</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=\"mtk12\">window</span><span class=\"mtk1\">.</span><span class=\"mtk11\">addEventListener</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;message&#39;</span><span class=\"mtk1\">,</span><span class=\"mtk4\">function</span><span class=\"mtk1\">(</span><span class=\"mtk12\">event</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\">event</span><span class=\"mtk1\">.</span><span class=\"mtk12\">origin</span><span class=\"mtk1\"> !== </span><span class=\"mtk8\">&#39;https://lrblogs.wpengine.com) return</span><span class=\"mtk14\">;</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">        </span><span class=\"mtk12\">event</span><span class=\"mtk1\">.</span><span class=\"mtk12\">source</span><span class=\"mtk1\">.</span><span class=\"mtk11\">postMessage</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&#39;message received:  &#39;</span><span class=\"mtk1\">,</span><span class=\"mtk12\">event</span><span class=\"mtk1\">.</span><span class=\"mtk12\">origin</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk1\">},</span><span class=\"mtk4\">false</span><span class=\"mtk1\">);</span></span></code></pre>\n<p><strong>sessionStorage</strong></p>\n<p>sessionStorage stores data for one session only, this is used in a single transaction it stores the data only for one session and as you close the window the session would be lost and  the data is deleted when the browser is closed.</p>\n<p>HTML5 sessionStorage object are shared in different tabs in the same browser session if you change a sessionStorage attribute’s value in one tab, that change should be reflected within another tab but in IE8 this system will not work properly it does not share sessionStorage objects between frames on a page. This issue has since been fixed in IE11.</p>\n<p><strong>Example:</strong></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=\"mtk3\">//save a value</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;website&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;https://www.example.com&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//retrieve item</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">website</span><span class=\"mtk1\">= </span><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;website&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//remove the key</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">sessionStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">removeItem</span><span class=\"mtk1\">(“</span><span class=\"mtk12\">website</span><span class=\"mtk1\">”);</span></span></code></pre>\n<p><strong>localStorage</strong></p>\n<p>The localStorage object stores the data like a persistent cookie, with no expiration date. The data will not be deleted when the browser is closed, and will be available when a user returns to the browser.</p>\n<p>IE also supports localStorage from IE8 but it does not support localStorage in IE7 and previous versions.</p>\n<p>localStorage Vs Cookies</p>\n<ol>\n<li>Cookies are small text files stored by browsers allowing for a max of 4KB while with localStorage we can store Mbs of localStorage data.</li>\n<li>Cookies are delivered with every request, which can slow down the delivery of your web pages.</li>\n</ol>\n<p><strong>Example</strong></p>\n<pre class=\"grvsc-container dark-default-dark\" data-language=\"javascript\" data-index=\"5\"><code class=\"grvsc-code\"><span class=\"grvsc-line\"><span class=\"mtk3\">//save a value</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">setItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;Domain&quot;</span><span class=\"mtk1\">, </span><span class=\"mtk8\">&quot;https://www.example.com&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//retrieve item</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk4\">var</span><span class=\"mtk1\"> </span><span class=\"mtk12\">website</span><span class=\"mtk1\">= </span><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">getItem</span><span class=\"mtk1\">(</span><span class=\"mtk8\">&quot;website&quot;</span><span class=\"mtk1\">);</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk3\">//remove the key</span></span>\n<span class=\"grvsc-line\"><span class=\"mtk12\">localStorage</span><span class=\"mtk1\">.</span><span class=\"mtk11\">removeItem</span><span class=\"mtk1\">(“</span><span class=\"mtk12\">website</span><span class=\"mtk1\">”);</span></span></code></pre>\n<style class=\"grvsc-styles\">\n  .grvsc-container {\n    overflow: auto;\n    -webkit-overflow-scrolling: touch;\n    padding-top: 1rem;\n    padding-top: var(--grvsc-padding-top, var(--grvsc-padding-v, 1rem));\n    padding-bottom: 1rem;\n    padding-bottom: var(--grvsc-padding-bottom, var(--grvsc-padding-v, 1rem));\n    border-radius: 8px;\n    border-radius: var(--grvsc-border-radius, 8px);\n    font-feature-settings: normal;\n  }\n  \n  .grvsc-code {\n    display: inline-block;\n    min-width: 100%;\n  }\n  \n  .grvsc-line {\n    display: inline-block;\n    box-sizing: border-box;\n    width: 100%;\n    padding-left: 1.5rem;\n    padding-left: var(--grvsc-padding-left, var(--grvsc-padding-h, 1.5rem));\n    padding-right: 1.5rem;\n    padding-right: var(--grvsc-padding-right, var(--grvsc-padding-h, 1.5rem));\n  }\n  \n  .grvsc-line-highlighted {\n    background-color: var(--grvsc-line-highlighted-background-color, transparent);\n    box-shadow: inset var(--grvsc-line-highlighted-border-width, 4px) 0 0 0 var(--grvsc-line-highlighted-border-color, transparent);\n  }\n  \n  .dark-default-dark {\n    background-color: #1E1E1E;\n    color: #D4D4D4;\n  }\n  .dark-default-dark .mtk1 { color: #D4D4D4; }\n  .dark-default-dark .mtk17 { color: #808080; }\n  .dark-default-dark .mtk4 { color: #569CD6; }\n  .dark-default-dark .mtk12 { color: #9CDCFE; }\n  .dark-default-dark .mtk7 { color: #B5CEA8; }\n  .dark-default-dark .mtk8 { color: #CE9178; }\n  .dark-default-dark .mtk3 { color: #6A9955; }\n  .dark-default-dark .mtk11 { color: #DCDCAA; }\n  .dark-default-dark .mtk10 { color: #4EC9B0; }\n  .dark-default-dark .mtk15 { color: #C586C0; }\n  .dark-default-dark .mtk14 { color: #F44747; }\n</style>","frontmatter":{"date":"June 30, 2015","updated_date":null,"description":null,"title":"HTML5 Limitation in Internet Explorer","tags":["Java","Maven","Eclipse"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1,"src":"/static/56b8ac1b7f3b7dfdc03ce43aa1e62eaa/7d145/radio-check-buttons-css.png","srcSet":"/static/56b8ac1b7f3b7dfdc03ce43aa1e62eaa/69585/radio-check-buttons-css.png 200w,\n/static/56b8ac1b7f3b7dfdc03ce43aa1e62eaa/497c6/radio-check-buttons-css.png 400w,\n/static/56b8ac1b7f3b7dfdc03ce43aa1e62eaa/7d145/radio-check-buttons-css.png 610w","sizes":"(max-width: 610px) 100vw, 610px"}}},"author":{"id":"Team LoginRadius","github":"LoginRadius","avatar":null}}}}]},"markdownRemark":{"excerpt":"Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie…","fields":{"slug":"/engineering/identity-impact-of-google-chrome-thirdparty-cookie-restrictions/"},"html":"<p>Google has prepared a roadmap to restrict third-party cookies in Chrome. Since 04 January 2024, Chrome has rolled out third-party cookie restrictions for 1% of stable clients and 20% of Canary, Dev, and Beta clients.</p>\n<p><strong>What does it mean for user authentication?</strong></p>\n<p>On one hand, Google believes third-party cookies are widely used for cross-site tracking, greatly affecting user privacy. Hence, Google wants to phase out (or restrict) supporting third-party cookies in Chrome by early Q2 2025 (subject to regulatory processes).</p>\n<p>On the other hand, Google introduced Privacy Sandbox to support the use cases (other than cross-site tracking and advertising) previously implemented using third-party cookies.</p>\n<p>In this article, we’ll discuss:</p>\n<ul>\n<li>How is user authentication (identity) affected?</li>\n<li>What is Google offering as part of Privacy Sandbox to support various identity use cases when third-party cookies are phased out?</li>\n</ul>\n<h2 id=\"how-is-user-authentication-affected\" style=\"position:relative;\"><a href=\"#how-is-user-authentication-affected\" aria-label=\"how is user authentication affected 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 is User Authentication Affected?</h2>\n<p>Third-party cookie restrictions affect user authentication in three ways, as follows.</p>\n<h3 id=\"external-identity-providers\" style=\"position:relative;\"><a href=\"#external-identity-providers\" aria-label=\"external identity providers 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>External Identity Providers</h3>\n<p>If your website or app uses an external Identity Provider (IdP) — like LoginRadius, the IdP sets a third-party cookie when the user authenticates on your app.</p>\n<h3 id=\"web-sso\" style=\"position:relative;\"><a href=\"#web-sso\" aria-label=\"web sso 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>Web SSO</h3>\n<p>If you have multiple apps across domains within your organization and authentication is handled using an IdP (internal or external) with web SSO, you already use third-party cookies to facilitate seamless access for each user using a single set of credentials.</p>\n<p>If you have implemented web SSO with one primary domain and multiple sub-domains of the primary domain, third-party cookie restrictions may not apply. For now, Google doesn’t consider the cookies set by sub-domains as third-party cookies, although this stance may change in the future.</p>\n<p>For example, you have apps at <code>example.com</code>, <code>travel.example.com</code>, <code>stay.example.com</code>, and web SSO is handled by <code>auth.example.com</code>. In this case, third-party cookie restrictions don’t apply.</p>\n<h3 id=\"federated-sso\" style=\"position:relative;\"><a href=\"#federated-sso\" aria-label=\"federated sso 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>Federated SSO</h3>\n<p>Federated SSO is similar to, albeit different from, web SSO. It can handle multiple IdPs and applications—aka., Service Providers (SPs)—spanning multiple organizations. It can also implement authentication scenarios that are usually implemented through web SSO.</p>\n<p>Usually, authentication is handled on a separate pop-up or page when the user wants to authenticate rather than on the application or website a user visits. </p>\n<p>For example, you already use federated SSO if you facilitate authentication for a set of apps through multiple social identity providers as well as traditional usernames and passwords.</p>\n<blockquote>\n<p><strong>Note</strong>: It is also possible to store tokens locally, not within cookies. In this case, third-party cookie restrictions won’t affect token-based authentication. However, the restrictions still affect authentication where tokens are stored within third-party cookies (a common and secure method).</p>\n</blockquote>\n<h2 id=\"chromes-alternatives-for-third-party-cookies\" style=\"position:relative;\"><a href=\"#chromes-alternatives-for-third-party-cookies\" aria-label=\"chromes alternatives for third party cookies permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Chrome’s Alternatives for Third-Party Cookies</h2>\n<p>Google has been developing alternative features and capabilities for Chrome to replace third-party cookies as part of its Privacy Sandbox for Web initiative.</p>\n<p>Specific to authentication, Google recommends the following:</p>\n<ol>\n<li>Cookies Having Independent Partitioned State (CHIPS)</li>\n<li>Storage Access API</li>\n<li>Related Website Sets</li>\n<li>Federated Credential Management (FedCM) API</li>\n</ol>\n<h3 id=\"cookies-having-independent-partitioned-state-chips\" style=\"position:relative;\"><a href=\"#cookies-having-independent-partitioned-state-chips\" aria-label=\"cookies having independent partitioned state chips permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Cookies Having Independent Partitioned State (CHIPS)</h3>\n<p><a href=\"https://developers.google.com/privacy-sandbox/3pcd/chips\">CHIPS</a> are a restricted way of setting third-party cookies on a top-level site without making them accessible on other top-level sites. Thus, they limit cross-site tracking and enable specific cross-site functionalities, such as maps, chat, and payment embeds.</p>\n<p>For example, a user visits <code>a.com</code> with a map embed from <code>map-example.com</code>, which can set a partitioned cookie that is only accessible on a.com. </p>\n<p>If the user visits <code>b.com</code> with a map embed from <code>map-example.com</code>, it cannot access the partitioned cookie set on <code>a.com</code>. It has to create a separate partitioned cookie specific to <code>b.com</code>, thus blocking cross-site tracking yet allowing limited cross-site functionality.</p>\n<p>You should specifically opt for partitioned cookies (CHIPS), which are set with partitioned and secure cookie attributes.</p>\n<p>If you’re using an external identity provider for your application, CHIPS is a good option to supplant third-party cookie restrictions. </p>\n<p>However, CHIPS may not be ideal if you have a web SSO or federated SSO implementation. It creates separate partitioned cookies for each application with a separate domain, which can increase complexity and create compatibility issues.</p>\n<h3 id=\"storage-access-api\" style=\"position:relative;\"><a href=\"#storage-access-api\" aria-label=\"storage access 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>Storage Access API</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/storage-access-api\">Storage Access API</a>, you can access the local storage in a third-party context through iframes, similar to when users visit it as a top-level site in a first-party context. That is, it gives access to unpartitioned cookies and storage.</p>\n<p>Storage Access API requires explicit user approval to grant access, similar to locations, camera, and microphone permissions. If the user denies access, unpartitioned cookies and storage won’t be accessible in a third-party context.</p>\n<p>It is most suitable when loading cross-site resources and interactions, such as:</p>\n<p>Verifying user sessions when allowing interactions on an embedded social post or providing personalization for an embedded video.\nEmbedded documents requiring user verification status to be accessible.</p>\n<p>As it requires explicit user approval, it is advisable to use Storage Access API when you can’t implement an identity use case with the other options.</p>\n<h3 id=\"related-website-sets\" style=\"position:relative;\"><a href=\"#related-website-sets\" aria-label=\"related website sets 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>Related Website Sets</h3>\n<p>With <a href=\"https://developers.google.com/privacy-sandbox/3pcd/related-website-sets\">Related Website Sets</a>, you can declare a <code>primary</code> website and <code>associatedSites</code> for limited purposes to grant third-party cookie access and local storage for a limited number of sites.</p>\n<p>Chrome automatically recognizes related website sets declared, accepted, and maintained in this open-source GitHub repository: <a href=\"https://github.com/GoogleChrome/related-website-sets\">Related Website Sets</a></p>\n<p>It provides access through Storage Access API directly without prompting for user approval, but only after the user interacts with the relevant iframe.</p>\n<p>It is important to declare a limited number of domains in related website sets that are meaningful and used for specific purposes. Google may block or suspend any exploitative use of this feature.</p>\n<p>The top-level site can also request approval for specific cross-site resources and scripts to Storage Access API using <code>resuestStorageAccessFor()</code> API.</p>\n<p>If you’re using an external identity provider for your web application, you can declare the domain of the identity provider in the related set to ensure limited third-party cookies and storage access to the identity provider, thus ensuring seamless user authentication.</p>\n<p>Related Website Sets can also work to supplement third-party cookie restrictions in web SSO and federated SSO if the number of web applications (or domains) is limited.</p>\n<h3 id=\"federated-credential-management-fedcm-api\" style=\"position:relative;\"><a href=\"#federated-credential-management-fedcm-api\" aria-label=\"federated credential management fedcm 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>Federated Credential Management (FedCM) API</h3>\n<p>FedCM API enables federated SSO without third-party cookies.</p>\n<p>With FedCM API, a user follows these steps for authentication:</p>\n<ol>\n<li>The User navigates to a Service Provider (SP) — aka., Relying Party (RP)</li>\n<li>As the user requests to authenticate, the SP requests the browser through FedCM API to initiate authentication.</li>\n<li>The browser displays a list of available identity providers (supported by the RP), such as social IdPs like Google, Apple, LinkedIn, and Facebook, or other OAuth IdPs like LoginRadius.</li>\n<li>Once the user selects an IdP, the browser communicates with the IdP. Upon valid authentication, the IdP generates a secure token.\nThe browser delivers this secure token to the RP to facilitate user authorization.</li>\n</ol>\n<p>You can access a user demo of FedCM here: <a href=\"https://fedcm-rp-demo.glitch.me/\">FedCM</a>. </p>\n<p>For more information about implementing federated SSO with FedCM API, go through the <a href=\"https://developers.google.com/privacy-sandbox/3pcd/fedcm-developer-guide\">FedCM developer guide</a>.</p>\n<h2 id=\"how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" style=\"position:relative;\"><a href=\"#how-is-loginradius-preparing-for-the-third-party-cookie-phase-out\" aria-label=\"how is loginradius preparing for the third party cookie phase out 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 is LoginRadius Preparing for the Third-party Cookie Phase-out?</h2>\n<p>Firstly, we’re committed to solving our customers' user identity pain points — and preparing for the third-party cookies phase-out is no different.</p>\n<p>We’ll implement the most relevant and widely useful solutions to facilitate a smooth transition for our customers.</p>\n<p>Please subscribe to our blog for more information. We’ll update you on how we help with the third-party cookie phase-out.</p>\n<h2 id=\"in-conclusion\" style=\"position:relative;\"><a href=\"#in-conclusion\" aria-label=\"in 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>In Conclusion</h2>\n<p>The proposed changes to phase out third-party cookies and suggested alternatives are evolving as Google has been actively collaborating and discussing changes with the border community.</p>\n<p>Moreover, browsers like Firefox, Safari, and Edge may approach restricting third-party cookies differently than Google does.</p>\n<p>From LoginRadius, we’ll keep you updated on what we’re doing as a leading Customer Identity and Access Management (CIAM) vendor to prepare for the third-party cookie phase-out.</p>\n<h2 id=\"glossary\" style=\"position:relative;\"><a href=\"#glossary\" aria-label=\"glossary 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>Glossary</h2>\n<p><strong>Top-level site</strong>: It is the primary site a user has visited.</p>\n<p><strong>First-party cookie</strong>: A cookie set by the top-level site.</p>\n<p><strong>Third-party cookie</strong>: A cookie set by a domain other than the top-level site. For example, let’s assume that a user has visited <code>a.com</code>, which might use an embed from <code>loginradius.com</code> to facilitate authentication. If <code>loginradius.com</code> sets a cookie when the user visits <code>a.com</code>, it is called a third-party cookie as the user hasn’t directly visited <code>loginradius.com</code>.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references 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>References</h2>\n<ul>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout\">Changes to Chrome's treatment of third-party cookies</a></li>\n<li><a href=\"https://developers.google.com/privacy-sandbox/3pcd/guides/identity\">Check the impact of the third-party cookie changes on your sign-in workflows</a></li>\n</ul>\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":"July 08, 2024","updated_date":null,"description":"Google Chrome has planned to phase out third-party cookies, which will affect different website functionalities depending on third-party cookies. This blog focuses on how this phase-out affects identity and user authentication and discusses alternatives for overcoming challenges.","title":"How Chrome’s Third-Party Cookie Restrictions Affect User Authentication?","tags":["Identity","Cookies","Chrome"],"pinned":null,"coverImage":{"childImageSharp":{"fluid":{"aspectRatio":1.5037593984962405,"src":"/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png","srcSet":"/static/eb7396060c0adc430dbed2d04b63d431/69585/third-party-cookies-phaseout-chrome.png 200w,\n/static/eb7396060c0adc430dbed2d04b63d431/497c6/third-party-cookies-phaseout-chrome.png 400w,\n/static/eb7396060c0adc430dbed2d04b63d431/ee604/third-party-cookies-phaseout-chrome.png 800w,\n/static/eb7396060c0adc430dbed2d04b63d431/f3583/third-party-cookies-phaseout-chrome.png 1200w","sizes":"(max-width: 800px) 100vw, 800px"}}},"author":{"id":"Raghunath Reddy","github":"raghunath-r-a","avatar":null}}}},"pageContext":{"limit":6,"skip":282,"currentPage":48,"type":"//engineering//","numPages":52,"pinned":"17fa0d7b-34c8-51c4-b047-df5e2bbaeedb"}},"staticQueryHashes":["1171199041","1384082988","2100481360","23180105","528864852"]}