Mutations
TanStack Query primitives for every Better Auth write endpoint.
Solid provides use* hooks for components. Shared options factories come from @better-auth-ui/core. Plugin factories come from their core plugin entrypoints.
import { useSignInEmail } from "@better-auth-ui/solid"
import { signInEmailOptions } from "@better-auth-ui/core"Use the hook in components. Use the core factory where Solid Query accepts a mutationOptions object.
Error handling
Each mutation adds throw: true to fetchOptions. The promise rejects with BetterFetchError instead of resolving with { error }.
You can therefore use the standard error, isError, throwOnError, and onError values from useMutation.
import { signInEmailOptions } from "@better-auth-ui/core"
import { useMutation } from "@tanstack/solid-query"
const signIn = useMutation(() => ({
...signInEmailOptions(authClient),
onError: (err) => toast.error(err.message)
}))Cache side effects
Factories that change authentication state use the same mutation keys as React. AuthProvider installs an invalidator for the standard cache updates.
Common side effects mirror the React docs:
signInEmailOptions/signInUsernameOptions/signInPasskeyOptions/signUpEmailOptions: reset the session query so it retrieves the new session.signInSocialOptions/signInMagicLinkOptions: redirect without a cache update.signOutOptions: remove every["auth", ...]query.useUpdateUser: update the current user's profile fields and refresh the cached session.setActiveSessionOptions: refresh the session and device-session queries after the active session changes.changeEmailOptions: refresh the session.addPasskeyOptions/deletePasskeyOptions: refresh the passkey list.revokeSessionOptions: refresh the sessions list.revokeMultiSessionOptions: refresh the device sessions list.unlinkAccountOptions: refresh the linked accounts list.- Organization hook mutations expose invalidation metadata consumed by
AuthProvider, so organization/member/invitation queries are invalidated with the same shared cache keys.
The Solid package does not render toast messages. Add success and error handling in the application, or use Zaidan components with toast integration.
Tracking mutation state globally
All mutation keys start with "auth". The shared authMutationKeys factory in @better-auth-ui/core exposes these keys.
Use this factory instead of inline tuples. Call sites and mutation factories will then use the same keys:
import { authMutationKeys } from "@better-auth-ui/core"
const authPending = queryClient.isMutating({
mutationKey: authMutationKeys.all
})
const signInPending = queryClient.isMutating({
mutationKey: authMutationKeys.signIn.all
})
const emailSignInPending = queryClient.isMutating({
mutationKey: authMutationKeys.signIn.email
})Each grouping (signIn, signUp, passkey, multiSession) exposes an all prefix so you can match a whole feature at once.
Match inside a MutationCache observer for global toasts or analytics:
import { authMutationKeys } from "@better-auth-ui/core"
import { MutationCache } from "@tanstack/solid-query"
new MutationCache({
onError: (error, _vars, _ctx, mutation) => {
if (mutation.options.mutationKey?.[0] === authMutationKeys.all[0]) {
toast.error(error.message)
}
}
})Escape hatch
Use useAuthMutation for a mutation endpoint that has no specific factory or hook. Use useAuthQuery for a read endpoint.
import { useAuthMutation } from "@better-auth-ui/solid"
const mutation = useAuthMutation(
authClient.emailOtp.sendVerificationOtp,
["auth", "emailOtp", "sendVerificationOtp"]
)
mutation.mutate({ email: "[email protected]", type: "sign-in" })TypeScript infers variables from the authFn parameter. Required parameters prevent an empty mutate() call, while optional parameters permit it.
The factory adds throw: true to fetchOptions. Therefore, onError and error receive a BetterFetchError.
For shared mutation registration, global mutation state checks, a MutationCache observer, or manual useMutation, use the endpoint's option factory from core directly:
import { changePasswordOptions } from "@better-auth-ui/core"
import { useMutation } from "@tanstack/solid-query"
const mutation = useMutation(() => changePasswordOptions(authClient))For endpoints that already have a key in authMutationKeys, prefer it over an inline tuple so cache observers and mutation state checks line up.
Available mutations
Auth
signInEmailOptions
signInUsernameOptions
signInMagicLinkOptions
signInPasskeyOptions
signInSocialOptions
signUpEmailOptions
signOutOptions
requestPasswordResetOptions
resetPasswordOptions
sendVerificationEmailOptions
isUsernameAvailableOptions
oauthConsentOptions
verifyDeviceCodeOptions
approveDeviceOptions
denyDeviceOptions
Settings
useUpdateUser
useChangeEmail
useChangePassword
useDeleteUser
useLinkSocial
useUnlinkAccount
useAddPasskey
useDeletePasskey
useRevokeSession
useRevokeMultiSession
useSetActiveSession
useCreateApiKey
useDeleteApiKey
Organization
Last updated on