{"id":2394,"date":"2025-08-05T09:45:38","date_gmt":"2025-08-05T16:45:38","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/identity\/?p=2394"},"modified":"2026-03-09T07:51:57","modified_gmt":"2026-03-09T14:51:57","slug":"native-auth-javascript-sdk-ga","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/identity\/native-auth-javascript-sdk-ga\/","title":{"rendered":"General Availability of Native Authentication JavaScript SDK"},"content":{"rendered":"<p>Today we announce that Native Authentication\u202fJavaScript SDK for Microsoft Entra External ID is now Generally Available! Initially <a href=\"https:\/\/devblogs.microsoft.com\/identity\/native-auth-for-external-id-ga\/\" target=\"_blank\">released in 2024<\/a>, Native Authentication empowers developers to build\u202fsign-in, sign-up and sign-out experiences for single page applications (SPAs) in Entra External ID.<\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/quickstart-native-authentication-single-page-app-sdk-sign-in?tabs=react\" target=\"_blank\">Get Started with Native Authentication JavaScript SDK<\/a><\/div><\/p>\n<h2>How to use native authentication JavaScript SDK<\/h2>\n<p>You can add native authentication to your single page applications (SPAs) by using the <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/quickstart-native-authentication-single-page-app-sdk-sign-in?tabs=react\" target=\"_blank\">Microsoft Authentication Library (MSAL) for JavaScript<\/a> with the native authentication extensions. Whenever possible, use MSAL to integrate native authentication for SPA experiences. If you\u2019re targeting platforms not supported by MSAL, use the underlying <a href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/reference-native-authentication-api?tabs=emailOtp\" target=\"_blank\">authentication APIs<\/a> directly.<\/p>\n<h3>Install MSAL SDK and Import Native Authentication Extension<\/h3>\n<pre lang=\"php\"><code>npm i @azure\/msal-browser<\/code><\/pre>\n<p>MSAL abstracts the protocol and exposes simple, scenario-based APIs. For example, to sign a user in using an email one-time passcode (OTP) flow, your app starts the sign-in with the user\u2019s email. MSAL drives the next step by returning a state indicating that a code is required; you then collect the OTP and submit it to complete sign-in.<\/p>\n<p>Below is a JavaScript\/TypeScript example that signs a user in using the email OTP flow. The signIn method returns a result that contains a state object. That state can represent different steps (for example, \u201ccode required\u201d, \u201cpassword required\u201d, \u201ccomplete\u201d, or \u201cfailed\u201d). Your code inspects the state and proceeds accordingly.<\/p>\n<h3>Sign In with Email One-Time Passcode (OTP)<\/h3>\n<pre lang=\"JavaScript\"><code>import { \n CustomAuthPublicClientApplication, \n SignInCompletedState, \n SignInCodeRequiredState, \n SignInPasswordRequiredState, \n AuthFlowStateBase, \n ICustomAuthPublicClientApplication, \n} from \"@azure\/msal-browser\/custom-auth\"; \n\/\/ Create the client \nconst authClient: ICustomAuthPublicClientApplication = \nawait CustomAuthPublicClientApplication.create(customAuthConfig); \n\/\/ Start sign-in with the user's email (username) \nconst actionResult = await authClient.signIn({ username: emailAddress }); \n\/\/ Inspect the result state and proceed \nif (actionResult.isCodeRequired()) { \n\/\/ Next step: prompt user for the OTP code (e.g., via a form) \n const submitCodeResult = await actionResult.state.submitCode(code); \n if (submitCodeResult.isCompleted()) { \n\/\/ Handle sign-in success \n const accountData = submitCodeResult.data; \/\/ CustomAuthAccountData \n  } \n}<\/code>  <\/pre>\n<h3>Handling Common Error Scenarios<\/h3>\n<p>Map well-known errors to user-friendly messages and remediation steps:<\/p>\n<pre lang=\"JavaScript\"><code>const result = await authClient.signIn({ username: emailAddress }); \nif (result.isFailed()) { \n  const err = result.error; \n  if (err?.isUserNotFound()) { \n    \/\/ User not found \n  } else if (err?.isInvalidUsername()) { \n    \/\/ Invalid email\/username \n  } else if (err?.isInvalidCode()) { \n    \/\/ Code incorrect (if code was required earlier) \n  } else if (err?.isRedirectRequired()) { \n    \/\/ Fallback to delegated (web-based) sign-in when native cannot proceed \n  } else { \n    \/\/ Generic error \n    \/\/ err?.errorData?.errorDescription \n  } \n}<\/code> <\/pre>\n<p>Ready to get started?<\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/tutorial-native-authentication-single-page-app-react-sdk-sign-in\" target=\"_blank\">Get Started with Code Samples in React<\/a><\/div><\/p>\n<p><div  class=\"d-flex justify-content-center\"><a class=\"cta_button_link btn-primary mb-24\" href=\"https:\/\/learn.microsoft.com\/en-us\/entra\/identity-platform\/tutorial-native-authentication-single-page-app-angular-sign-in\" target=\"_blank\">Get Started with Code Samples in AngularJS<\/a><\/div><\/p>\n<h2>Stay connected and informed<\/h2>\n<p>To learn more or test out features in the Microsoft Entra suite of products, visit our\u202f<a href=\"https:\/\/developer.microsoft.com\/en-us\/identity\/\">developer center<\/a>. Make sure you subscribe to the\u202f<a href=\"https:\/\/devblogs.microsoft.com\/identity\/\">Identity blog<\/a>\u202ffor more insights and to keep up with the latest on all things Identity. And, follow us on <a href=\"https:\/\/www.youtube.com\/@MicrosoftSecurity\/playlists\">YouTube<\/a> for video overviews, tutorials, and deep dives.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today we announce that Native Authentication\u202fJavaScript SDK for Microsoft Entra External ID is now Generally Available! Initially released in 2024, Native Authentication empowers developers to build\u202fsign-in, sign-up and sign-out experiences for single page applications (SPAs) in Entra External ID. How to use native authentication JavaScript SDK You can add native authentication to your single page [&hellip;]<\/p>\n","protected":false},"author":135210,"featured_media":2426,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[32,33],"tags":[38,17,54,20,16,67,50,39,4],"class_list":["post-2394","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","category-product-updates","tag-authentication","tag-customer-identity","tag-developer-experience","tag-devex","tag-entra","tag-entra-external-id","tag-identity","tag-native-authentication","tag-security"],"acf":[],"blog_post_summary":"<p>Today we announce that Native Authentication\u202fJavaScript SDK for Microsoft Entra External ID is now Generally Available! Initially released in 2024, Native Authentication empowers developers to build\u202fsign-in, sign-up and sign-out experiences for single page applications (SPAs) in Entra External ID. How to use native authentication JavaScript SDK You can add native authentication to your single page [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/posts\/2394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/users\/135210"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/comments?post=2394"}],"version-history":[{"count":2,"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/posts\/2394\/revisions"}],"predecessor-version":[{"id":2437,"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/posts\/2394\/revisions\/2437"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/media\/2426"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/media?parent=2394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/categories?post=2394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/identity\/wp-json\/wp\/v2\/tags?post=2394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}