Social Login Authentication

Social login authentication allows users to authenticate using OAuth providers like Google, Facebook, or custom providers through Auth0. There are two authentication flows available:

  1. Redirect flow: Redirects the user to the provider’s login page and back to your application
  2. Popup flow: Opens the provider’s login page in a popup window without leaving your application

Prerequisites

Before implementing social login in your application, you need to configure your Account Kit dashboard and application:

  1. Follow the Setup Instructions in the Getting Started Guide:

    • See the Getting Started with Authentication page for complete setup instructions
    • Pay special attention to the social authentication provider configuration and whitelisted origins setup
  2. Key Configuration Requirements:

    • Enable desired social providers in your Account Kit dashboard
    • Add your application’s domain to the whitelisted origins
    • Set enablePopupOauth: true in your config if using popup flow

Implementation Options

You can implement Social Login authentication in two ways:

Pre-built UI Components

Account Kit provides pre-built UI components that handle the entire Social Login authentication flow with minimal code.

Step 1: Add Authentication Components to Your Page

Before configuring your authentication, first add one of the pre-built components to your application:

Using Modal Authentication

To add authentication in a modal popup:

import React from "react";
import { 
const useAuthModal: () => { isOpen: boolean; openAuthModal: () => void; closeAuthModal: () => void; }

A hook that returns the open and close functions for the Auth Modal if uiConfig is enabled on the Account Provider

useAuthModal
} from "@account-kit/react";
export default function
function MyPage(): JSX.Element
MyPage
() {
const {
const openAuthModal: () => void
openAuthModal
} =
function useAuthModal(): { isOpen: boolean; openAuthModal: () => void; closeAuthModal: () => void; }

A hook that returns the open and close functions for the Auth Modal if uiConfig is enabled on the Account Provider

useAuthModal
();
return <
React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
React.DOMAttributes<HTMLButtonElement>.onClick?: React.MouseEventHandler<HTMLButtonElement> | undefined
onClick
={
const openAuthModal: () => void
openAuthModal
}>Sign in</
React.JSX.IntrinsicElements.button: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
button
>;
}

For more details on modal configuration, see the Modal Authentication documentation.

Or:

Using Embedded Authentication

To embed authentication directly in your page:

import React from "react";
import { 
const AuthCard: (props: AuthCardProps) => JSX.Element

React component containing an Auth view with configured auth methods and options based on the config passed to the AlchemyAccountProvider

AuthCard
} from "@account-kit/react";
export default function
function MyLoginPage(): JSX.Element
MyLoginPage
() {
return ( <
React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
React.HTMLAttributes<HTMLDivElement>.className?: string | undefined
className
="flex flex-row p-4 bg-white border border-gray-200 rounded-lg">
<
const AuthCard: (props: AuthCardProps) => JSX.Element

React component containing an Auth view with configured auth methods and options based on the config passed to the AlchemyAccountProvider

AuthCard
/>
</
React.JSX.IntrinsicElements.div: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>
); }

For more details on embedded authentication, see the Embedded Authentication documentation.

Step 2: Configure Social Login in UI Components

After adding the components, configure the Social Login authentication in your application config:

import { 
type AlchemyAccountsUIConfig = { auth?: { addPasskeyOnSignup?: boolean; header?: React.ReactNode; hideError?: boolean; onAuthSuccess?: () => void; sections: AuthType[][]; hideSignInText?: boolean; }; illustrationStyle?: "outline" | "linear" | "filled" | "flat" | undefined; modalBaseClassName?: string; supportUrl?: string | undefined; }
AlchemyAccountsUIConfig
,
const createConfig: (props: CreateConfigProps, ui?: AlchemyAccountsUIConfig) => AlchemyAccountsConfigWithUI

Wraps the createConfig that is exported from @aa-sdk/core to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).

createConfig
} from "@account-kit/react";
import {
const sepolia: Chain
sepolia
,
function alchemy(config: AlchemyTransportConfig): AlchemyTransport

Creates an Alchemy transport with the specified configuration options. When sending all traffic to Alchemy, you must pass in one of rpcUrl, apiKey, or jwt. If you want to send Bundler and Paymaster traffic to Alchemy and Node traffic to a different RPC, you must pass in alchemyConnection and nodeRpcUrl.

alchemy
} from "@account-kit/infra";
const
const uiConfig: AlchemyAccountsUIConfig
uiConfig
:
type AlchemyAccountsUIConfig = { auth?: { addPasskeyOnSignup?: boolean; header?: React.ReactNode; hideError?: boolean; onAuthSuccess?: () => void; sections: AuthType[][]; hideSignInText?: boolean; }; illustrationStyle?: "outline" | "linear" | "filled" | "flat" | undefined; modalBaseClassName?: string; supportUrl?: string | undefined; }
AlchemyAccountsUIConfig
= {
auth?: { addPasskeyOnSignup?: boolean; header?: React.ReactNode; hideError?: boolean; onAuthSuccess?: () => void; sections: AuthType[][]; hideSignInText?: boolean; } | undefined
auth
: {
sections: AuthType[][]

Each section can contain multiple auth types which will be grouped together and separated by an OR divider

sections
: [
[ // Include social login providers {
type: "social"
type
: "social",
authProviderId: KnownAuthProvider
authProviderId
: "google",
mode: "popup"
mode
: "popup" },
{
type: "social"
type
: "social",
authProviderId: KnownAuthProvider
authProviderId
: "facebook",
mode: "popup"
mode
: "popup" },
{
type: "social"
type
: "social",
authProviderId: KnownAuthProvider
authProviderId
: "apple",
mode: "popup"
mode
: "popup" },
], ], }, }; export const
const config: AlchemyAccountsConfigWithUI
config
=
function createConfig(props: CreateConfigProps, ui?: AlchemyAccountsUIConfig): AlchemyAccountsConfigWithUI

Wraps the createConfig that is exported from @aa-sdk/core to allow passing an additional argument, the configuration object for the Auth Components UI (the modal and AuthCard).

createConfig
(
{
transport: AlchemyTransport
transport
:
function alchemy(config: AlchemyTransportConfig): AlchemyTransport

Creates an Alchemy transport with the specified configuration options. When sending all traffic to Alchemy, you must pass in one of rpcUrl, apiKey, or jwt. If you want to send Bundler and Paymaster traffic to Alchemy and Node traffic to a different RPC, you must pass in alchemyConnection and nodeRpcUrl.

alchemy
({
apiKey: string
apiKey
: "your-api-key" }),
chain: Chain
chain
:
const sepolia: Chain
sepolia
,
// Required for popup flow
enablePopupOauth: true
enablePopupOauth
: true,
},
const uiConfig: AlchemyAccountsUIConfig
uiConfig
,
);

For custom OAuth providers like GitHub, Twitter, etc., see the Custom Social Providers documentation.

Standard social login providers accept the following configuration:

type 
type SocialAuthType = { type: "social"; authProviderId: "google" | "facebook" | "apple"; mode: "popup" | "redirect"; scope?: string; claims?: string; }
SocialAuthType
= {
type: "social"
type
: "social";
// For standard providers (google, facebook, apple)
authProviderId: "google" | "facebook" | "apple"
authProviderId
: "google" | "facebook" | "apple";
// Authentication mode (popup or redirect)
mode: "popup" | "redirect"
mode
: "popup" | "redirect";
// Optional: Specifies the requested OAuth scope
scope?: string | undefined
scope
?: string;
// Optional: Specifies additional claims to be included in the authentication token
claims?: string | undefined
claims
?: string;
};

You can find the full type definition in the Account Kit source code.

For more details on UI component customization, see the UI Components documentation.

Custom UI

If you need complete control over the user experience, you can implement your own custom UI for Social Login authentication using Account Kit hooks.

Step 1: Configure Your Application

Before implementing social login, make sure you’ve:

  1. Set up your authentication providers in the Account Kit dashboard
  2. If using popup flow, set enablePopupOauth: true in your Account Kit configuration

Step 2: Implement the Authentication

Create buttons or UI elements for each social provider you want to support:

import { 
function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResult

Hook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.

This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.

useAuthenticate
} from "@account-kit/react";
// Inside your component const {
const authenticate: UseMutateFunction<User, Error, AuthParams, unknown>
authenticate
,
const isPending: boolean
isPending
} =
function useAuthenticate(mutationArgs?: UseAuthenticateMutationArgs): UseAuthenticateResult

Hook that provides functions and state for authenticating a user using a signer. It includes methods for both synchronous and asynchronous mutations. Useful if building your own UI components and want to control the authentication flow. For authenticate vs authenticateAsync, use authenticate when you want the hook the handle state changes for you, authenticateAsync when you need to wait for the result to finish processing.

This can be complex for magic link or OTP flows: OPT calls authenticate twice, but this should be handled by the signer.

useAuthenticate
();
// For redirect flow const
const handleGoogleRedirectLogin: () => void
handleGoogleRedirectLogin
= () => {
const authenticate: (variables: AuthParams, options?: MutateOptions<User, Error, AuthParams, unknown> | undefined) => void
authenticate
(
{
type: "oauth"
type
: "oauth",
authProviderId: "google"
authProviderId
: "google",
mode: "redirect"
mode
: "redirect",
redirectUrl: string
redirectUrl
: "/", // Redirect to this page after authentication
}, {
MutateOptions<User, Error, AuthParams, unknown>.onError?: ((error: Error, variables: AuthParams, context: unknown) => void) | undefined
onError
: (
error: Error
error
) => {
// Handle error // The page will redirect on success, so no need for onSuccess handler }, }, ); }; // For popup flow const
const handleGooglePopupLogin: () => void
handleGooglePopupLogin
= () => {
const authenticate: (variables: AuthParams, options?: MutateOptions<User, Error, AuthParams, unknown> | undefined) => void
authenticate
(
{
type: "oauth"
type
: "oauth",
authProviderId: "google"
authProviderId
: "google",
mode: "popup"
mode
: "popup",
}, {
MutateOptions<User, Error, AuthParams, unknown>.onSuccess?: ((data: User, variables: AuthParams, context: unknown) => void) | undefined
onSuccess
: () => {
// Authentication successful! },
MutateOptions<User, Error, AuthParams, unknown>.onError?: ((error: Error, variables: AuthParams, context: unknown) => void) | undefined
onError
: (
error: Error
error
) => {
// Handle error }, }, ); };

Step 3: Track Authentication Status

Use the useSignerStatus hook to determine if the user is authenticated:

import { 
const useSignerStatus: (override?: AlchemyAccountContextProps) => UseSignerStatusResult

Hook to get the signer status, optionally using an override configuration, useful if you’re building your own login.

useSignerStatus
} from "@account-kit/react";
// Inside your component const {
const isConnected: boolean
isConnected
} =
function useSignerStatus(override?: AlchemyAccountContextProps): UseSignerStatusResult

Hook to get the signer status, optionally using an override configuration, useful if you’re building your own login.

useSignerStatus
();
// You can use isConnected to conditionally render UI

Step 4: Handle Redirect (for redirect flow)

If you’re using the redirect flow, you need to handle the redirect when the user returns to your application:

import { 
function useEffect(effect: React.EffectCallback, deps?: React.DependencyList): void

Accepts a function that contains imperative, possibly effectful code.

useEffect
} from "react";
import {
const useSignerStatus: (override?: AlchemyAccountContextProps) => UseSignerStatusResult

Hook to get the signer status, optionally using an override configuration, useful if you’re building your own login.

useSignerStatus
} from "@account-kit/react";
// Inside your component const {
const isAuthenticating: boolean
isAuthenticating
} =
function useSignerStatus(override?: AlchemyAccountContextProps): UseSignerStatusResult

Hook to get the signer status, optionally using an override configuration, useful if you’re building your own login.

useSignerStatus
();
// Show loading state during authentication
function useEffect(effect: React.EffectCallback, deps?: React.DependencyList): void

Accepts a function that contains imperative, possibly effectful code.

useEffect
(() => {
if (
const isAuthenticating: boolean
isAuthenticating
) {
// Show loading UI while authentication completes } }, [
const isAuthenticating: boolean
isAuthenticating
]);

Next Steps

Enabling Authenticator App (TOTP) MFA

If you want to require a second factor for Social Login, see Social Login with Multi-Factor Authentication. Once users have set up a TOTP-based authenticator app, they’ll be prompted for their 6-digit code automatically.