Summary
A hook which can be used to trigger sign-in with social or social account linking and unlinking for an authenticated user.
The hook needs to be initialized within a child of DynamicContextProvider.
Usage
The hook can receive an optional sessionTimeout
param that is used to cancel sign-in/linking due to inactivity. It’s value should be a number (time in milliseconds) and defaults to 10s (10000 ms).
Note: This is mainly used for X/Twitter oauth, since we cannot detect when the oauth window is closed for this provider.
Example setting timeout to 20s:
const {
signInWithSocialAccount,
isProcessing,
error,
} = useSocialAccounts({sessionTimeout: 20000});
Available functions and states:
Method | Type | Description |
---|
error | SocialOAuthError | undefined | Contains the code and message in case of an error during the link or unlink process |
getLinkedAccountInformation | (provider: ProviderEnum) => SocialAccountInformation | Returns an object with the information about the linked account for the specified provider if there’s a linked account. If not, returns undefined. |
isLinked | (provider: ProviderEnum) => boolean | Returns true if user has an account linked for the specified provider. Otherwise returns false. |
isProcessing | boolean | Indicates whether a link or unlink request is in process |
linkSocialAccount | (provider: ProviderEnum) => Promise<void> | When called, will trigger the oauth linking for the specified provider |
signInWithSocialAccount | (provider: ProviderEnum) => Promise<void> | When called, will trigger the oauth sign-in for the specified provider |
unlinkSocialAccount | (provider: ProviderEnum) => Promise<void> | When called, it will unlink the user account for the specified provider |
Types
ProviderEnum =
"discord" |
"facebook" |
"farcaster" |
"github" |
"google" |
"instagram" |
"twitch" |
"twitter";
SocialAccountInformation = {
id: string;
provider: ProviderEnum;
accountId: string;
publicIdentifier: string;
avatar?: string;
displayName?: string;
email?: string;
username?: string;
};
SocialOAuthErrorCode =
"account_already_linked" |
"account_already_linked_to_different_profile" |
"invalid_provider" |
"no_account_linked" |
"no_auth_code" |
"no_oauth_url" |
"no_provider" |
"oauth_error" |
"oauth_window_timeout" |
"provider_not_enabled" |
"session_timeout" |
"signin_error" |
"social_linking_not_enabled" |
"unlink_error" |
"verification_error" |
"general_error";
Linking/unlinking example
import {
useSocialAccounts,
} from '@dynamic-labs/sdk-react-core';
import { ProviderEnum } from '@dynamic-labs/types';
import { GoogleIcon } from '@dynamic-labs/iconic';
const UserProfileSocialAccount = () => {
const {
linkSocialAccount,
unlinkSocialAccount,
isProcessing,
isLinked,
getLinkedAccountInformation,
} = useSocialAccounts();
const provider = ProviderEnum.Google;
const isGoogleLinked = isLinked(provider);
const connectedAccountInfo = getLinkedAccountInformation(provider);
return (
<div>
<div className="icon">
{isGoogleLinked ? (
<Avatar avatarUrl={connectedAccountInfo?.avatar} />
) : (
<GoogleIcon />
)}
</div>
<div className="label">
<Typography>
{connectedAccountInfo?.publicIdentifier ?? provider}
</Typography>
</div>
{isGoogleLinked ? (
<Button
onClick={() => unlinkSocialAccount(provider)}
loading={isProcessing}
>
Disconnect
</Button>
) : (
<Button
onClick={() => linkSocialAccount(provider)}
loading={isProcessing}
>
Connect
</Button>
)}
</div>
);
};
Sign-in example
import { FC } from 'react';
import {
DynamicWidget,
useDynamicContext,
useSocialAccounts,
} from '@dynamic-labs/sdk-react-core';
import { ProviderEnum } from '@dynamic-labs/types';
import { FarcasterIcon, GoogleIcon, TwitterIcon } from '@dynamic-labs/iconic';
const SocialSignIn = () => {
const { error, isProcessing, signInWithSocialAccount } = useSocialAccounts();
return (
<div className='headless-social-signin'>
<div className='headless-social-signin__container'>
<p>Log in or sign up</p>
<button onClick={() => signInWithSocialAccount(ProviderEnum.Farcaster)}>
<FarcasterIcon />
Sign in with Farcaster
</button>
<button onClick={() => signInWithSocialAccount(ProviderEnum.Google)}>
<GoogleIcon />
Sign in with Google
</button>
<button onClick={() => signInWithSocialAccount(ProviderEnum.Twitter)}>
<TwitterIcon />
Sign in with Twitter
</button>
{isProcessing && <span className='processing'>Processing...</span>}
{error && <span className='error'>{error.message}</span>}
</div>
</div>
);
};
const LoggedInUser = () => {
const { user } = useDynamicContext();
return (
<>
<DynamicWidget />
<p>user: {user?.email}</p>
</>
);
};
export const HeadlessSocialSignInView: FC = () => {
const { user } = useDynamicContext();
return (
<div style={{ overflowY: 'scroll' }}>
{user ? <LoggedInUser /> : <SocialSignIn />}
</div>
);
};