Add SSO to login page
Login page UX strategies to implement single sign-on
Using our quickstart guide, you may already have implemented single sign-on (SSO) between your application and your customer’s identity provider. In this article, we’ll explore different UX strategies to incorporate SSO into your application’s login page. Assuming your users can log in via email and password or through social providers like Google and GitHub, you can adopt one of the following three strategies to implement SSO on your login page:

Strategy 1: Identifier-driven single sign-on
Section titled “Strategy 1: Identifier-driven single sign-on”In this strategy, you first collect the user’s identifier—the most popular identifier is the email address. Based on the email address, you determine whether to navigate the user to SSO login experience or password-based authentication. The organization can be discovered using either (i) the domain of the user’s email address or (ii) an organization identifier shared by the user.

The benefit with this approach is that users don’t have to choose the authentication method, thus reducing their cognitive load and making the experience smoother. This is especially useful when users initially log in with passwords, and their admin later mandates SSO. Users don’t need to change their behavior; your application can handle it. Popular products like Google, Microsoft, and AWS use this strategy in their login pages.
Strategy 2: Login with single sign-on button
Section titled “Strategy 2: Login with single sign-on button”In this strategy, you add a “Login with SSO” button on your login page, prompting users to choose this option explicitly. The advantage is that it presents all available authentication options, allowing users to decide how they want to log in.

If a user tries to log in with a password, but their admin mandates SSO, you would force SSO-based authentication instead of showing an error message. Popular products like Cal.com and Notion use this strategy in their login pages.
Strategy 3: Tenant specific login page
Section titled “Strategy 3: Tenant specific login page”In this strategy, instead of a single login page at https://app.b2b-app.com/login, you serve different login pages for each tenant. For example, https://customer1.b2b-app.com/login, https://customer2.b2b-app.com/login. Depending on the tenant URL, you would show only the respective authentication methods applicable to that tenant, thus optimizing the user experience further.
Popular products like Zendesk and Slack use this strategy in their login pages. However, the big drawback with this approach is that users need to remember their tenant URL to access the login page.
Initiating single sign-on from your login page
Section titled “Initiating single sign-on from your login page”Once you’ve chosen a UX strategy for your application’s login, let’s move to the login implementation of SSO through Scalekit. Regardless of the strategy you implemented, you can construct the authorization_url using Scalekit SDK and redirect the user to this URL. Refer to the code samples below:
import { Scalekit } from '@scalekit-sdk/node';// Initialize the SDK clientconst scalekit = new Scalekit('', '', '');const options = {};// Option 1: Authorization URL with the organization IDoptions['organizationId'] = 'org_15421144869927830';// Option 2: Authorization URL with login hintoptions['loginHint'] = 'user@example.com';const authorizationURL = scalekit.getAuthorizationUrl( redirect_uri, options,);// Next step is to redirect the user to this authorization URLfrom scalekit import ScalekitClient, AuthorizationUrlOptions# Initialize the SDK clientscalekit_client = ScalekitClient('', '', '')options = AuthorizationUrlOptions()# Option 1: Authorization URL with the organization IDoptions.organization_id = "org_15421144869927830"# Option 2: Authorization URL with login hintoptions.login_hint = "user@example.com"authorization_url = scalekit_client.get_authorization_url( redirect_uri=redirect_uri, options=options)# Next step is to redirect the user to this authorization_urlimport ( "github.com/scalekit-inc/scalekit-sdk-go")func main() { // Initialize the SDK client scalekitClient := scalekit.NewScalekitClient("", "", "") options := scalekit.AuthorizationUrlOptions{} // Option 1: Authorization URL with the organization ID options.OrganizationId = "org_15421144869927830" // Option 2: Authorization URL with login hint options.LoginHint = "user@example.com" authorizationURL := scalekitClient.GetAuthorizationUrl( redirectUrl, options, ) // Next step is to redirect the user to this authorizationURL}import com.scalekit.ScalekitClient;import com.scalekit.internal.http.AuthorizationUrlOptions;@PostMapping(path = "/login")public ResponseEntity<Map<String, String>> loginHandler(@RequestBody LoginRequest body) { AuthorizationUrlOptions options = new AuthorizationUrlOptions(); // Option 1: Authorization URL with the organization ID if (body.getOrganizationId() != null) { options.setOrganizationId(body.getOrganizationId()); } // Option 2: Authorization URL with login hint if (body.getEmail() != null) { options.setLoginHint(body.getEmail()); } try { String url = scalekit .authentication() .getAuthorizationUrl(redirectUrl, options) .toString(); return ResponseEntity.ok(Collections.singletonMap("url", url)); } catch (Exception e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(Collections.singletonMap("error", e.getMessage())); }}// Redirect the user to this authorization URLPre-check SSO by domain (when using discovery)
Section titled “Pre-check SSO by domain (when using discovery)”If your login form uses discovery (domain_hint or login_hint), run a lightweight check to confirm the user’s email domain maps to an active SSO connection before redirecting. This prevents dead-end redirects and helps you present the right path (SSO vs non‑SSO).
- Recommended when: You ask for email first or infer SSO from the domain.
- Skip when: You already pass
organizationIdorconnectionIdexplicitly.
How to implement:
- Ask for email and extract the domain
- Query for connections by domain
- If found → redirect with
domain_hint(orconnectionId) - If none → route to your non‑SSO flow