Synq Docs
SDK reference

@synqauth/react

React hooks and components for Synq.

@synqauth/react

AccountManager

Component. Manage the signed-in person's account. Nothing while nobody is signed in.

function AccountManager({ unstyled, className, sections, }: AccountManagerProps): ReactNode

AccountManagerProps

Interface. What AccountManager takes: which sections it shows, and its look.

interface AccountManagerProps extends SynqStyleProps {
    readonly sections?: readonly AccountSection[];
}

AccountSection

Type. One part of AccountManager: the profile, the ways to sign in, the sessions, or the API keys.

type AccountSection = 'profile' | 'accounts' | 'sessions' | 'apiKeys';

AccountSession

Type. One of the person's sessions at the brand, on some device.

type AccountSession = AccountComponents['schemas']['Session'];

ApiKey

Type. One of the person's API keys for the brand's APIs: never the key itself.

type ApiKey = AccountComponents['schemas']['UserApiKey'];

ApiKeyInput

Type. What making an API key takes: the API's identifier, a name, its scopes, an expiry if any.

type ApiKeyInput = AccountComponents['schemas']['UserApiKeyCreate'];

DEFAULT_MESSAGES

Constant. The components' English words, which an app's own messages override one by one.

const DEFAULT_MESSAGES: SynqMessages

EmailCodeForm

Component. An emailed code: the address to send it to, then the code it held.

function EmailCodeForm({ signIn, autofill, unstyled, className, }: SignInPartProps & { readonly autofill?: boolean | undefined; }): ReactNode

KeyableApi

Type. One of the brand's APIs the person may make keys for, with the scopes it defines.

type KeyableApi = AccountComponents['schemas']['KeyableApi'];

LinkedAccount

Type. A way the person signs in: their email address, a wallet, a Google account...

type LinkedAccount = AccountComponents['schemas']['Identity'];

NewApiKey

Type. A key just made: key is the key itself, in this answer only.

type NewApiKey = AccountComponents['schemas']['NewUserApiKey'];

OneTimeCodeInput

Component. The field for an emailed code, named code: digits, filled from the message where the device can.

function OneTimeCodeInput({ label, unstyled, className, ...input }: OneTimeCodeInputProps): ReactNode

OneTimeCodeInputProps

Interface. What OneTimeCodeInput takes: its label, its look, and any input attribute.

interface OneTimeCodeInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'className'>, SynqStyleProps {
    readonly label: ReactNode;
}

PasskeyButton

Component. The button for a passkey: the brand's, or with related its own host's on its custom domain.

function PasskeyButton({ signIn, related, children, unstyled, className, }: SignInPartProps & { readonly related?: boolean | undefined; readonly children?: ReactNode; }): ReactNode

PasswordForm

Component. An email address and a password: signs in, or with screen="sign-up" makes an account. With emailCode, it offers a code by email for the same address too.

function PasswordForm({ signIn, screen, emailCode, autofill, unstyled, className, }: SignInPartProps & { readonly screen?: "sign-in" | "sign-up" | undefined; readonly emailCode?: boolean | undefined; readonly autofill?: boolean | undefined; }): ReactNode

Profile

Type. The person's profile at the brand.

type Profile = AccountComponents['schemas']['Profile'];

ProfileUpdate

Type. Changes to it: only the fields given change, and null clears one.

type ProfileUpdate = AccountComponents['schemas']['ProfileUpdate'];

SessionStatus

Type. error when the app couldn't be asked who is signed in, and nothing is known yet: the provider asks again, waiting longer each time.

type SessionStatus = 'loading' | 'signed-in' | 'signed-out' | 'error';

SignedIn

Component. Shows its children only while someone is signed in. It renders no element of its own.

function SignedIn({ children }: { readonly children?: ReactNode; }): ReactNode

SignedOut

Component. Shows its children only once the app has said nobody is signed in. It renders no element of its own.

function SignedOut({ children }: { readonly children?: ReactNode; }): ReactNode

SignInButton

Component. A button that sends the browser to sign in, through the app's route mount.

function SignInButton({ unstyled, className, children, ...options }: SignInButtonProps): ReactNode

SignInButtonProps

Interface. What SignInButton takes: the sign-in's options, its look and its words.

interface SignInButtonProps extends SignInOptions, SynqStyleProps {
    readonly children?: ReactNode;
}

SignInForm

Component. Sign-in on the app's own page: a passkey where the browser takes the issuer's, then an emailed code or a password, and the code or the new address's proof after. Whatever only the hosted page can do, it goes there for.

function SignInForm({ methods, screen: initialScreen, returnTo, onSignedIn, unstyled, className, }: SignInFormProps): ReactNode

SignInFormProps

Interface. What SignInForm takes: which ways to offer, where it starts, and its look.

interface SignInFormProps extends UseSignInOptions, SynqStyleProps {
    readonly methods?: readonly ChallengeMethod[];
    readonly screen?: 'sign-in' | 'sign-up';
}

SignInHandover

Interface. What only the hosted page can do for this sign-in, and what to take there.

interface SignInHandover {
    readonly reason: RedirectReason;
    readonly method?: ChallengeMethod;
    readonly loginHint?: string;
}

SignInMethod

Type. One of the brand's sign-in methods.

type SignInMethod = Extract<keyof SignInMethods, string>;

SignInMethods

Interface. The ways a brand signs people in, as synq_method names them: the hosted page goes straight to one. A brand's own connection joins them the same way:

``ts declare module '@synqauth/react' { interface SignInMethods { okta: true } } ``

interface SignInMethods {
    readonly password: true;
    readonly email: true;
    readonly passkey: true;
    readonly wallet: true;
    readonly google: true;
    readonly github: true;
    readonly microsoft: true;
    readonly discord: true;
}

SignInOptions

Interface. How to send the person to sign in.

interface SignInOptions {
    readonly returnTo?: string;
    readonly method?: SignInMethod;
    readonly loginHint?: string;
    readonly prompt?: 'login' | 'none' | 'consent' | 'select_account' | 'create';
    readonly maxAge?: number;
    readonly intent?: 'add-passkey';
}

SignInPartProps

Interface. What each part of the form takes: the sign-in it works on, and its look.

interface SignInPartProps extends SynqStyleProps {
    readonly signIn: UseSignIn;
}

SignInProblem

Interface. What went wrong with the last step: branch on code, never on the English.

interface SignInProblem {
    readonly code: ChallengeProblem | 'expired' | 'refused' | 'passkey_cancelled' | 'unavailable';
    readonly reason?: DeniedReason;
    readonly message: string;
    readonly retryAfter?: number;
}

SignInStep

Type. Where a sign-in is: what the form shows.

type SignInStep = 'start' | 'code' | 'verify-email' | 'done';

SynqClientPlugin

Interface. A browser plugin: actions over its server plugin's routes. The same shape as @synqauth/nextjs/client's defineSynqClientPlugin, so its plugins work here as they are.

interface SynqClientPlugin<Id extends string = string, Actions = unknown> {
    readonly id: Id;
    actions(request: SynqMountRequest): Actions;
}

SynqMessages

Interface. Every word the components show, for <SynqProvider messages>; any left out stay English.

interface SynqMessages {
    readonly signIn: string;
    readonly signOut: string;
    readonly manageAccount: string;
    readonly account: string;
    readonly loading: string;
    readonly save: string;
    readonly saving: string;
    readonly saved: string;
    readonly cancel: string;
    readonly profile: string;
    readonly name: string;
    readonly username: string;
    readonly waysToSignIn: string;
    readonly remove: string;
    readonly removeAccount: (provider: string, subject: string) => string;
    readonly providers: Readonly<Record<string, string>>;
    readonly devices: string;
    readonly signedIn: string;
    readonly thisDevice: string;
    readonly signOutDevice: (when: string) => string;
    readonly apps: (count: number) => string;
    readonly wallets: string;
    readonly noWallets: string;
    readonly primary: string;
    readonly rename: string;
    readonly renameWallet: (name: string) => string;
    readonly makePrimary: string;
    readonly makeWalletPrimary: (name: string) => string;
    readonly walletName: (address: string) => string;
    readonly apiKeys: string;
    readonly noApiKeys: string;
    readonly newApiKey: string;
    readonly api: string;
    readonly keyScopes: string;
    readonly expires: string;
    readonly never: string;
    readonly inDays: (days: number) => string;
    readonly makeKey: string;
    readonly makingKey: string;
    readonly revoke: string;
    readonly revokeKey: (name: string) => string;
    readonly revoked: string;
    readonly expired: string;
    readonly lastUsed: (when: string) => string;
    readonly neverUsed: string;
    readonly expiresOn: (when: string) => string;
    readonly copyKeyNow: string;
    readonly copy: string;
    readonly copied: string;
    readonly done: string;
    readonly keyNeedsFreshSignIn: string;
    readonly signInAgain: string;
    readonly email: string;
    readonly password: string;
    readonly signInWithPasskey: string;
    readonly passkeyFor: (domain: string) => string;
    readonly emailMeACode: string;
    readonly or: string;
    readonly code: string;
    readonly codeSentTo: (email: string) => string;
    readonly verifyYourEmail: (email: string) => string;
    readonly verify: string;
    readonly sendAnotherCode: string;
    readonly useAnotherWay: string;
    readonly skipForNow: string;
    readonly forgotPassword: string;
    readonly createAccount: string;
    readonly newHere: string;
    readonly haveAnAccount: string;
    readonly continuingToSignIn: string;
    readonly tryAgainIn: (seconds: number) => string;
    readonly signInProblems: Readonly<Partial<Record<SignInProblem['code'], string>>>;
    readonly signInRefusals: Readonly<Partial<Record<DeniedReason, string>>>;
}

SynqMountRequest

Type. Calls the app's route mount: request('session'), request('account/v1/profile', { method: 'PATCH',... }).

type SynqMountRequest = (path: string, init?: RequestInit) => Promise<Response>;

SynqProvider

Component. Synq for the components under it. Its route mount and fetch are read once, when it mounts.

function SynqProvider({ initialSession, basePath, plugins, fetch: fetcher, navigate, messages, children, }: SynqProviderProps): ReactNode

SynqProviderProps

Interface. What SynqProvider takes: the server's session, the route mount, the words and the plugins.

interface SynqProviderProps {
    readonly initialSession?: SynqSessionInfo | null;
    readonly basePath?: string;
    readonly plugins?: readonly SynqClientPlugin[];
    readonly fetch?: typeof fetch;
    readonly navigate?: (url: string) => void;
    readonly messages?: Partial<SynqMessages>;
    readonly children?: ReactNode;
}

SynqResult

Type. A call's outcome: its data, or the SynqError it failed with (branch on error.code).

type SynqResult<T> = {
    readonly data: T;
    readonly error: null;
} | {
    readonly data: null;
    readonly error: SynqError;
};

SynqSessionInfo

Interface. Who is signed in, as the app's server tells the browser: await synq.getSession(), or the route mount's session.

interface SynqSessionInfo {
    readonly user: SynqUser | null;
    readonly expiresAt: number | null;
}

SynqStyleProps

Interface. What every component takes for its look: Synq's classes, or unstyled.

interface SynqStyleProps {
    readonly unstyled?: boolean;
    readonly className?: string;
}

SynqUser

Interface. A signed-in person, from the ID token Synq issued at sign-in.

interface SynqUser {
    readonly sub: string;
    readonly email?: string;
    readonly email_verified?: boolean;
    readonly name?: string;
    readonly preferred_username?: string;
    readonly picture?: string;
    readonly auth_time?: number;
    readonly amr?: readonly string[];
    readonly [claim: string]: unknown;
}

UseAccountData

Interface. What the account hooks (useWallets, useLinkedAccounts, useAccountSessions) answer: the data, the error, and whether it loaded.

interface UseAccountData<T> {
    readonly data: T | null;
    readonly error: SynqError | null;
    readonly isLoading: boolean;
    readonly reload: () => Promise<void>;
}

useAccountSessions

Function. The person's sessions at the brand, on every device.

function useAccountSessions(): UseAccountData<readonly { readonly amr: readonly string[]; readonly apps: readonly string[]; readonly current: boolean; readonly expires_at: string | null; readonly id: string; readonly signed_in_at: string | null; readonly via: "hosted" | "app"; }[]>

useApiKeys

Function. The person's API keys for the brand's APIs, revoked and expired ones too.

function useApiKeys(): UseAccountData<readonly { readonly api: { readonly identifier: string; readonly name: string; }; readonly created_at: string; readonly expires_at: string | null; readonly id: string; readonly last_used_at: string | null; readonly name: string; readonly prefix: string; readonly revoked_at: string | null; readonly scopes: readonly string[]; }[]>

useAuth

Function. Everything the signed-in person can do.

function useAuth(): UseAuth

UseAuth

Interface. What useAuth() answers: signIn, signOut, link, and the account's wallets, ways to sign in and sessions.

interface UseAuth {
    readonly isLoaded: boolean;
    readonly isSignedIn: boolean;
    readonly userId: string | null;
    readonly signIn: (options?: SignInOptions) => void;
    readonly signInUrl: (options?: SignInOptions) => string;
    readonly signOut: () => Promise<SynqResult<null>>;
    readonly link: (method: SignInMethod, options?: {
        returnTo?: string;
    }) => Promise<SynqResult<null>>;
    readonly wallets: {
        readonly list: () => Promise<SynqResult<readonly Wallet[]>>;
        readonly rename: (id: string, label: string | null) => Promise<SynqResult<Wallet>>;
        readonly setPrimary: (id: string) => Promise<SynqResult<Wallet>>;
    };
    readonly accounts: {
        readonly list: () => Promise<SynqResult<readonly LinkedAccount[]>>;
        readonly unlink: (id: string) => Promise<SynqResult<null>>;
    };
    readonly sessions: {
        readonly list: () => Promise<SynqResult<readonly AccountSession[]>>;
        readonly end: (id: string) => Promise<SynqResult<null>>;
    };
    readonly apiKeys: {
        readonly list: () => Promise<SynqResult<readonly ApiKey[]>>;
        readonly create: (input: ApiKeyInput) => Promise<SynqResult<NewApiKey>>;
        readonly revoke: (id: string) => Promise<SynqResult<null>>;
    };
    readonly plugins: Readonly<Record<string, unknown>>;
}

useKeyableApis

Function. The brand's APIs that let the person make keys, with the scopes each defines.

function useKeyableApis(): UseAccountData<readonly { readonly identifier: string; readonly name: string; readonly scopes: readonly { readonly description: string; readonly name: string; }[]; }[]>

useLinkedAccounts

Function. The ways the person signs in: their email address, wallets, social accounts.

function useLinkedAccounts(): UseAccountData<readonly { readonly created_at: string; readonly handle: string | null; readonly id: string; readonly last_used_at: string | null; readonly password?: boolean | undefined; readonly provider: string; readonly subject: string; }[]>

usePlugin

Function. A browser plugin's actions, typed by the plugin, which must be one of the provider's plugins.

function usePlugin<Actions>(plugin: SynqClientPlugin<string, Actions>): Actions

UserButton

Component. The signed-in person's picture and name, showing a panel to manage their account or sign out: a disclosure (a button that shows and hides it), so its link and button are reached with Tab as anywhere else. Escape or a click elsewhere hides it. Nothing while nobody is signed in.

function UserButton({ unstyled, className, accountHref }: UserButtonProps): ReactNode

UserButtonProps

Interface. What UserButton takes: where its account link goes, and its look.

interface UserButtonProps extends SynqStyleProps {
    readonly accountHref?: string;
}

UserMetadata

Interface. What the brand keeps for the person (the account API's metadata). Augment it to type what the app reads:

``ts declare module '@synqauth/react' { interface UserMetadata { plan?: 'free' | 'pro' } } ``

interface UserMetadata {
    readonly [field: string]: unknown;
}

useSession

Function. Who is signed in. It reads the session alone, and asks the account API nothing.

function useSession(): UseSession

UseSession

Interface. What useSession() answers: who is signed in, and whether the app said yet.

interface UseSession {
    readonly status: SessionStatus;
    readonly isLoaded: boolean;
    readonly isSignedIn: boolean;
    readonly user: SynqUser | null;
    readonly expiresAt: number | null;
    readonly error: SynqError | null;
    readonly refresh: () => Promise<void>;
}

useSignIn

Function. One sign-in on the app's own screens, through the route mount's sign-in/flow.

function useSignIn(options?: UseSignInOptions): UseSignIn

UseSignIn

Interface. What useSignIn() answers: the sign-in's step, what went wrong, and each method's steps.

interface UseSignIn {
    readonly step: SignInStep;
    readonly pending: boolean;
    readonly problem: SignInProblem | null;
    readonly email: string | undefined;
    readonly canSkip: boolean;
    readonly handover: SignInHandover | null;
    readonly password: {
        readonly signIn: (input: {
            email: string;
            password: string;
        }) => Promise<void>;
        readonly signUp: (input: {
            email: string;
            password: string;
        }) => Promise<void>;
    };
    readonly emailCode: {
        readonly send: (email: string) => Promise<void>;
        readonly verify: (code: string) => Promise<void>;
        readonly resend: () => Promise<void>;
    };
    readonly passkey: {
        readonly supported: boolean;
        readonly autofill: boolean;
        readonly relatedDomain: string | null;
        readonly signIn: (options?: {
            related?: boolean;
        }) => Promise<void>;
        readonly startAutofill: () => Promise<void>;
    };
    readonly verifyEmail: {
        readonly verify: (code: string) => Promise<void>;
        readonly resend: () => Promise<void>;
        readonly skip: () => Promise<void>;
    };
    readonly continueOnHostedPage: (options?: {
        method?: ChallengeMethod;
        loginHint?: string;
    }) => void;
    readonly startOver: () => Promise<void>;
}

UseSignInOptions

Interface. What useSignIn() takes: where to go once signed in, or what to do instead.

interface UseSignInOptions {
    readonly returnTo?: string;
    readonly onSignedIn?: (returnTo: string) => void;
}

useUser

Function. The signed-in person: their ID token's claims at once, then their profile and metadata.

function useUser(): UseUser

UseUser

Interface. What useUser() answers: the person's claims, profile and metadata, and update for the profile.

interface UseUser {
    readonly isLoaded: boolean;
    readonly isSignedIn: boolean;
    readonly user: SynqUser | null;
    readonly profile: Profile | null;
    readonly metadata: UserMetadata | null;
    readonly isLoading: boolean;
    readonly error: SynqError | null;
    readonly update: (changes: ProfileUpdate) => Promise<SynqResult<Profile>>;
    readonly reload: () => Promise<void>;
}

useWallets

Function. The person's wallets, the primary one marked.

function useWallets(): UseAccountData<readonly { readonly address: string; readonly created_at: string; readonly id: string; readonly label: string | null; readonly last_used_at: string | null; readonly primary: boolean; }[]>

VerifyEmailForm

Component. The code that proves a new account's address, or "Skip for now" where the brand allows.

function VerifyEmailForm({ signIn, unstyled, className }: SignInPartProps): ReactNode

Wallet

Type. A Solana wallet the person signs in with.

type Wallet = AccountComponents['schemas']['Wallet'];

WalletManager

Component. Manage the signed-in person's wallets. Nothing while nobody is signed in.

function WalletManager({ unstyled, className }: SynqStyleProps): ReactNode

WalletManagerProps

Type. What WalletManager takes: its look.

type WalletManagerProps = SynqStyleProps;

See every package.

On this page