Skip to content

useUserProfile

useUserProfile() loads the signed-in user’s full /me profile and exposes a helper to update it. It fetches on mount (and when the user signs in) and tracks loading, updating, and error state.

  • Build a custom “edit profile” form (the prebuilt <UserProfile> already wraps this).
  • Read more fields than the JWT-decoded user carries: first/last name, locale, and the derived display name.
  • Read or write user metadata: profile.publicMetadata / profile.unsafeMetadata, and write the user-owned bag with updateProfile({ unsafeMetadata }).
import { useUserProfile } from '@torii-js/torii-react';
function EditName() {
const { profile, isUpdating, updateProfile } = useUserProfile();
async function save(firstName: string) {
// `name` is derived from first + last and is read-only; edit the parts.
const result = await updateProfile({ firstName });
if (!result.ok) alert(result.error.message);
}
return (
<input
defaultValue={profile?.firstName ?? ''}
disabled={isUpdating}
onBlur={(e) => save(e.target.value)}
/>
);
}
Name Type Description
profile UserProfileData | null The user’s full profile. null while loading or when signed out.
isLoading boolean true while the profile is being fetched.
isUpdating boolean true while an update is in progress.
error ToriiError | null Error from the last fetch or update, or null.
refresh () => Promise<void> Re-fetch the profile from the server.
updateProfile (fields: UpdateProfileFields) => Promise<MutationResult<UserProfileData>> Update profile fields: only included fields change. Resolves a discriminated result; never throws.
requestEmailChange (newEmail: string) => Promise<MutationResult<void>> Send a verified email-change confirmation link to newEmail; the address swaps only after the user clicks it. Call refresh() after confirmation.
updateUnsafeMetadata (metadata: Record<string, unknown>) => Promise<MutationResult<UserProfileData>> Deep-merge into the unsafe-metadata bag (a key set to null is removed); convenience over updateProfile({ unsafeMetadata }).

updateProfile resolves a discriminated result rather than throwing, so the message stays at the call site:

type MutationResult<T> =
| { ok: true; value: T }
| { ok: false; error: ToriiError };
  • useUser vs useUserProfile. Torii also exports a lighter useUser() returning { user, isLoaded, isSignedIn } (built on this hook), where user carries the id, verified flag, and metadata bags with an update method. It does not expose email addresses or linked identities; for those use useEmailAddresses and useIdentities.
  • Email changes. updateProfile does not change email, but this hook’s requestEmailChange(newEmail) starts a verified single-email change (confirmation-link flow); multi-email management lives in useEmailAddresses.
  • Metadata write rules. updateProfile can write only unsafeMetadata. publicMetadata is read-only here (server-written) and privateMetadata is never exposed to the SDK. See User metadata.
import type {
UseUserProfileReturn,
UserProfileData,
UpdateProfileFields,
MutationResult,
ToriiError,
} from '@torii-js/torii-react';