Skip to content
Torii docs

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)}
/>
);
}
NameTypeDescription
profileUserProfileData | nullThe user’s full profile. null while loading or when signed out.
isLoadingbooleantrue while the profile is being fetched.
isUpdatingbooleantrue while an update is in progress.
errorToriiError | nullError 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';