CINXE.COM

Sign-up form best practices  |  Articles  |  web.dev

<!doctype html> <html lang="en" dir="ltr"> <head> <meta name="google-signin-client-id" content="157101835696-ooapojlodmuabs2do2vuhhnf90bccmoi.apps.googleusercontent.com"> <meta name="google-signin-scope" content="profile email https://www.googleapis.com/auth/developerprofiles https://www.googleapis.com/auth/developerprofiles.award"> <meta property="og:site_name" content="web.dev"> <meta property="og:type" content="website"><meta name="theme-color" content="#3740ff"><meta charset="utf-8"> <meta content="IE=Edge" http-equiv="X-UA-Compatible"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="manifest" href="/_pwa/web/manifest.json" crossorigin="use-credentials"> <link rel="preconnect" href="//www.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.gstatic.com" crossorigin> <link rel="preconnect" href="//fonts.googleapis.com" crossorigin> <link rel="preconnect" href="//apis.google.com" crossorigin> <link rel="preconnect" href="//www.google-analytics.com" crossorigin><link rel="stylesheet" href="//fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"> <link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Material+Icons&family=Material+Symbols+Outlined&display=block"><link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/css/app.css"> <link rel="stylesheet" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/css/dark-theme.css" disabled> <link rel="shortcut icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/favicon.png"> <link rel="apple-touch-icon" href="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/touchicon-180.png"><link rel="canonical" href="https://web.dev/articles/sign-up-form-best-practices"><link rel="search" type="application/opensearchdescription+xml" title="web.dev" href="https://web.dev/s/opensearch.xml"> <link rel="alternate" hreflang="en" href="https://web.dev/articles/sign-up-form-best-practices" /><link rel="alternate" hreflang="x-default" href="https://web.dev/articles/sign-up-form-best-practices" /><link rel="alternate" hreflang="ar" href="https://web.dev/articles/sign-up-form-best-practices?hl=ar" /><link rel="alternate" hreflang="bn" href="https://web.dev/articles/sign-up-form-best-practices?hl=bn" /><link rel="alternate" hreflang="zh-Hans" href="https://web.dev/articles/sign-up-form-best-practices?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant" href="https://web.dev/articles/sign-up-form-best-practices?hl=zh-tw" /><link rel="alternate" hreflang="fa" href="https://web.dev/articles/sign-up-form-best-practices?hl=fa" /><link rel="alternate" hreflang="fr" href="https://web.dev/articles/sign-up-form-best-practices?hl=fr" /><link rel="alternate" hreflang="de" href="https://web.dev/articles/sign-up-form-best-practices?hl=de" /><link rel="alternate" hreflang="he" href="https://web.dev/articles/sign-up-form-best-practices?hl=he" /><link rel="alternate" hreflang="hi" href="https://web.dev/articles/sign-up-form-best-practices?hl=hi" /><link rel="alternate" hreflang="id" href="https://web.dev/articles/sign-up-form-best-practices?hl=id" /><link rel="alternate" hreflang="it" href="https://web.dev/articles/sign-up-form-best-practices?hl=it" /><link rel="alternate" hreflang="ja" href="https://web.dev/articles/sign-up-form-best-practices?hl=ja" /><link rel="alternate" hreflang="ko" href="https://web.dev/articles/sign-up-form-best-practices?hl=ko" /><link rel="alternate" hreflang="pl" href="https://web.dev/articles/sign-up-form-best-practices?hl=pl" /><link rel="alternate" hreflang="pt-BR" href="https://web.dev/articles/sign-up-form-best-practices?hl=pt-br" /><link rel="alternate" hreflang="ru" href="https://web.dev/articles/sign-up-form-best-practices?hl=ru" /><link rel="alternate" hreflang="es" href="https://web.dev/articles/sign-up-form-best-practices?hl=es" /><link rel="alternate" hreflang="es-419" href="https://web.dev/articles/sign-up-form-best-practices?hl=es-419" /><link rel="alternate" hreflang="th" href="https://web.dev/articles/sign-up-form-best-practices?hl=th" /><link rel="alternate" hreflang="tr" href="https://web.dev/articles/sign-up-form-best-practices?hl=tr" /><link rel="alternate" hreflang="vi" href="https://web.dev/articles/sign-up-form-best-practices?hl=vi" /><link rel="alternate" hreflang="en-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices" /><link rel="alternate" hreflang="x-default" href="https://web.developers.google.cn/articles/sign-up-form-best-practices" /><link rel="alternate" hreflang="ar-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=ar" /><link rel="alternate" hreflang="bn-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=bn" /><link rel="alternate" hreflang="zh-Hans-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=zh-cn" /><link rel="alternate" hreflang="zh-Hant-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=zh-tw" /><link rel="alternate" hreflang="fa-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=fa" /><link rel="alternate" hreflang="fr-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=fr" /><link rel="alternate" hreflang="de-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=de" /><link rel="alternate" hreflang="he-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=he" /><link rel="alternate" hreflang="hi-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=hi" /><link rel="alternate" hreflang="id-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=id" /><link rel="alternate" hreflang="it-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=it" /><link rel="alternate" hreflang="ja-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=ja" /><link rel="alternate" hreflang="ko-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=ko" /><link rel="alternate" hreflang="pl-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=pl" /><link rel="alternate" hreflang="pt-BR-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=pt-br" /><link rel="alternate" hreflang="ru-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=ru" /><link rel="alternate" hreflang="es-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=es" /><link rel="alternate" hreflang="es-419-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=es-419" /><link rel="alternate" hreflang="th-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=th" /><link rel="alternate" hreflang="tr-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=tr" /><link rel="alternate" hreflang="vi-cn" href="https://web.developers.google.cn/articles/sign-up-form-best-practices?hl=vi" /><title>Sign-up form best practices &nbsp;|&nbsp; Articles &nbsp;|&nbsp; web.dev</title> <meta property="og:title" content="Sign-up form best practices &nbsp;|&nbsp; Articles &nbsp;|&nbsp; web.dev"><meta name="description" content="Help your users sign up, log in and manage their account details with a minimum of fuss."> <meta property="og:description" content="Help your users sign up, log in and manage their account details with a minimum of fuss."><meta property="og:url" content="https://web.dev/articles/sign-up-form-best-practices"><meta property="og:image" content="https://web.dev/static/articles/sign-up-form-best-practices/image/thumbnail.jpg"> <meta property="og:image:width" content="1200"> <meta property="og:image:height" content="675"><meta property="og:locale" content="en"><meta name="twitter:card" content="summary_large_image"><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Article", "dateModified": "2020-12-09", "headline": "Sign-up form best practices" } </script><script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Articles", "item": "https://web.dev/articles" },{ "@type": "ListItem", "position": 2, "name": "Sign-up form best practices", "item": "https://web.dev/articles/sign-up-form-best-practices" }] } </script> <link rel="stylesheet" href="/extras.css"></head> <body class="" template="page" theme="web-theme" type="article" appearance layout="docs" display-toc pending> <devsite-progress type="indeterminate" id="app-progress"></devsite-progress> <section class="devsite-wrapper"> <devsite-cookie-notification-bar></devsite-cookie-notification-bar><devsite-header role="banner"> <div class="devsite-header--inner nocontent"> <div class="devsite-top-logo-row-wrapper-wrapper"> <div class="devsite-top-logo-row-wrapper"> <div class="devsite-top-logo-row"> <button type="button" id="devsite-hamburger-menu" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Navigation menu button" visually-hidden aria-label="Open menu"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="webDev" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="web.dev"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup.svg" class="devsite-site-logo" alt="web.dev"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> <div class="devsite-top-logo-row-middle"> <div class="devsite-header-upper-tabs"> <devsite-tabs class="upper-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Upper tabs"> <tab > <a href="https://web.dev/about" track-metadata-eventdetail="https://web.dev/about" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - about" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: About" track-name="about" > About </a> </tab> <tab > <a href="https://web.dev/html" track-metadata-eventdetail="https://web.dev/html" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - html" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: HTML" track-name="html" > HTML </a> </tab> <tab > <a href="https://web.dev/css" track-metadata-eventdetail="https://web.dev/css" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - css" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: CSS" track-name="css" > CSS </a> </tab> <tab > <a href="https://web.dev/javascript" track-metadata-eventdetail="https://web.dev/javascript" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - javascript" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: JavaScript" track-name="javascript" > JavaScript </a> </tab> <tab > <a href="https://web.dev/blog" track-metadata-eventdetail="https://web.dev/blog" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - blog" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" > Blog </a> </tab> <tab > <a href="https://web.dev/learn" track-metadata-eventdetail="https://web.dev/learn" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - learn" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Learn" track-name="learn" > Learn </a> </tab> <tab class="devsite-active"> <a href="https://web.dev/explore" track-metadata-eventdetail="https://web.dev/explore" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - explore" track-metadata-module="primary nav" aria-label="Explore, selected" data-category="Site-Wide Custom Events" data-label="Tab: Explore" track-name="explore" > Explore </a> </tab> <tab > <a href="https://web.dev/patterns" track-metadata-eventdetail="https://web.dev/patterns" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - patterns" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Patterns" track-name="patterns" > Patterns </a> </tab> <tab > <a href="https://web.dev/case-studies" track-metadata-eventdetail="https://web.dev/case-studies" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - case studies" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Case studies" track-name="case studies" > Case studies </a> </tab> </nav> </devsite-tabs> </div> <devsite-search enable-signin enable-search enable-suggestions enable-query-completion project-name="Articles" tenant-name="web.dev" > <form class="devsite-search-form" action="https://web.dev/s/results" method="GET"> <div class="devsite-search-container"> <button type="button" search-open class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Open search"></button> <div class="devsite-searchbox"> <input aria-activedescendant="" aria-autocomplete="list" aria-label="Search" aria-expanded="false" aria-haspopup="listbox" autocomplete="off" class="devsite-search-field devsite-search-query" name="q" placeholder="Search" role="combobox" type="text" value="" > <div class="devsite-search-image material-icons" aria-hidden="true"> </div> <div class="devsite-search-shortcut-icon-container" aria-hidden="true"> <kbd class="devsite-search-shortcut-icon">/</kbd> </div> </div> </div> </form> <button type="button" search-close class="devsite-search-button devsite-header-icon-button button-flat material-icons" aria-label="Close search"></button> </devsite-search> </div> <devsite-appearance-selector></devsite-appearance-selector> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> <devsite-user enable-profiles id="devsite-user"> <span class="button devsite-top-button" aria-hidden="true" visually-hidden>Sign in</span> </devsite-user> </div> </div> </div> <div class="devsite-collapsible-section "> <div class="devsite-header-background"> <div class="devsite-product-id-row" > <div class="devsite-product-description-row"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> <a href="https://web.dev/explore" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Lower Header" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="" > Collections </a> </li> </ul> </div> </div> <div class="devsite-doc-set-nav-row"> <devsite-tabs class="lower-tabs"> <nav class="devsite-tabs-wrapper" aria-label="Lower tabs"> <tab > <a href="https://web.dev/explore/learn-core-web-vitals" track-metadata-eventdetail="https://web.dev/explore/learn-core-web-vitals" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - core web vitals" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Core Web Vitals" track-name="core web vitals" > Core Web Vitals </a> </tab> <tab > <a href="https://web.dev/explore/metrics" track-metadata-eventdetail="https://web.dev/explore/metrics" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - metrics" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Metrics" track-name="metrics" > Metrics </a> </tab> <tab > <a href="https://web.dev/explore/fast" track-metadata-eventdetail="https://web.dev/explore/fast" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - fast load times" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Fast load times" track-name="fast load times" > Fast load times </a> </tab> <tab > <a href="https://web.dev/explore/ai" track-metadata-eventdetail="https://web.dev/explore/ai" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - ai" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: AI" track-name="ai" > AI </a> </tab> <tab > <a href="https://web.dev/explore/how-to-optimize-inp" track-metadata-eventdetail="https://web.dev/explore/how-to-optimize-inp" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - optimize interaction to next paint (inp)" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Optimize Interaction to Next Paint (INP)" track-name="optimize interaction to next paint (inp)" > Optimize Interaction to Next Paint (INP) </a> </tab> <tab > <a href="https://web.dev/explore/progressive-web-apps" track-metadata-eventdetail="https://web.dev/explore/progressive-web-apps" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - progressive web apps" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Progressive Web Apps" track-name="progressive web apps" > Progressive Web Apps </a> </tab> <tab > <a href="https://web.dev/accessibility" track-metadata-eventdetail="https://web.dev/accessibility" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - accessible to all" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Accessible to all" track-name="accessible to all" > Accessible to all </a> </tab> <tab > <a href="https://web.dev/explore/reliable" track-metadata-eventdetail="https://web.dev/explore/reliable" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - network reliability" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Network reliability" track-name="network reliability" > Network reliability </a> </tab> <tab > <a href="https://web.dev/explore/secure" track-metadata-eventdetail="https://web.dev/explore/secure" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - safe and secure" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Safe and secure" track-name="safe and secure" > Safe and secure </a> </tab> <tab > <a href="https://web.dev/explore/discoverable" track-metadata-eventdetail="https://web.dev/explore/discoverable" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - easily discoverable" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Easily discoverable" track-name="easily discoverable" > Easily discoverable </a> </tab> <tab > <a href="https://web.dev/explore/payments" track-metadata-eventdetail="https://web.dev/explore/payments" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - web payments" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Web Payments" track-name="web payments" > Web Payments </a> </tab> <tab > <a href="https://web.dev/explore/media" track-metadata-eventdetail="https://web.dev/explore/media" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - media" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Media" track-name="media" > Media </a> </tab> <tab > <a href="https://web.dev/explore/devices" track-metadata-eventdetail="https://web.dev/explore/devices" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - devices" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Devices" track-name="devices" > Devices </a> </tab> <tab > <a href="https://web.dev/explore/animations" track-metadata-eventdetail="https://web.dev/explore/animations" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - animations" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Animations" track-name="animations" > Animations </a> </tab> <tab class="devsite-active"> <a href="https://web.dev/explore/identity" track-metadata-eventdetail="https://web.dev/explore/identity" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - identity" track-metadata-module="primary nav" aria-label="Identity, selected" data-category="Site-Wide Custom Events" data-label="Tab: Identity" track-name="identity" > Identity </a> </tab> <tab > <a href="https://web.dev/explore/webassembly" track-metadata-eventdetail="https://web.dev/explore/webassembly" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - webassembly" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: WebAssembly" track-name="webassembly" > WebAssembly </a> </tab> <tab > <a href="https://web.dev/explore/test-automation" track-metadata-eventdetail="https://web.dev/explore/test-automation" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - test automation" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Test automation" track-name="test automation" > Test automation </a> </tab> <tab > <a href="https://web.dev/explore/react" track-metadata-eventdetail="https://web.dev/explore/react" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - react" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: React" track-name="react" > React </a> </tab> <tab > <a href="https://web.dev/explore/angular" track-metadata-eventdetail="https://web.dev/explore/angular" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - angular" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Angular" track-name="angular" > Angular </a> </tab> <tab > <a href="https://web.dev/explore/mini-apps" track-metadata-eventdetail="https://web.dev/explore/mini-apps" class="devsite-tabs-content gc-analytics-event " track-type="nav" track-metadata-position="nav - mini apps" track-metadata-module="primary nav" data-category="Site-Wide Custom Events" data-label="Tab: Mini apps" track-name="mini apps" > Mini apps </a> </tab> </nav> </devsite-tabs> </div> </div> </div> </div> </devsite-header> <devsite-book-nav scrollbars > <div class="devsite-book-nav-filter" hidden> <span class="filter-list-icon material-icons" aria-hidden="true"></span> <input type="text" placeholder="Filter" aria-label="Type to filter" role="searchbox"> <span class="filter-clear-button hidden" data-title="Clear filter" aria-label="Clear filter" role="button" tabindex="0"></span> </div> <nav class="devsite-book-nav devsite-nav nocontent" aria-label="Side menu"> <div class="devsite-mobile-header"> <button type="button" id="devsite-close-nav" class="devsite-header-icon-button button-flat material-icons gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Close navigation" aria-label="Close navigation"> </button> <div class="devsite-product-name-wrapper"> <a href="/" class="devsite-site-logo-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Site logo" track-type="globalNav" track-name="webDev" track-metadata-position="nav" track-metadata-eventDetail="nav"> <picture> <source srcset="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup-dark-theme.svg" media="(prefers-color-scheme: dark)" class="devsite-dark-theme" alt="web.dev"> <img src="https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup.svg" class="devsite-site-logo" alt="web.dev"> </picture> </a> <span class="devsite-product-name"> <ul class="devsite-breadcrumb-list" > <li class="devsite-breadcrumb-item "> </li> </ul> </span> </div> </div> <div class="devsite-book-nav-wrapper"> <div class="devsite-mobile-nav-top"> <ul class="devsite-nav-list"> <li class="devsite-nav-item"> <a href="/about" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: About" track-name="about" data-category="Site-Wide Custom Events" data-label="Responsive Tab: About" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > About </span> </a> </li> <li class="devsite-nav-item"> <a href="/html" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: HTML" track-name="html" data-category="Site-Wide Custom Events" data-label="Responsive Tab: HTML" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > HTML </span> </a> </li> <li class="devsite-nav-item"> <a href="/css" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: CSS" track-name="css" data-category="Site-Wide Custom Events" data-label="Responsive Tab: CSS" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > CSS </span> </a> </li> <li class="devsite-nav-item"> <a href="/javascript" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: JavaScript" track-name="javascript" data-category="Site-Wide Custom Events" data-label="Responsive Tab: JavaScript" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > JavaScript </span> </a> </li> <li class="devsite-nav-item"> <a href="/blog" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Blog" track-name="blog" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Blog" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Blog </span> </a> </li> <li class="devsite-nav-item"> <a href="/learn" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Learn" track-name="learn" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Learn" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Learn </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore" class="devsite-nav-title gc-analytics-event devsite-nav-active" data-category="Site-Wide Custom Events" data-label="Tab: Explore" track-name="explore" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Explore" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Explore </span> </a> <ul class="devsite-nav-responsive-tabs"> <li class="devsite-nav-item"> <a href="/explore/learn-core-web-vitals" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Core Web Vitals" track-name="core web vitals" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Core Web Vitals" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Core Web Vitals </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/metrics" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Metrics" track-name="metrics" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Metrics" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Metrics </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/fast" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Fast load times" track-name="fast load times" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Fast load times" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Fast load times </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/ai" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: AI" track-name="ai" data-category="Site-Wide Custom Events" data-label="Responsive Tab: AI" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > AI </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/how-to-optimize-inp" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Optimize Interaction to Next Paint (INP)" track-name="optimize interaction to next paint (inp)" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Optimize Interaction to Next Paint (INP)" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Optimize Interaction to Next Paint (INP) </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/progressive-web-apps" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Progressive Web Apps" track-name="progressive web apps" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Progressive Web Apps" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Progressive Web Apps </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/accessibility" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Accessible to all" track-name="accessible to all" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Accessible to all" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Accessible to all </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/reliable" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Network reliability" track-name="network reliability" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Network reliability" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Network reliability </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/secure" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Safe and secure" track-name="safe and secure" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Safe and secure" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Safe and secure </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/discoverable" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Easily discoverable" track-name="easily discoverable" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Easily discoverable" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Easily discoverable </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/payments" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Web Payments" track-name="web payments" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Web Payments" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Web Payments </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/media" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Media" track-name="media" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Media" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Media </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/devices" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Devices" track-name="devices" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Devices" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Devices </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/animations" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Animations" track-name="animations" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Animations" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Animations </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/identity" class="devsite-nav-title gc-analytics-event devsite-nav-has-children devsite-nav-active" data-category="Site-Wide Custom Events" data-label="Tab: Identity" track-name="identity" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Identity" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip menu="_book"> Identity </span> <span class="devsite-nav-icon material-icons" data-icon="forward" menu="_book"> </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/webassembly" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: WebAssembly" track-name="webassembly" data-category="Site-Wide Custom Events" data-label="Responsive Tab: WebAssembly" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > WebAssembly </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/test-automation" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Test automation" track-name="test automation" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Test automation" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Test automation </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/react" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: React" track-name="react" data-category="Site-Wide Custom Events" data-label="Responsive Tab: React" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > React </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/angular" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Angular" track-name="angular" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Angular" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Angular </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> <li class="devsite-nav-item"> <a href="/explore/mini-apps" class="devsite-nav-title gc-analytics-event devsite-nav-has-children " data-category="Site-Wide Custom Events" data-label="Tab: Mini apps" track-name="mini apps" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Mini apps" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Mini apps </span> <span class="devsite-nav-icon material-icons" data-icon="forward" > </span> </a> </li> </ul> </li> <li class="devsite-nav-item"> <a href="/patterns" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Patterns" track-name="patterns" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Patterns" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Patterns </span> </a> </li> <li class="devsite-nav-item"> <a href="/case-studies" class="devsite-nav-title gc-analytics-event " data-category="Site-Wide Custom Events" data-label="Tab: Case studies" track-name="case studies" data-category="Site-Wide Custom Events" data-label="Responsive Tab: Case studies" track-type="globalNav" track-metadata-eventDetail="globalMenu" track-metadata-position="nav"> <span class="devsite-nav-text" tooltip > Case studies </span> </a> </li> </ul> </div> <div class="devsite-mobile-nav-bottom"> <ul class="devsite-nav-list" menu="_book"> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Understand authentication basics</span> </div></li> <li class="devsite-nav-item"><a href="/articles/sign-in-form-best-practices" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/sign-in-form-best-practices" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/sign-in-form-best-practices" ><span class="devsite-nav-text" tooltip>Sign-in form best practices</span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://web.dev/codelab-sign-in-form-best-practices/" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://web.dev/codelab-sign-in-form-best-practices/" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://web.dev/codelab-sign-in-form-best-practices/" ><span class="devsite-nav-text" tooltip>[Codelab] Use cross-platform browser features to build a sign-in form</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item"><a href="/articles/sign-up-form-best-practices" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/sign-up-form-best-practices" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/sign-up-form-best-practices" ><span class="devsite-nav-text" tooltip>Sign-up form best practices</span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://web.dev/codelab-sign-up-form-best-practices/" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://web.dev/codelab-sign-up-form-best-practices/" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://web.dev/codelab-sign-up-form-best-practices/" ><span class="devsite-nav-text" tooltip>[Codelab] Sign-up form best practices codelab</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item"><a href="/articles/sign-out-best-practices" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/sign-out-best-practices" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/sign-out-best-practices" ><span class="devsite-nav-text" tooltip>What makes for a good sign-out experience?</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Build authentication systems with modern APIs</span> </div></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developer.chrome.com/docs/identity/web-apis/web-otp" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developer.chrome.com/docs/identity/web-apis/web-otp" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developer.chrome.com/docs/identity/web-apis/web-otp" ><span class="devsite-nav-text" tooltip>Verify phone numbers on the web with the WebOTP API</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item"><a href="/articles/change-password-url" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/change-password-url" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/change-password-url" ><span class="devsite-nav-text" tooltip>Help users change passwords easily by adding a well-known URL for changing passwords</span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Strengthen security with two-factor authentication</span> </div></li> <li class="devsite-nav-item"><a href="/sms-otp-form" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /sms-otp-form" track-type="bookNav" track-name="click" track-metadata-eventdetail="/sms-otp-form" ><span class="devsite-nav-text" tooltip>SMS OTP form for two-step verification</span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/codelabs/webauthn-2fa-key/" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/codelabs/webauthn-2fa-key/" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/codelabs/webauthn-2fa-key/" ><span class="devsite-nav-text" tooltip>[Codelab] Enable two-factor authentication with WebAuthn</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Build advanced authentication systems</span> </div></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/identity/passkeys/" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/identity/passkeys/" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/identity/passkeys/" ><span class="devsite-nav-text" tooltip>Passwordless login with passkeys</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item"><a href="/articles/passkey-registration" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/passkey-registration" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/passkey-registration" ><span class="devsite-nav-text" tooltip>Create a passkey for passwordless logins</span></a></li> <li class="devsite-nav-item"><a href="/articles/passkey-form-autofill" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/passkey-form-autofill" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/passkey-form-autofill" ><span class="devsite-nav-text" tooltip>Sign in with a passkey through form autofill</span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/identity/passkeys/developer-guides/server-introduction" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/identity/passkeys/developer-guides/server-introduction" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/identity/passkeys/developer-guides/server-introduction" ><span class="devsite-nav-text" tooltip>Passkey server-side introduction</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/identity/passkeys/developer-guides/server-registration" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/identity/passkeys/developer-guides/server-registration" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/identity/passkeys/developer-guides/server-registration" ><span class="devsite-nav-text" tooltip>Passkey registration server-side </span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/identity/passkeys/developer-guides/server-authentication" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/identity/passkeys/developer-guides/server-authentication" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/identity/passkeys/developer-guides/server-authentication" ><span class="devsite-nav-text" tooltip>Passkey authentication server-side</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item"><a href="/articles/webauthn-user-verification" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/webauthn-user-verification" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/webauthn-user-verification" ><span class="devsite-nav-text" tooltip>User verification deep dive</span></a></li> <li class="devsite-nav-item"><a href="/articles/webauthn-discoverable-credentials" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/webauthn-discoverable-credentials" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/webauthn-discoverable-credentials" ><span class="devsite-nav-text" tooltip>Discoverable credentials deep dive</span></a></li> <li class="devsite-nav-item"><a href="/articles/webauthn-exclude-credentials" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/webauthn-exclude-credentials" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/webauthn-exclude-credentials" ><span class="devsite-nav-text" tooltip>Prevent duplicate credentials</span></a></li> <li class="devsite-nav-item"><a href="/articles/webauthn-aaguid" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/webauthn-aaguid" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/webauthn-aaguid" ><span class="devsite-nav-text" tooltip>Determine the passkey provider</span></a></li> <li class="devsite-nav-item"><a href="/articles/webauthn-related-origin-requests" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/webauthn-related-origin-requests" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/webauthn-related-origin-requests" ><span class="devsite-nav-text" tooltip>Associate related origins</span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developer.chrome.com/docs/identity/webauthn-signal-api" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developer.chrome.com/docs/identity/webauthn-signal-api" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developer.chrome.com/docs/identity/webauthn-signal-api" ><span class="devsite-nav-text" tooltip>Keep passkeys consistent with the server</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/identity/passkeys/developer-guides/upgrades" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/identity/passkeys/developer-guides/upgrades" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/identity/passkeys/developer-guides/upgrades" ><span class="devsite-nav-text" tooltip>Passkey upgrades</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/codelabs/passkey-form-autofill/" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/codelabs/passkey-form-autofill/" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/codelabs/passkey-form-autofill/" ><span class="devsite-nav-text" tooltip>[Codelab] Implement passkeys with form autofill</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/codelabs/webauthn-reauth/" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/codelabs/webauthn-reauth/" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/codelabs/webauthn-reauth/" ><span class="devsite-nav-text" tooltip>[Codelab] Set up a re-authentication functionality with WebAuthn</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Build authentication with identity federation</span> </div></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/identity/protocols/oauth2" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/identity/protocols/oauth2" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/identity/protocols/oauth2" ><span class="devsite-nav-text" tooltip>Use OAuth 2.0 to access Google APIs</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-external"><a href="https://developers.google.com/identity/protocols/oauth2/openid-connect" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: https://developers.google.com/identity/protocols/oauth2/openid-connect" track-type="bookNav" track-name="click" track-metadata-eventdetail="https://developers.google.com/identity/protocols/oauth2/openid-connect" ><span class="devsite-nav-text" tooltip>Set up OpenID Connect compliant OAuth 2.0</span><span class="devsite-nav-icon material-icons" data-icon="external" data-title="External" aria-hidden="true"></span></a></li> <li class="devsite-nav-item devsite-nav-heading"><div class="devsite-nav-title devsite-nav-title-no-path"> <span class="devsite-nav-text" tooltip>Case studies</span> </div></li> <li class="devsite-nav-item"><a href="/articles/yahoo-japan-identity-case-study" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /articles/yahoo-japan-identity-case-study" track-type="bookNav" track-name="click" track-metadata-eventdetail="/articles/yahoo-japan-identity-case-study" ><span class="devsite-nav-text" tooltip>Yahoo! JAPAN&#39;s password-free authentication reduced inquiries by 25%, sped up sign-in time by 2.6x</span></a></li> <li class="devsite-nav-item"><a href="/goibibo#web-otp" class="devsite-nav-title gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Book nav link, pathname: /goibibo#web-otp" track-type="bookNav" track-name="click" track-metadata-eventdetail="/goibibo#web-otp" ><span class="devsite-nav-text" tooltip>Goibibo dropped OTP retry on sign-up by 25% with WebOTP</span></a></li> </ul> </div> </div> </nav> </devsite-book-nav> <section id="gc-wrapper"> <main role="main" class="devsite-main-content" has-book-nav has-sidebar > <div class="devsite-sidebar"> <div class="devsite-sidebar-content"> <devsite-toc class="devsite-nav" role="navigation" aria-label="On this page" depth="2" scrollbars ></devsite-toc> <devsite-recommendations-sidebar class="nocontent devsite-nav"> </devsite-recommendations-sidebar> </div> </div> <devsite-content> <article class="devsite-article"> <div class="devsite-article-meta nocontent" role="navigation"> <ul class="devsite-breadcrumb-list" aria-label="Breadcrumb"> <li class="devsite-breadcrumb-item "> <a href="https://web.dev/" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="1" track-type="globalNav" track-name="breadcrumb" track-metadata-position="1" track-metadata-eventdetail="" > Home </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://web.dev/articles" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="2" track-type="globalNav" track-name="breadcrumb" track-metadata-position="2" track-metadata-eventdetail="Articles" > Articles </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://web.dev/explore" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="3" track-type="globalNav" track-name="breadcrumb" track-metadata-position="3" track-metadata-eventdetail="" > Explore </a> </li> <li class="devsite-breadcrumb-item "> <div class="devsite-breadcrumb-guillemet material-icons" aria-hidden="true"></div> <a href="https://web.dev/explore/identity" class="devsite-breadcrumb-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Breadcrumbs" data-value="4" track-type="globalNav" track-name="breadcrumb" track-metadata-position="4" track-metadata-eventdetail="" > Identity </a> </li> </ul> <devsite-thumb-rating position="header"> </devsite-thumb-rating> </div> <h1 class="devsite-page-title" tabindex="-1"> Sign-up form best practices </h1> <devsite-feature-tooltip ack-key="AckCollectionsBookmarkTooltipDismiss" analytics-category="Site-Wide Custom Events" analytics-action-show="Callout Profile displayed" analytics-action-close="Callout Profile dismissed" analytics-label="Create Collection Callout" class="devsite-page-bookmark-tooltip nocontent" dismiss-button="true" id="devsite-collections-dropdown" dismiss-button-text="Dismiss" close-button-text="Got it"> <devsite-bookmark></devsite-bookmark> <span slot="popout-heading"> Stay organized with collections </span> <span slot="popout-contents"> Save and categorize content based on your preferences. </span> </devsite-feature-tooltip> <div class="devsite-page-title-meta"><devsite-view-release-notes></devsite-view-release-notes></div> <devsite-toc class="devsite-nav" depth="2" devsite-toc-embedded > </devsite-toc> <div class="devsite-article-body clearfix "> <p>Help your users sign up, log in and manage their account details with a minimum of fuss.</p> <p> <div class="wd-authors" translate="no"> <div class="wd-author"> <img class="devsite-landing-row-item-icon" alt="Sam Dutton" src="https://web.dev/images/authors/samdutton.jpg" decoding="async" height="64" loading="lazy" width="64"> <div> <span> Sam Dutton </span> <div class="wd-author__links"> <a href="https://twitter.com/sw12" aria-label="Sam Dutton on X" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 300 271"> <title>X</title> <path fill="currentColor" d="m236 0h46l-101 115 118 156h-92.6l-72.5-94.8-83 94.8h-46l107-123-113-148h94.9l65.5 86.6zm-16.1 244h25.5l-165-218h-27.4z"></path> </svg></a> <a href="https://github.com/samdutton" aria-label="Sam Dutton on GitHub" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32.6 31.8"> <title>GitHub</title> <path d="M16.3 0C7.3 0 0 7.3 0 16.3c0 7.2 4.7 13.3 11.1 15.5.8.1 1.1-.4 1.1-.8v-2.8c-4.5 1-5.5-2.2-5.5-2.2-.7-1.9-1.8-2.4-1.8-2.4-1.5-1 .1-1 .1-1 1.6.1 2.5 1.7 2.5 1.7 1.5 2.5 3.8 1.8 4.7 1.4.1-1.1.6-1.8 1-2.2-3.6-.4-7.4-1.8-7.4-8.1 0-1.8.6-3.2 1.7-4.4-.1-.3-.7-2 .2-4.2 0 0 1.4-.4 4.5 1.7 1.3-.4 2.7-.5 4.1-.5 1.4 0 2.8.2 4.1.5 3.1-2.1 4.5-1.7 4.5-1.7.9 2.2.3 3.9.2 4.3 1 1.1 1.7 2.6 1.7 4.4 0 6.3-3.8 7.6-7.4 8 .6.5 1.1 1.5 1.1 3V31c0 .4.3.9 1.1.8 6.5-2.2 11.1-8.3 11.1-15.5C32.6 7.3 25.3 0 16.3 0z" fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" /> </svg></a> <a href="https://glitch.com/@samdutton" aria-label="Sam Dutton on Glitch" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 32 32"> <title>Glitch</title> <path fill="currentColor" d="M31.734 16.76c-.385-.198-4.536 1.865-5.427 1.693-2.24-.401-1.828-.667-4.839-1.359-1.203-.266-1.031-.109-1.297-.307-.172-.135-.344-.161-.599-.401 4-.719 6.026-1.693 6.734-1.839.76-.146 5.161 1.958 5.427 1.469.266-.495-.964-1.578-.401-3.031.589-1.464-.693-2.422.016-3.583.719-1.161.573-2.932.396-3.026-.396-.203-4.531 1.865-5.438 1.693-2.24-.417-1.828-.682-4.839-1.359-1.203-.271-1.031-.12-1.297-.323-.266-.198-.521-.13-1.036-.974-.521-.839-6.51-2.13-6.906-2.13-.828 0-2.375 2.13-2.375 2.13s-.599 0-2.401.094c-1.802.094-3.375.896-5.495 2.563C-.173 9.737.134 11.414.134 11.414s1.969.667 1.969 1.042c0 .359-1.729.802-1.729.802 1.12 1.411 4.583 2.745 5.464 2.745h.693c-1.438.281-2.823 1.068-4.583 2.438-2.12 1.698-1.813 3.375-1.813 3.375s1.969.667 1.969 1.026-1.729.802-1.729.802c1.12 1.427 4.583 2.76 5.464 2.76.844 0 1.427.026 2.495-.172.078.172.906 1.932 2.599 2.292 1.786.385 2.776.078 2.776.078s.094-.786-.323-1.573c1.547.161 3.307.203 5.026-.068 4.76-.719 7.12-1.865 7.896-2.01.76-.161 5.161 1.948 5.427 1.464.266-.505-.964-1.583-.385-3.036.573-1.469-.708-2.417 0-3.589.719-1.161.573-2.932.396-3.026zM4.615 11.828a1.446 1.446 0 0 1-.297-.042h-.052c-.026-.01-.052-.026-.078-.042l-.052-.01-.083-.042h-.052a.418.418 0 0 1-.068-.042l-.068-.052-.063-.036-.057-.042c-.021-.016-.042-.036-.063-.052l-.042-.042c-.026-.026-.047-.052-.068-.078l-.026-.031a1.954 1.954 0 0 1-.094-.104l-.026-.026c-.021-.036-.036-.073-.052-.109l-.026-.036-.057-.083c-.005-.021-.016-.042-.026-.063l-.026-.083-.026-.052-.016-.094-.01-.068c-.01-.026-.021-.052-.026-.078v-.068c.094.573.557 1.016 1.104 1.016.63 0 1.146-.573 1.146-1.297 0-.719-.505-1.307-1.146-1.307-.625 0-1.13.573-1.146 1.281 0-.932.667-1.693 1.495-1.693.823 0 1.479.745 1.479 1.682 0 .932-.667 1.693-1.479 1.693zm-1-1.265c0-.203.13-.365.318-.365s.307.161.307.365c0 .198-.135.344-.307.344s-.318-.161-.318-.344zm1 11.651a.712.712 0 0 1-.146 0l-.057-.016a.6.6 0 0 1-.094-.01l-.052-.016-.078-.026-.052-.026c-.031-.005-.057-.016-.083-.026l-.052-.026c-.021-.016-.047-.026-.068-.042L3.881 22l-.068-.052-.052-.042-.068-.052-.042-.042c-.031-.031-.063-.057-.089-.094a.671.671 0 0 1-.094-.12l-.031-.026c-.016-.031-.036-.063-.052-.094l-.026-.052c-.016-.026-.036-.052-.052-.078l-.026-.057-.026-.094-.026-.052-.031-.094-.01-.052c-.01-.031-.021-.063-.026-.094v-.068c.094.573.557 1.016 1.104 1.016.63 0 1.146-.573 1.146-1.292 0-.724-.505-1.297-1.146-1.297-.625 0-1.13.563-1.146 1.266 0-.932.667-1.693 1.495-1.693.823 0 1.479.76 1.479 1.682 0 .917-.667 1.693-1.479 1.693zm-1-1.266c0-.188.13-.349.318-.349s.307.161.307.349c0 .188-.135.344-.307.344s-.318-.146-.318-.344zm6.77-7.333v-.042l.042-.078.078-.297c.182-.583.344-1.172.479-1.771.161-.708.229-1.281.203-1.599-.016-.12-.031-.245-.052-.359a8.276 8.276 0 0 0-.521-1.724l-.083-.172-.026-.068c-.12-.266.057-.573.323-.557h.188l.531.036 2.104.109 1.151.078a28.24 28.24 0 0 1 10.573 2.828l.891.401c.172.078.266.307.188.505-.068.188-.266.292-.438.214l-.896-.401a27.695 27.695 0 0 0-10.359-2.786l-1.146-.068-.51-.026-1.599-.094h-.156c.188.51.339 1.031.453 1.562l.063.427c.042.453-.036 1.078-.224 1.88l-.203.823a23.62 23.62 0 0 1-.385 1.323l-.026.078v.042c-.068.188-.266.292-.438.214-.177-.068-.271-.292-.203-.495zm-2-6.349a.307.307 0 0 1 .479.026c.208.26.396.536.563.828.292.531.495 1.068.547 1.615.026.307 0 .651-.052 1.026a8.718 8.718 0 0 1-.271 1.104c-.094.313-.208.62-.333.922-.078.188-.276.266-.453.172-.172-.094-.24-.318-.156-.521l.026-.052.068-.172c.073-.198.146-.396.214-.599.099-.328.182-.661.24-1 .052-.307.063-.573.052-.802a3.47 3.47 0 0 0-.453-1.292 4.794 4.794 0 0 0-.443-.667l-.036-.042a.417.417 0 0 1 .026-.531zm1.537 13.869c-.063.38-.151.76-.271 1.13a9.549 9.549 0 0 1-.333.906c-.078.188-.276.266-.453.177-.172-.094-.24-.323-.156-.521l.026-.057.068-.172c.073-.198.146-.396.214-.599.099-.328.182-.661.24-1 .052-.307.063-.573.036-.802a3.365 3.365 0 0 0-.438-1.276 4.794 4.794 0 0 0-.443-.667l-.036-.057a.417.417 0 0 1 .026-.531.3.3 0 0 1 .464 0c.214.266.396.547.563.839.292.536.495 1.083.547 1.615.026.307 0 .651-.052 1.026zm16.531.157c-.068.188-.266.297-.438.214l-.896-.401a27.695 27.695 0 0 0-10.359-2.786l-1.135-.063h-.063l-.458-.026c-.583-.036-1.172-.068-1.755-.094l.036.078c.234.615.396 1.255.479 1.906.042.453-.036 1.078-.224 1.88l-.203.828a24.99 24.99 0 0 1-.385 1.333l-.026.068v.036c-.068.203-.266.297-.438.229a.42.42 0 0 1-.203-.51v-.026l.042-.078.078-.292c.182-.589.344-1.177.479-1.776.161-.708.229-1.281.203-1.599-.016-.12-.031-.24-.052-.359a7.996 7.996 0 0 0-.521-1.708l-.052-.12-.031-.068-.026-.063c-.12-.271.057-.578.323-.563h.188l.531.042 2.12.104 1.135.083a28.14 28.14 0 0 1 10.573 2.823l.891.401c.172.078.266.307.188.505z"/> </svg></a> <a href="https://techhub.social/@samdutton" aria-label="Sam Dutton on Mastodon" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 16 16"> <title>Mastodon</title> <path fill="currentColor" d="M 15.659 9.592 C 15.424 10.72 13.553 11.956 11.404 12.195 C 10.283 12.32 9.18 12.434 8.003 12.384 C 6.079 12.302 4.56 11.956 4.56 11.956 C 4.56 12.13 4.572 12.297 4.595 12.452 C 4.845 14.224 6.478 14.33 8.025 14.379 C 9.586 14.429 10.976 14.02 10.976 14.02 L 11.04 15.337 C 11.04 15.337 9.948 15.884 8.003 15.984 C 6.93 16.039 5.598 15.959 4.047 15.576 C 0.683 14.746 0.104 11.4 0.015 8.006 C -0.012 6.998 0.005 6.048 0.005 5.253 C 0.005 1.782 2.443 0.765 2.443 0.765 C 3.672 0.238 5.782 0.017 7.975 0 L 8.029 0 C 10.221 0.017 12.332 0.238 13.561 0.765 C 13.561 0.765 15.999 1.782 15.999 5.253 C 15.999 5.253 16.03 7.814 15.659 9.592 Z M 13.124 5.522 L 13.124 9.725 L 11.339 9.725 L 11.339 5.646 C 11.339 4.786 10.951 4.35 10.175 4.35 C 9.317 4.35 8.887 4.867 8.887 5.891 L 8.887 8.124 L 7.113 8.124 L 7.113 5.891 C 7.113 4.867 6.683 4.35 5.825 4.35 C 5.049 4.35 4.661 4.786 4.661 5.646 L 4.661 9.725 L 2.876 9.725 L 2.876 5.522 C 2.876 4.663 3.111 3.981 3.582 3.476 C 4.067 2.971 4.703 2.712 5.493 2.712 C 6.406 2.712 7.098 3.039 7.555 3.695 L 8 4.39 L 8.445 3.695 C 8.902 3.039 9.594 2.712 10.507 2.712 C 11.297 2.712 11.933 2.971 12.418 3.476 C 12.889 3.981 13.124 4.663 13.124 5.522 Z" style="stroke:none;stroke-miterlimit:10;fill-rule:evenodd;"></path> </svg></a> <a href="https://samdutton.com" aria-label="Sam Dutton's homepage" rel="me"> <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 30 30"> <title>Homepage</title> <circle cx="14.5" cy="14.5" r="13.5" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> <ellipse cx="14.5" cy="14.5" rx="6.1" ry="13.5" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> <path d="M1.6 9.6h25.8M1.6 19.4h25.8" stroke-width="2" stroke-miterlimit="10" fill="none" stroke="currentColor" /> </svg></a> </div> </div> </div> </div></p> <p><devsite-video video-id="Ev2mCzJZLtY"></devsite-video></p> <p>If users ever need to log in to your site, then good sign-up form design is critical. This is especially true for people on poor connections, on mobile, in a hurry, or under stress. Poorly designed sign-up forms get high bounce rates. Each bounce could mean a lost and disgruntled user—not just a missed sign-up opportunity.</p> <aside class="beta"><b>Try it: </b> If you would prefer to learn these best practices with a hands-on tutorial, check out the <a href="/articles/codelab-sign-up-form-best-practices">Sign-up form best practices codelab</a>. </aside> <p>Here is an example of a very simple sign-up form that demonstrates all of the best practices:</p> <div class="wd-embed" style="height: 700px;"> <iframe allow="camera; clipboard-read; clipboard-write; encrypted-media; geolocation; microphone; midi" loading="lazy" src="https://glitch.com/embed/#!/embed/signup-form?attributionHidden=true&sidebarCollapsed=true&path=index.html&previewSize=100" style="height: 100%; width: 100%; border: 0;" title="signup-form on Glitch" ></iframe> </div> <aside class="caution"><b>Caution: </b> This post is about form best practices. It does not explain how to implement sign-up via a third-party identity provider (federated login) or show how to build backend services to authenticate users, store credentials, and manage accounts. <a href="https://developers.google.com/identity/gsi/web/guides/overview">Integrating Google Sign-In into your web app</a> explains how to add federated login to your sign-up options. <a href="https://cloud.google.com/blog/products/gcp/12-best-practices-for-user-account">12 best practices for user account, authorization and password management</a> outlines core back-end principles for managing user accounts. </aside> <h2 id="checklist" data-text="Checklist" tabindex="-1">Checklist</h2> <ul> <li><a href="#no-forced-sign-in">Avoid sign-in if you can</a>.</li> <li><a href="#obvious-account-creation">Make it obvious how to create an account</a>.</li> <li><a href="#obvious-account-details">Make it obvious how to access account details</a>.</li> <li><a href="#cut-clutter">Cut form clutter</a>.</li> <li><a href="#session-length">Consider session length</a>.</li> <li><a href="#help-password-managers">Help password managers securely suggest and store passwords</a>.</li> <li><a href="#no-compromised-passwords">Don&#39;t allow compromised passwords</a>.</li> <li><a href="#allow-password-pasting">Do allow password pasting</a>.</li> <li><a href="#salt-and-hash">Never store or transmit passwords in plain text</a>.</li> <li><a href="#no-forced-password-updates">Don&#39;t force password updates</a>.</li> <li><a href="#password-change">Make it simple to change or reset passwords</a>.</li> <li><a href="#federated-login">Enable federated login</a>.</li> <li><a href="#account-switching">Make account switching simple</a>.</li> <li><a href="#multi-factor-authentication">Consider offering multi-factor authentication</a>.</li> <li><a href="#username">Take care with usernames</a>.</li> <li><a href="#analytics-rum">Test in the field as well as the lab</a>.</li> <li><a href="#test-platforms">Test on a range of browsers, devices and platforms</a>.</li> </ul> <h2 id="no-forced-sign-in" data-text="Avoid sign-in if you can" tabindex="-1">Avoid sign-in if you can</h2> <p>Before you implement a sign-up form and ask users to create an account on your site, consider whether you really need to. Wherever possible you should avoid gating features behind login.</p> <p>The best sign-up form is no sign-up form!</p> <p>By asking a user to create an account, you come between them and what they&#39;re trying to achieve. You&#39;re asking a favor, and asking the user to trust you with personal data. Every password and item of data you store carries privacy and security &quot;data debt&quot;, becoming a cost and liability for your site.</p> <p>If the main reason you ask users to create an account is to save information between navigations or browsing sessions, <a href="/articles/storage-for-the-web">consider using client-side storage</a> instead. For shopping sites, forcing users to create an account to make a purchase is cited as a major reason for shopping cart abandonment. You should <a href="/articles/payment-and-address-form-best-practices#guest-checkout">make guest checkout the default</a>.</p> <h2 id="obvious-account-creation" data-text="Make sign-in obvious" tabindex="-1">Make sign-in obvious</h2> <p>Make it obvious how to create an account on your site, for example with a <strong>Login</strong> or <strong>Sign in</strong> button at the top right of the page. Avoid using an ambiguous icon or vague wording (&quot;Get on board!&quot;, &quot;Join us&quot;) and don&#39;t hide login in a navigational menu. The usability expert Steve Krug summed up this approach to website usability: <a href="https://uxplanet.org/dont-make-me-think-20-wise-thoughts-about-usability-from-steve-krug-876b563f1d63">Don&#39;t make me think!</a> If you need to convince others on your web team, use <a href="#analytics-rum">analytics</a> to show the impact of different options.</p> <figure> <img src="/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e.jpg" alt="Two screenshots of a mockup ecommerce website viewed on an Android phone. The one on the left uses an icon for the sign-in link that's somewhat ambiguous; the one on the right simply says 'Sign in'" width="800" height="737" srcset="https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_36.jpg 36w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_48.jpg 48w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_72.jpg 72w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_96.jpg 96w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_480.jpg 480w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_720.jpg 720w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_856.jpg 856w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_960.jpg 960w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_1440.jpg 1440w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_1920.jpg 1920w,https://web.dev/static/articles/sign-up-form-best-practices/image/two-screenshots-a-mockup-62ee25473e20e_2880.jpg 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="wd-caption">Make sign-in obvious. An icon may be ambiguous, but a <b>Sign in</b> button or link is obvious.</figcaption> </figure> <aside class="note"><b>Note: </b> You may be wondering whether to add a button (or link) to create an account and another one for existing users to sign in. Many popular sites now simply display a single <strong>Sign in</strong> button. When the user taps or clicks on that, they also get a link to create an account if necessary. That's a common pattern now, and your users are likely to understand it, but you can use <a href="##analytics-rum">interaction analytics</a> to monitor whether or not a single button works best. </aside> <figure> <img src="/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a.jpg" alt="Screenshots of sign-in for Gmail: one page, showing Sign in button, when clicked leads to form that also has a Create account link." width="800" height="545" srcset="https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_36.jpg 36w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_48.jpg 48w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_72.jpg 72w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_96.jpg 96w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_480.jpg 480w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_720.jpg 720w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_856.jpg 856w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_960.jpg 960w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_1440.jpg 1440w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_1920.jpg 1920w,https://web.dev/static/articles/sign-up-form-best-practices/image/screenshots-sign-for-gm-52c4c6c94532a_2880.jpg 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="wd-caption">The Gmail sign-in page has a link to create an account.<br> At window sizes larger than shown here, Gmail displays a <b>Sign in</b> link and a <b>Create an account</b> button.</figcaption> </figure> <p>Make sure to link accounts for users who sign up via an identity provider such as Google and who also sign up using email and password. That&#39;s easy to do if you can access a user&#39;s email address from the profile data from the identity provider, and match the two accounts. The code below shows how to access email data for a Google Sign-in user.</p> <pre class="prettyprint lang-js" translate="no" dir="ltr"><code translate="no" dir="ltr">// auth2 is initialized with gapi.auth2.init() if (auth2.isSignedIn.get()) { var profile = auth2.currentUser.get().getBasicProfile(); console.log(`Email: ${profile.getEmail()}`); } </code></pre> <h3 id="obvious-account-details" data-text="Make it obvious how to access account details" tabindex="-1">Make it obvious how to access account details</h3> <p>Once a user has signed in, make it clear how to access account details. In particular, make it obvious how to <a href="#password-change">change or reset passwords</a>.</p> <h2 id="cut-clutter" data-text="Cut form clutter" tabindex="-1">Cut form clutter</h2> <p>In the sign-up flow, your job is to minimize complexity and keep the user focused. Cut the clutter. This is not the time for distractions and temptations!</p> <figure> <video controls autoplay loop muted playsinline> <source src="/static/articles/sign-up-form-best-practices/video/avoid-distractions.mp4" type="video/mp4"> </video> <figcaption class="wd-caption">Don't distract users from completing sign-up.</figcaption> </figure> <p>On sign-up, ask for as little as possible. Collect additional user data (such as name and address) only when you need to, and when the user sees a clear benefit from providing that data. Bear in mind that every item of data you communicate and store incurs cost and liability.</p> <p>Don&#39;t double up your inputs just to make sure users get their contact details right. That slows down form completion and doesn&#39;t make sense if form fields are autofilled. Instead, send a confirmation code to the user once they&#39;ve entered their contact details, then continue with account creation once they respond. This is a common sign-up pattern: users are used to it.</p> <p>You may want to consider password-free sign-in by sending users a code every time they sign in on a new device or browser. Sites such as Slack and Medium use a version of this.</p> <figure> <video controls autoplay loop muted playsinline> <source src="/static/articles/sign-up-form-best-practices/video/medium-sign-in.mp4" type="video/mp4"> </video> <figcaption class="wd-caption">Password-free sign-in on medium.com.</figcaption> </figure> <p>As with federated login, this has the added benefit that you don&#39;t have to manage user passwords.</p> <h2 id="session-length" data-text="Consider session length" tabindex="-1">Consider session length</h2> <p>Whatever approach you take to user identity, you&#39;ll need to make a careful decision about session length: how long the user remains logged in, and what might cause you to log them out.</p> <p>Consider whether your users are on mobile or desktop, and whether they are sharing on desktop, or sharing devices.</p> <aside class="note"><b>Note: </b> You can get around some of the issues of shared devices by enforcing re-authentication for sensitive features, for example when a purchase is made or an account updated. You can find out more about ways to implement re-authentication from the codelab <a href="https://codelabs.developers.google.com/codelabs/webauthn-reauth/#0">Your First WebAuthn App</a>. </aside> <h2 id="help-password-managers" data-text="Help password managers securely suggest and store passwords" tabindex="-1">Help password managers securely suggest and store passwords</h2> <p>You can help third party and built-in browser password managers suggest and store passwords, so that users don&#39;t need to choose, remember or type passwords themselves. Password managers work well in modern browsers, synchronizing accounts across devices, across platform-specific and web apps—and for new devices.</p> <p>This makes it extremely important to code sign-up forms correctly, in particular to use the correct autocomplete values. For sign-up forms use <code translate="no" dir="ltr">autocomplete=&quot;new-password&quot;</code> for new passwords, and add correct autocomplete values to other form fields wherever possible, such as <code translate="no" dir="ltr">autocomplete=&quot;email&quot;</code> and <code translate="no" dir="ltr">autocomplete=&quot;tel&quot;</code>. You can also help password managers by using different <code translate="no" dir="ltr">name</code> and <code translate="no" dir="ltr">id</code> values in sign-up and sign-in forms, for the <code translate="no" dir="ltr">form</code> element itself, as well as any <code translate="no" dir="ltr">input</code>, <code translate="no" dir="ltr">select</code> and <code translate="no" dir="ltr">textarea</code> elements.</p> <p>You should also use the appropriate <a href="https://developer.mozilla.org/docs/Web/HTML/Element/input/email"><code translate="no" dir="ltr">type</code> attribute</a> to provide the right keyboard on mobile and enable basic built-in validation by the browser. You can find out more from <a href="/articles/payment-and-address-form-best-practices#make_it_easy_for_users_to_enter_data">Payment and address form best practices</a>.</p> <aside class="note"><b>Note: </b> <a href="/articles/sign-in-form-best-practices">Sign-in form best practices</a> has lots more tips on how to improve form design, layout and accessibility, and how to code forms correctly in order to take advantage of built-in browser features. </aside> <h2 id="secure-passwords" data-text="Ensure users enter secure passwords" tabindex="-1">Ensure users enter secure passwords</h2> <p>Enabling password managers to suggest passwords is the best option, and you should encourage users to accept the strong passwords suggested by browsers and third-party browser managers.</p> <p>However, many users want to enter their own passwords, so you need to implement rules for password strength. The US National Institute of Standards and Technology explains <a href="https://pages.nist.gov/800-63-3/sp800-63b.html#5-authenticator-and-verifier-requirements">how to avoid insecure passwords</a>.</p> <aside class="warning"><b>Warning: </b> Sign-up forms on some sites have password validation rules that don't allow the strong passwords generated by browser and third-party password managers. Make sure your site doesn't do this, since it interrupts form completion, annoys users, and requires users to make up their own passwords, which may be less secure than those generated by password managers. </aside> <h2 id="no-compromised-passwords" data-text="Don't allow compromised passwords" tabindex="-1">Don't allow compromised passwords</h2> <p>Whatever rules you choose for passwords, you should never allow passwords that have been <a href="https://haveibeenpwned.com/PwnedWebsites">exposed in security breaches</a>.</p> <p>Once a user has entered a password, you need to check that it&#39;s not a password that&#39;s already been compromised. The site <a href="https://haveibeenpwned.com/Passwords">Have I Been Pwned</a> provides an API for password checking, or you can run this as a service yourself.</p> <p>Google&#39;s Password Manager also allows you to <a href="https://passwords.google.com/checkup">check if any of your existing passwords have been compromised</a>.</p> <p>If you do reject the password that a user proposes, tell them specifically why it was rejected. <a href="https://baymard.com/blog/inline-form-validation">Show problems inline and explain how to fix them</a>, as soon as the user has entered a value—not after they&#39;ve submitted the sign-up form and had to wait for a response from your server.</p> <figure> <video controls autoplay loop muted playsinline> <source src="/static/articles/sign-up-form-best-practices/video/password-validation.mp4" type="video/mp4"> </video> <figcaption class="wd-caption">Be clear why a password is rejected.</figcaption> </figure> <h2 id="allow-password-pasting" data-text="Don't prohibit password pasting" tabindex="-1">Don't prohibit password pasting</h2> <p>Some sites don&#39;t allow text to be pasted into password inputs.</p> <p>Disallowing password pasting annoys users, encourages passwords that are memorable (and therefore may be easier to compromise) and, according to organizations such as the UK National Cyber Security Centre, may actually <a href="https://www.ncsc.gov.uk/blog-post/let-them-paste-passwords">reduce security</a>. Users only become aware that pasting is disallowed <em>after</em> they try to paste their password, so <a href="https://github.com/OWASP/owasp-masvs/issues/106">disallowing password pasting doesn&#39;t avoid clipboard vulnerabilities</a>.</p> <h2 id="salt-and-hash" data-text="Never store or transmit passwords in plain text" tabindex="-1">Never store or transmit passwords in plain text</h2> <p>Make sure to <a href="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#Use_a_cryptographically_strong_credential-specific_salt">salt and hash</a> passwords—and <a href="https://www.schneier.com/blog/archives/2011/04/schneiers_law.html">don&#39;t try to invent your own hashing algorithm</a>!</p> <h2 id="no-forced-password-updates" data-text="Don't force password updates" tabindex="-1">Don't force password updates</h2> <p><a href="https://pages.nist.gov/800-63-3/sp800-63b.html#-5112-memorized-secret-verifiers:%7E:text=Verifiers%20SHOULD%20NOT%20require%20memorized%20secrets%20to%20be%20changed%20arbitrarily%20(e.g.%2C%20periodically).">Don&#39;t force users to update their passwords arbitrarily.</a></p> <p>Forcing password updates can be costly for IT departments, annoying to users, and <a href="https://pages.nist.gov/800-63-FAQ/#q-b05">doesn&#39;t have much impact on security</a>. It&#39;s also likely to encourage people to use insecure memorable passwords, or to keep a physical record of passwords.</p> <p>Rather than force password updates, you should monitor for unusual account activity and warn users. If possible you should also monitor for passwords that become compromised because of data breaches.</p> <p>You should also provide your users with access to their account login history, showing them where and when a login happened.</p> <figure> <img src="/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264.jpg" alt="Gmail account activity page" width="800" height="469" srcset="https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_36.jpg 36w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_48.jpg 48w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_72.jpg 72w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_96.jpg 96w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_480.jpg 480w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_720.jpg 720w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_856.jpg 856w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_960.jpg 960w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_1440.jpg 1440w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_1920.jpg 1920w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-account-activity-pa-c70c73f9a3264_2880.jpg 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="wd-caption"><a href="https://support.google.com/mail/answer/45938" title="Find out how to view Gmail account activity.">Gmail account activity page</a>.</figcaption> </figure> <h2 id="password-change" data-text="Make it simple to change or reset passwords" tabindex="-1">Make it simple to change or reset passwords</h2> <p>Make it obvious to users where and how to <strong>update</strong> their account password. On some sites, it&#39;s surprisingly difficult.</p> <p>You should, of course, also make it simple for users to <strong>reset</strong> their password if they forget it. The Open Web Application Security Project provides detailed guidance on <a href="https://cheatsheetseries.owasp.org/cheatsheets/Forgot_Password_Cheat_Sheet.html">how to handle lost passwords</a>.</p> <p>To keep your business and your users safe, it&#39;s especially important to help users change their password if they discover that it&#39;s been compromised. To make this easier, you should add a <a href="https://w3c.github.io/webappsec-change-password-url/"><code translate="no" dir="ltr">/.well-known/change-password</code></a> URL to your site that redirects to your password management page. This enables password managers to navigate your users directly to the page where they can change their password for your site. This feature is now implemented in Safari, Chrome, and is coming to other browsers. <a href="/articles/change-password-url">Help users change passwords easily by adding a well-known URL for changing passwords</a> explains how to implement this.</p> <p>You should also make it simple for users to delete their account if that&#39;s what they want.</p> <h2 id="federated-login" data-text="Offer login via third-party identity providers" tabindex="-1">Offer login via third-party identity providers</h2> <p>Many users prefer to log in to websites using an email address and password sign-up form. However, you should also enable users to log in via a third party identity provider, also known as federated login.</p> <figure> <img src="/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13.jpg" alt="WordPress login page" width="800" height="513" srcset="https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_36.jpg 36w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_48.jpg 48w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_72.jpg 72w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_96.jpg 96w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_480.jpg 480w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_720.jpg 720w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_856.jpg 856w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_960.jpg 960w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_1440.jpg 1440w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_1920.jpg 1920w,https://web.dev/static/articles/sign-up-form-best-practices/image/wordpress-login-page-b16b91f2dcb13_2880.jpg 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="wd-caption">WordPress login page, with Google and Apple login options.</figcaption> </figure> <p>This approach has several advantages. For users who create an account using federated login, you don&#39;t need to ask for, communicate, or store passwords.</p> <p>You may also be able to access additional verified profile information from federated login, such as an email address—which means the user doesn&#39;t have to enter that data and you don&#39;t need to do the verification yourself. Federated login can also make it much easier for users when they get a new device.</p> <p><a href="https://developers.google.com/identity/gsi/web/guides/overview">Integrating Google Sign-In into your web app</a> explains how to add federated login to your sign-up options. <a href="https://en.wikipedia.org/wiki/Federated_identity#Examples">Many other</a> identity platforms are available.</p> <aside class="note"><b>Note: </b> &quot;First day experience&quot; when you get a new device is increasingly important. Users expect to log in from multiple devices including their phone, laptop, desktop, tablet, TV, or from a car. If your sign-up and sign-in forms aren't seamless, this is a moment where you risk losing users, or at least losing contact with them until they get set up again. You need to make it as quick and easy as possible for users on new devices to get up and running on your site. This is another area where federated login can help. </aside> <h2 id="account-switching" data-text="Make account switching simple" tabindex="-1">Make account switching simple</h2> <p>Many users share devices and swap between accounts using the same browser. Whether users access federated login or not, you should make account switching simple.</p> <figure> <img src="/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6.jpg" alt="Gmail, showing account switching" width="800" height="494" srcset="https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_36.jpg 36w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_48.jpg 48w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_72.jpg 72w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_96.jpg 96w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_480.jpg 480w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_720.jpg 720w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_856.jpg 856w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_960.jpg 960w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_1440.jpg 1440w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_1920.jpg 1920w,https://web.dev/static/articles/sign-up-form-best-practices/image/gmail-showing-account-sw-452d02090bac6_2880.jpg 2880w" sizes="(max-width: 840px) 100vw, 856px"> <figcaption class="wd-caption">Account switching on Gmail.</figcaption> </figure> <h2 id="multi-factor-authentication" data-text="Consider offering multi-factor authentication" tabindex="-1">Consider offering multi-factor authentication</h2> <p>Multi-factor authentication means ensuring that users provide authentication in more than one way. For example, as well as requiring the user to set a password, you might also enforce verification using a one-time-passcode sent by email or an SMS text message, or by using an app-based one-time code, security key or fingerprint sensor. <a href="/articles/sms-otp-form">SMS OTP best practices</a> and <a href="https://developer.chrome.com/blog/webauthn">Enabling Strong Authentication with WebAuthn</a> explain how to implement multi-factor authentication.</p> <p>You should certainly offer (or enforce) multi-factor authentication if your site handles personal or sensitive information.</p> <h2 id="username" data-text="Take care with usernames" tabindex="-1">Take care with usernames</h2> <p>Don&#39;t insist on a username unless (or until) you need one. Enable users to sign up and sign in with only an email address (or telephone number) and password—or <a href="#federated-login">federated login</a> if they prefer. Don&#39;t force them to choose and remember a username.</p> <p>If your site does require usernames, don&#39;t impose unreasonable rules on them, and don&#39;t stop users from updating their username. On your backend you should generate a unique ID for every user account, not an identifier based on personal data such as username.</p> <p>Also make sure to use <code translate="no" dir="ltr">autocomplete=&quot;username&quot;</code> for usernames.</p> <aside class="caution"><b>Caution: </b> As with personal names, ensure that usernames aren't restricted to characters from the <a href="https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Types:~:text=Latin%20alphabet">Latin alphabet</a>. <a href="/articles/payment-and-address-form-best-practices#unicode-matching">Payment and address form best practices</a> explains how and why to validate using Unicode letter matching. </aside> <h2 id="test-platforms" data-text="Test on a range of devices, platforms, browsers and versions" tabindex="-1">Test on a range of devices, platforms, browsers and versions</h2> <p>Test sign-up forms on the platforms most common for your users. Form element functionality may vary, and differences in viewport size can cause layout problems. BrowserStack enables <a href="https://www.browserstack.com/open-source">free testing for open source projects</a> on a range of devices and browsers.</p> <h2 id="analytics-rum" data-text="Implement analytics and Real User Monitoring" tabindex="-1">Implement analytics and Real User Monitoring</h2> <p>You need <a href="/articles/how-to-measure-speed#lab_data_vs_field_data">field data as well as lab data</a> to understand how users experience your sign-up forms. Analytics and <a href="https://developer.mozilla.org/docs/Web/Performance/Rum-vs-Synthetic#Real_User_Monitoring">Real User Monitoring</a> (RUM) provide data for the actual experience of your users, such as how long sign-up pages take to load, which UI components users interact with (or not) and how long it takes users to complete sign-up.</p> <ul> <li><strong>Page analytics</strong>: <a href="https://analytics.google.com/analytics/academy/course/6">page views, bounce rates and exits</a> for every page in your sign-up flow.</li> <li><strong>Interaction analytics</strong>: <a href="https://support.google.com/analytics/answer/6180923">goal funnels</a> and <a href="https://developers.google.com/analytics/devguides/collection/gtagjs/events">events</a> indicate where users abandon the sign-up flow and what proportion of users click buttons, links, and other components of your sign-up pages.</li> <li><strong>Website performance</strong>: <a href="/articles/user-centric-performance-metrics">user-centric metrics</a> can tell you if your sign-up flow is slow to load or <a href="/articles/cls">visually unstable</a>.</li> </ul> <p>Small changes can make a big difference to completion rates for sign-up forms. Analytics and RUM enable you to optimize and prioritize changes, and monitor your site for problems that aren&#39;t exposed by local testing.</p> <h2 id="resources" data-text="Keep learning" tabindex="-1">Keep learning</h2> <ul> <li><a href="/articles/sign-in-form-best-practices">Sign-in form best practices</a></li> <li><a href="/articles/payment-and-address-form-best-practices">Payment and address form best practices</a></li> <li><a href="/learn/forms">Create Amazing Forms</a></li> <li><a href="https://www.smashingmagazine.com/2018/08/best-practices-for-mobile-form-design/">Best Practices For Mobile Form Design</a></li> <li><a href="/articles/more-capable-form-controls">More capable form controls</a></li> <li><a href="https://webaim.org/techniques/forms/">Creating Accessible Forms</a></li> <li><a href="https://developer.chrome.com/blog/credential-management-api">Streamlining the Sign-up Flow Using Credential Management API</a></li> <li><a href="/articles/web-otp">Verify phone numbers on the web with the WebOTP API</a></li> </ul> <p>Photo by <a href="https://unsplash.com/@ecowarriorprincess">@ecowarriorprincess</a> on <a href="https://unsplash.com/photos/lUShu7PHIGA">Unsplash</a>.</p> </div> <devsite-thumb-rating position="footer"> </devsite-thumb-rating> <div class="devsite-floating-action-buttons"> </div> </article> <devsite-content-footer class="nocontent"> <p>Except as otherwise noted, the content of this page is licensed under the <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 License</a>, and code samples are licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. For details, see the <a href="https://developers.google.com/site-policies">Google Developers Site Policies</a>. Java is a registered trademark of Oracle and/or its affiliates.</p> <p>Last updated 2020-12-09 UTC.</p> </devsite-content-footer> <devsite-notification > </devsite-notification> <div class="devsite-content-data"> <template class="devsite-content-data-template"> [[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2020-12-09 UTC."],[],[]] </template> </div> </devsite-content> </main> <devsite-footer-promos class="devsite-footer"> </devsite-footer-promos> <devsite-footer-linkboxes class="devsite-footer"> <nav class="devsite-footer-linkboxes nocontent" aria-label="Footer links"> <ul class="devsite-footer-linkboxes-list"> <li class="devsite-footer-linkbox wd-footer-promo"> <h3 class="devsite-footer-linkbox-heading no-link">web.dev</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <h3 class="devsite-footer-linkbox-heading no-link"> web.dev </h3> <div class="devsite-footer-linkbox-description">We want to help you build beautiful, accessible, fast, and secure websites that work cross-browser, and for all of your users. This site is our home for content to help you on that journey, written by members of the Chrome team, and external experts.</div> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Contribute</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues/new?component=1400680&amp;template=1857359" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > File a bug </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://issuetracker.google.com/issues?q=status:open%20componentid:1400680&amp;s=created_time:desc" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > See open issues </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Related Content</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://developer.chrome.com/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > Chrome for Developers </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://blog.chromium.org/" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > Chromium updates </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/case-studies" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Case studies </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/shows" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > Podcasts &amp; shows </a> </li> </ul> </li> <li class="devsite-footer-linkbox "> <h3 class="devsite-footer-linkbox-heading no-link">Follow</h3> <ul class="devsite-footer-linkbox-list"> <li class="devsite-footer-linkbox-item"> <a href="https://twitter.com/ChromiumDev" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 1)" > @ChromiumDev on X </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.youtube.com/user/ChromeDevelopers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 2)" > YouTube </a> </li> <li class="devsite-footer-linkbox-item"> <a href="https://www.linkedin.com/showcase/chrome-for-developers" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 3)" > Chrome for Developers on LinkedIn </a> </li> <li class="devsite-footer-linkbox-item"> <a href="/static/blog/feed.xml" class="devsite-footer-linkbox-link gc-analytics-event" data-category="Site-Wide Custom Events" data-label="Footer Link (index 4)" > RSS </a> </li> </ul> </li> </ul> </nav> </devsite-footer-linkboxes> <devsite-footer-utility class="devsite-footer"> <div class="devsite-footer-utility nocontent"> <nav class="devsite-footer-utility-links" aria-label="Utility links"> <ul class="devsite-footer-utility-list"> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/terms" data-category="Site-Wide Custom Events" data-label="Footer Terms link" > Terms </a> </li> <li class="devsite-footer-utility-item "> <a class="devsite-footer-utility-link gc-analytics-event" href="//policies.google.com/privacy" data-category="Site-Wide Custom Events" data-label="Footer Privacy link" > Privacy </a> </li> <li class="devsite-footer-utility-item glue-cookie-notification-bar-control"> <a class="devsite-footer-utility-link gc-analytics-event" href="#" data-category="Site-Wide Custom Events" data-label="Footer Manage cookies link" aria-hidden="true" > Manage cookies </a> </li> </ul> <devsite-language-selector> <ul role="presentation"> <li role="presentation"> <a role="menuitem" lang="en" >English</a> </li> <li role="presentation"> <a role="menuitem" lang="de" >Deutsch</a> </li> <li role="presentation"> <a role="menuitem" lang="es" >Español</a> </li> <li role="presentation"> <a role="menuitem" lang="es_419" >Español – América Latina</a> </li> <li role="presentation"> <a role="menuitem" lang="fr" >Français</a> </li> <li role="presentation"> <a role="menuitem" lang="id" >Indonesia</a> </li> <li role="presentation"> <a role="menuitem" lang="it" >Italiano</a> </li> <li role="presentation"> <a role="menuitem" lang="pl" >Polski</a> </li> <li role="presentation"> <a role="menuitem" lang="pt_br" >Português – Brasil</a> </li> <li role="presentation"> <a role="menuitem" lang="vi" >Tiếng Việt</a> </li> <li role="presentation"> <a role="menuitem" lang="tr" >Türkçe</a> </li> <li role="presentation"> <a role="menuitem" lang="ru" >Русский</a> </li> <li role="presentation"> <a role="menuitem" lang="he" >עברית</a> </li> <li role="presentation"> <a role="menuitem" lang="ar" >العربيّة</a> </li> <li role="presentation"> <a role="menuitem" lang="fa" >فارسی</a> </li> <li role="presentation"> <a role="menuitem" lang="hi" >हिंदी</a> </li> <li role="presentation"> <a role="menuitem" lang="bn" >বাংলা</a> </li> <li role="presentation"> <a role="menuitem" lang="th" >ภาษาไทย</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_cn" >中文 – 简体</a> </li> <li role="presentation"> <a role="menuitem" lang="zh_tw" >中文 – 繁體</a> </li> <li role="presentation"> <a role="menuitem" lang="ja" >日本語</a> </li> <li role="presentation"> <a role="menuitem" lang="ko" >한국어</a> </li> </ul> </devsite-language-selector> </nav> </div> </devsite-footer-utility> <devsite-panel></devsite-panel> </section></section> <devsite-sitemask></devsite-sitemask> <devsite-snackbar></devsite-snackbar> <devsite-tooltip ></devsite-tooltip> <devsite-heading-link></devsite-heading-link> <devsite-analytics> <script type="application/json" analytics>[]</script> <script type="application/json" tag-management>{&#34;at&#34;: &#34;True&#34;, &#34;ga4&#34;: [], &#34;ga4p&#34;: [], &#34;gtm&#34;: [{&#34;id&#34;: &#34;GTM-MZWCJPP&#34;, &#34;purpose&#34;: 0}], &#34;parameters&#34;: {&#34;internalUser&#34;: &#34;False&#34;, &#34;language&#34;: {&#34;machineTranslated&#34;: &#34;False&#34;, &#34;requested&#34;: &#34;en&#34;, &#34;served&#34;: &#34;en&#34;}, &#34;pageType&#34;: &#34;article&#34;, &#34;projectName&#34;: &#34;Articles&#34;, &#34;signedIn&#34;: &#34;False&#34;, &#34;tenant&#34;: &#34;web&#34;, &#34;recommendations&#34;: {&#34;sourcePage&#34;: &#34;&#34;, &#34;sourceType&#34;: 0, &#34;sourceRank&#34;: 0, &#34;sourceIdenticalDescriptions&#34;: 0, &#34;sourceTitleWords&#34;: 0, &#34;sourceDescriptionWords&#34;: 0, &#34;experiment&#34;: &#34;&#34;}, &#34;experiment&#34;: {&#34;ids&#34;: &#34;&#34;}}}</script> </devsite-analytics> <devsite-badger></devsite-badger> <script nonce="zOc8UrUTsVWluVZOVJd0R0mik4X3kf"> (function(d,e,v,s,i,t,E){d['GoogleDevelopersObject']=i; t=e.createElement(v);t.async=1;t.src=s;E=e.getElementsByTagName(v)[0]; E.parentNode.insertBefore(t,E);})(window, document, 'script', 'https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/js/app_loader.js', '[27,"en",null,"/js/devsite_app_module.js","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web","https://web-dot-devsite-v2-prod-3p.appspot.com",1,null,["/_pwa/web/manifest.json","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/images/video-placeholder.svg","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/favicon.png","https://www.gstatic.com/devrel-devsite/prod/v870e399c64f7c43c99a3043db4b3a74327bb93d0914e84a0c3dba90bbfd67625/web/images/lockup.svg","https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap"],1,null,[1,6,8,12,14,17,21,25,50,52,63,70,75,76,80,87,91,92,93,97,98,100,101,102,103,104,105,107,108,109,110,112,113,116,117,118,120,122,124,125,126,127,129,130,131,132,133,134,135,136,138,140,141,147,148,149,151,152,156,157,158,159,161,163,164,168,169,170,179,180,182,183,186,191,193,196],"AIzaSyCNm9YxQumEXwGJgTDjxoxXK6m1F-9720Q","AIzaSyCc76DZePGtoyUjqKrLdsMGk_ry7sljLbY","web.dev","AIzaSyB9bqgQ2t11WJsOX8qNsCQ6U-w91mmqF-I","AIzaSyAdYnStPdzjcJJtQ0mvIaeaMKj7_t6J_Fg",null,null,null,["Cloud__enable_cloud_facet_chat","MiscFeatureFlags__emergency_css","Profiles__enable_page_saving","TpcFeatures__enable_required_headers","Experiments__reqs_query_experiments","EngEduTelemetry__enable_engedu_telemetry","TpcFeatures__enable_mirror_tenant_redirects","Profiles__enable_complete_playlist_endpoint","Profiles__enable_awarding_url","DevPro__enable_cloud_innovators_plus","MiscFeatureFlags__enable_view_transitions","MiscFeatureFlags__enable_explain_this_code","Profiles__enable_dashboard_curated_recommendations","Cloud__enable_llm_concierge_chat","Search__enable_suggestions_from_borg","CloudShell__cloud_code_overflow_menu","Analytics__enable_clearcut_logging","MiscFeatureFlags__enable_variable_operator","Profiles__enable_recognition_badges","CloudShell__cloud_shell_button","DevPro__enable_developer_subscriptions","Cloud__enable_legacy_calculator_redirect","Cloud__enable_cloudx_ping","MiscFeatureFlags__developers_footer_dark_image","MiscFeatureFlags__enable_project_variables","MiscFeatureFlags__enable_firebase_utm","Search__enable_page_map","Profiles__enable_profile_collections","Profiles__enable_release_notes_notifications","Profiles__enable_public_developer_profiles","Search__enable_ai_eligibility_checks","Cloud__enable_cloud_shell","Concierge__enable_pushui","Cloud__enable_cloud_dlp_service","Profiles__require_profile_eligibility_for_signin","Profiles__enable_completecodelab_endpoint","Search__enable_dynamic_content_confidential_banner","OnSwitch__enable","Cloud__enable_cloudx_experiment_ids","BookNav__enable_tenant_cache_key","Cloud__enable_free_trial_server_call","Profiles__enable_developer_profiles_callout","MiscFeatureFlags__developers_footer_image","Cloud__enable_cloud_shell_fte_user_flow"],null,null,"AIzaSyA58TaKli1DculwmAmbpzLVGuWc8eCQgQc","https://developerscontentserving-pa.googleapis.com","AIzaSyDWBU60w0P9hEkr29kkksYs8Z7gvZ8u_wc","https://developerscontentsearch-pa.googleapis.com",2,4,null,"https://developerprofiles-pa.googleapis.com",[27,"web","web.dev","web.dev",null,"web-dot-devsite-v2-prod-3p.appspot.com",null,null,[null,null,null,null,null,null,null,null,null,null,null,[1],null,null,null,null,null,null,[1],null,null,null,null,[1,null,1],[1,1,null,1,1]],null,[38,null,null,null,null,null,"/images/lockup.svg","/images/touchicon-180.png",null,null,null,1,1,null,null,null,null,null,null,null,null,2,null,null,null,"/images/lockup-dark-theme.svg",[]],[],null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,[[],[1,1]],[[null,null,null,null,null,["GTM-MZWCJPP"],null,null,null,null,null,[["GTM-MZWCJPP",1]],1]],null,4]]') </script> <devsite-a11y-announce></devsite-a11y-announce> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10