Client

Learn how to set up the Better Auth client for React, Vue, Svelte, and other frameworks, use hooks, configure fetch options, handle errors, and extend with client plugins.

Better Auth 提供了一个与流行前端框架(如 React、Vue、Svelte 等)兼容的客户端库。该客户端库包含一组用于与 Better Auth 服务器交互的函数。每个框架的客户端库都建立在一个与框架无关的核心客户端库之上,因此所有方法和钩子在所有客户端库中均保持一致。

安装

如果尚未安装,请先安装 better-auth。

npm i better-auth

创建客户端实例

从你所用的框架的包中导入 createAuthClient(例如 React 框架使用 "better-auth/react")。调用该函数创建你的客户端。传入你身份验证服务器的基础 URL。如果身份验证服务器与客户端运行在同一域上,则可以跳过此步骤。

If your auth server uses a different base path other than /api/auth, you can either pass the full URL including the path (e.g., http://localhost:3000/custom-path/auth), or use the basePath option separately.

lib/auth-client.ts
import { createAuthClient } from "better-auth/client"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // The base URL of your auth server
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // The base URL of your auth server
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/vue"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // The base URL of your auth server
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/svelte"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // The base URL of your auth server
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/solid"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // The base URL of your auth server
})

使用方法

创建客户端实例后,你可以使用该客户端与 Better Auth 服务器交互。客户端默认提供一组函数,也可以使用插件进行扩展。

示例:登录

auth-client.ts
import { createAuthClient } from "better-auth/client"
const authClient = createAuthClient()

await authClient.signIn.email({
    email: "test@user.com",
    password: "password1234"
})

钩子

除了标准方法外,客户端还提供钩子以便轻松访问不同的响应式数据。每个钩子都在客户端根对象中可用,且名称都以 use 开头。

示例:useSession

user.tsx
//make sure you're using the react client
import { createAuthClient } from "better-auth/react"
const { useSession } = createAuthClient() 

export function User() {
    const {
        data: session,
        isPending, //loading state
        error, //error object 
        refetch //refetch the session
    } = useSession()
    return (
        //...
    )
}
user.vue
<script lang="ts" setup>
import { authClient } from '@/lib/auth-client'
const session = authClient.useSession()
</script>
<template>
    <div>
        <button v-if="!session.data" @click="() => authClient.signIn.social({
            provider: 'github'
        })">
            Continue with GitHub
        </button>
        <div>
            <pre>{{ session.data }}</pre>
            <button v-if="session.data" @click="authClient.signOut()">
                Sign out
            </button>
        </div>
    </div>
</template>
user.svelte
<script lang="ts">
import { authClient } from "$lib/auth-client";
const session = authClient.useSession();
</script>

<div
    style="display: flex; flex-direction: column; gap: 10px; border-radius: 10px; border: 1px solid #4B453F; padding: 20px; margin-top: 10px;"
>
    <div>
    {#if $session.data}
        <div>
        <p>
            {$session.data.user.name}
        </p>
        <p>
            {$session.data.user.email}
        </p>
        <button
            onclick={async () => {
            await authClient.signOut();
            }}
        >
            Signout
        </button>
        </div>
    {:else}
        <button
        onclick={async () => {
            await authClient.signIn.social({
            provider: "github",
            });
        }}
        >
        Continue with GitHub
        </button>
    {/if}
    </div>
</div>
user.tsx
import { authClient } from "~/lib/auth-client";
import { Show } from 'solid-js';

export default function Home() {
    const session = authClient.useSession()
    return (
        <Show
            when={session()}
            fallback={<button onClick={toggle}>Log in</button>}
        >
            <button onClick={toggle}>Log out</button>
        </Show>
    ); 
}

请求选项

The client uses a library called better fetch to make requests to the server.

Better fetch 是对原生 fetch API 的封装,提供了更方便的请求方式。它由 Better Auth 团队创建,设计上与 Better Auth 无缝配合。

你可以通过传递 fetchOptions 对象给 createAuthClient,为客户端设置默认的 fetch 选项。

auth-client.ts
import { createAuthClient } from "better-auth/client"

const authClient = createAuthClient({
    fetchOptions: {
        // 任何 better-fetch 的选项
    },
})

禁用默认的 Fetch 插件

身份验证客户端包含默认的 fetch 插件,用于处理浏览器特有的行为,比如自动重定向。对于非浏览器环境(例如 React Native/Expo),你可以通过设置 disableDefaultFetchPluginstrue 来禁用这些插件:

auth-client.ts
import { createAuthClient } from "better-auth/client"

const authClient = createAuthClient({
    disableDefaultFetchPlugins: true,
})

你也可以将 fetch 选项传递给大多数客户端函数,作为第二个参数,或者作为对象中的属性。

import { authClient } from "@/lib/auth-client"

await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
}, {
    onSuccess(ctx) {
            //      
    }
})

//或

await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
    fetchOptions: {
        onSuccess(ctx) {
            //      
        }
    },
})

Session Options

You can configure how the client handles session fetching and revalidation using the sessionOptions option.

auth-client.ts
import { createAuthClient } from "better-auth/client"

const authClient = createAuthClient({
    sessionOptions: {
        refetchInterval: 0,
        refetchOnWindowFocus: true,
        refetchWhenOffline: false,
    }
})

Prop

Type

Disable Default Fetch Plugins

The client includes a default redirect plugin that handles authentication redirects. If you need to disable this behavior, you can set disableDefaultFetchPlugins to true.

auth-client.ts
import { createAuthClient } from "better-auth/client"

const authClient = createAuthClient({
    disableDefaultFetchPlugins: true
})

Disabling Hook Rerenders

某些端点在成功响应后,会触发 atom 信号,导致像 useSession 的钩子重新渲染。 这对于让你的 UI 与身份验证状态保持同步非常有用。

但是,有时你可能想要调用端点而不触发钩子重新渲染。 例如,更新不会影响 session 的用户偏好时,或者你想手动控制钩子何时更新。

你可以通过在 fetch 选项中设置 disableSignal: true,禁用特定端点调用的钩子重新渲染:

import { authClient } from "@/lib/auth-client"

// 作为第二个参数
await authClient.updateUser({
    name: "New Name"
}, {
    disableSignal: true
})

// 或者在 fetchOptions 中
await authClient.updateUser({
    name: "New Name",
    fetchOptions: {
        disableSignal: true
    }
})

disableSignal 设置为 true 时,端点调用会成功完成, 但像 useSession 这样的钩子不会自动重新渲染。你可以根据需要手动触发重新获取:

import { authClient } from "@/lib/auth-client"

const { refetch } = authClient.useSession()

await authClient.updateUser({
    name: "New Name"
}, {
    disableSignal: true,
    onSuccess() {
        // 如果需要,手动重新获取 session
        refetch()
    }
})

错误处理

Most of the client functions return a response object with the following properties:

  • data: The response data.
  • error: The error object if there was an error.

The error object contains the following properties:

  • message: The error message. (e.g., "Invalid email or password")
  • status: The HTTP status code.
  • statusText: The HTTP status text.
import { authClient } from "@/lib/auth-client"

const { data, error } = await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234"
})
if (error) {
    // 处理错误
}

如果动作支持 fetchOptions 选项,你可以传入 onError 回调来处理错误。

import { authClient } from "@/lib/auth-client"

await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
}, {
    onError(ctx) {
        // 处理错误
    }
})

// 或者
await authClient.signIn.email({
    email: "email@email.com",
    password: "password1234",
    fetchOptions: {
        onError(ctx) {
            // 处理错误
        }
    }
})

useSession 这样的钩子也会返回错误对象(如果获取 session 失败),此外还返回 isPending 属性以指示请求是否仍在进行中。

import { useSession } from "@/lib/auth-client"

const { data, error, isPending } = useSession()
if (error) {
    // 处理错误
}

错误代码

The client instance contains $ERROR_CODES object that contains all the error codes returned by the server. You can use this to handle error translations or custom error messages.

auth-client.ts
const authClient = createAuthClient();

type ErrorTypes = Partial<
	Record<
		keyof typeof authClient.$ERROR_CODES,
		{
			en: string;
			es: string;
		}
	>
>;

const errorCodes = {
	USER_ALREADY_EXISTS: {
		en: "user already registered",
		es: "usuario ya registrado",
	},
} satisfies ErrorTypes;

const getErrorMessage = (code: string, lang: "en" | "es") => {
	if (code in errorCodes) {
		return errorCodes[code as keyof typeof errorCodes][lang];
	}
	return "";
};


const { error } = await authClient.signUp.email({
	email: "user@email.com",
	password: "password",
	name: "User",
});
if(error?.code){
    alert(getErrorMessage(error.code, "en"));
}

插件

You can extend the client with plugins to add more functionality. Plugins can add new functions to the client or modify existing ones.

Example: Magic Link Plugin

auth-client.ts
import { createAuthClient } from "better-auth/client"
import { magicLinkClient } from "better-auth/client/plugins"

const authClient = createAuthClient({
    plugins: [
        magicLinkClient()
    ]
})

添加插件后,你可以使用插件提供的新函数。

import { authClient } from "@/lib/auth-client"

await authClient.signIn.magicLink({
    email: "test@email.com"
})