Handle Members with a Custom Login Page Using the JS SDK

This article explains how to implement a custom login page using the JavaScript SDK.

You'll learn how to:

  • Set up a Wix client for authentication.
  • Check if a visitor is already logged in.
  • Sign up and log in members.
  • Exchange session tokens for access and refresh tokens.
  • Use a full-page redirect for mobile-compatible authentication.
  • Handle failed authentication states.
  • Refresh access tokens.
  • Log out members.

Step 1 | Set up a Wix client

To authenticate and interact with Wix APIs, create a Wix client in your code. Install and import the Members API to create and manage a site's members. You can also import other APIs as needed and pass to your client.

Copy

Replace <YOUR_CLIENT_ID> with your OAuth app's Client ID from your Headless Settings.

Step 2 | Check if the visitor is already logged in

Before showing a login form, check if the current visitor is already logged in:

Copy

If logged in, you can immediately make authenticated API calls. Otherwise, send them to your sign-up or login form.

Step 3 | Sign up and log in members

Create custom forms in your app with fields for email and password. You can design these forms to match your branding exactly. Your page should be able to:

  • Sign up a new member
  • Log in an existing member

Tip: You can add reCAPTCHA protection to your custom login flows to help prevent fraud and abuse. Make sure to also enable reCAPTCHA in your project settings.

Sign up a new member

To sign up a new member, use the register() method with the email and password provided by the visitor:

Copy

Collecting additional profile details at sign-up, such as a name, nickname, or your own custom fields, is one of the main reasons to build a custom login page instead of using a Wix login page. To do this, pass an optional profile object with any of the fields your form collects:

Copy

Note: Standard profile fields such as firstName, lastName, and nickname work as-is. Arbitrary keys in customFields must first be defined using the Members Custom Fields API, which requires the Wix Members Area app to be installed. An undefined custom field is silently dropped.

If response.loginState is SUCCESS, exchange the session token for access and refresh tokens. Otherwise, handle failed authentication states.

Log in an existing member

To log in an existing member, use the login() method with the email and password provided by the visitor:

Copy

If response.loginState is SUCCESS, exchange the session token for access and refresh tokens. Otherwise, handle failed authentication states.

Step 4 | Exchange the session token for access and refresh tokens

When authentication is successful, you need to exchange the session token for access and refresh tokens. This process is the same whether you're signing up a new member or logging in an existing member.

Choose one of the following approaches to exchange the session token:

Use the SDK (desktop browsers only)

Call getMemberTokensForDirectLogin() and set the returned member tokens on your client:

Copy

Tip: After setting tokens, you can use myWixClient.members.getCurrentMember() to fetch the member's info.

Use a full-page redirect (desktop and mobile browsers)

This approach uses a full-page redirect to complete the PKCE OAuth exchange instead of a hidden iframe. This avoids 3rd-party cookie restrictions that cause getMemberTokensForDirectLogin() to fail on mobile browsers.

Note: The redirectUri you use in this flow must be an allowed authorization redirect URI and must match exactly, including any trailing slash.

To use a full-page redirect:

  1. After a successful login or register call, retrieve the sessionToken from response.data.sessionToken. You'll specify this token when calling Create Redirect Session to establish the member's identity.

  2. Generate PKCE data:

    • A random code verifier.
    • A SHA-256 code challenge derived from the verifier.
    • A random state value.

    Store the code verifier and state so you can retrieve them after the redirect.

    For example:

    Copy
  3. Call Create Redirect Session, specifying the sessionToken and the PKCE challenge data in auth.authRequest. Specify the visitor access token as the authorization header.

    Copy
  4. Redirect the browser to the fullUrl returned in the response. This navigates the user to the Wix authorization page instead of using a hidden iframe.

    Copy
  5. When the authorization flow completes, the browser redirects back to your redirectUri with code and state query parameters. On page load, retrieve these values and verify that state matches what you stored to protect against CSRF attacks.

    For example:

    Copy
  6. Exchange the authorization code for member tokens by calling Create Access Token, specifying the code, stored codeVerifier, and redirectUri.

    Copy
  7. Convert the token response to the SDK token format and reinitialize the Wix client with the member tokens.

    Copy

Step 5 | Handle failed authentication states

When a sign-up or login attempt fails, the login() and register() methods return an object with a loginState property. Your code should handle each possible state to provide a smooth user experience. The possible values include:

  • SUCCESS: Authentication was successful.
  • FAILURE: Authentication unsuccessful due to one of the following reasons, as indicated by the errorCode:
    • invalidEmail: The email address provided is invalid. Your code should present an error.
    • invalidPassword: The password provided is invalid. Your code should present an error.
    • emailAlreadyExists: The visitor attempted to sign up as a new member using an email address belonging to an existing member. Your code should present an error.
    • resetPassword: The member needs to reset their password. Your code needs to send a password reset email.
  • EMAIL_VERIFICATION_REQUIRED: Authentication requires email verification. Your code needs to process email verification.
  • OWNER_APPROVAL_REQUIRED: The site owner needs to approve registration for the new member. Your code should present a notice to inform the visitor that their membership is pending. Once their membership is approved, the member can log in.

Send a password reset email

Call the sendPasswordResetEmail() method to send a password reset email to a member. The method takes the member's email address and a URL to send the member to after they successfully change their password.

Copy

The redirectUri must be an allowed authorization redirect URI. When the member clicks the reset link in their email, they're taken to a Wix-managed password reset page. After successfully setting a new password, Wix redirects them to your specified URL.

For example, the following code sends a password reset email to john_doe@email.com, and once the member resets their password on the Wix-hosted page, Wix redirects the member back to your page at http://www.my-site.com/password_changed.

Copy

Process email verification

If the loginState is EMAIL_VERIFICATION_REQUIRED, Wix sends an email with a verification code to the member. You need to create a form or prompt to collect this verification code from the member, and then use the processVerification() method to complete the verification:

Copy

If response.loginState is SUCCESS, exchange the session token for access and refresh tokens.

Step 6 | Refresh access tokens

Access tokens expire after a short time for security reasons. When this happens, you can use a refresh token to request a new access token without asking the member to log in again.

Your API layer should handle this automatically. Set up your logic to detect when an access token has expired, use the refresh token to get a new one, and then retry the original request.

Copy

Tip: Don't expose refresh tokens to the browser unnecessarily. For best security, handle token refresh on the server when possible.

Logging out a member

To log a member out:

  1. Get the logout URL from your Wix client:

    Copy
  2. Redirect the member to the logout URL:

    Copy

This logs the member out and redirects them back to your app.

Troubleshooting

If you encounter issues with custom login, make sure that:

  • You're using the correct client ID from your Headless Settings.
  • The redirectUri parameter in sendPasswordResetEmail() matches one of your allowed authorization redirect URIs.
  • If you're having token-related errors during testing, clear browser cookies and try again.
  • You're using a single shared client instance throughout your app (not creating new instances in components).
  • If createRedirectSession() fails with FAILED_TO_EXTRACT_SESSION, no member session was established. This commonly happens when getMemberTokensForDirectLogin() hangs on mobile browsers that block 3rd-party cookies. For mobile-compatible authentication, use a full-page redirect.

Last updated: 14 July 2026

Did this help?