BETTER-AUTH. UI
Plugins

Admin

Add static user management, session details, and impersonation to an administration area.

The Admin plugin adds a static /admin/users page and a user-detail drawer. It also adds a "Stop impersonating" action to <UserButton />.

Setup

Enable the Better Auth admin plugin

Add admin() to the server configuration:

lib/auth.ts
import { betterAuth } from "better-auth"
import { admin } from "better-auth/plugins"

export const auth = betterAuth({
  // ...
  plugins: [
    admin() 
  ]
})

Update your database schema after enabling the plugin. Better Auth adds admin fields to users and an impersonatedBy field to sessions.

Add the matching client plugin

lib/auth-client.ts
import { createAuthClient } from "better-auth/react"
import { adminClient } from "better-auth/client/plugins"

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

Register the UI plugin

components/providers.tsx
import { AuthProvider } from "@better-auth-ui/heroui"
import { adminPlugin } from "@better-auth-ui/heroui/plugins"

<AuthProvider
  authClient={authClient}
  navigate={navigate}
  plugins={[adminPlugin()]} 
>
  {children}
</AuthProvider>

Add the users route

Create one static route for the users page:

app/admin/users/page.tsx
import { Admin } from "@better-auth-ui/heroui"

export default function AdminUsersPage() {
  return <Admin view="users" />
}

Use <Admin path="users" /> when a parent route passes the final static path segment. The user-detail drawer keeps user IDs out of the route contract.

Applications can control the drawer through <AdminUsers />:

<AdminUsers
  selectedUserId={selectedUserId}
  onSelectedUserIdChange={setSelectedUserId}
/>

Inspector tabs

The user inspector includes local Overview and Sessions tabs. Registered plugins can add more tabs without adding routes.

The Dash integration adds an Activity tab when both UI plugins are registered. Dash applies its own organization owner or admin access rules to this tab.

User actions

The users page can create users. The drawer can update a user's name and role, set a password, ban or unban the user, impersonate the user, delete the user, and revoke one or all of the user's sessions.

The UI checks the matching Admin client permission before it enables each action. Dangerous actions require confirmation. The UI also disables actions that would ban, delete, impersonate, or revoke sessions for the current user.

Permissions and privacy

The users page calls the Better Auth permission API before it requests the user list. Do not authorize the page from a role string alone.

The table searches one field per request. The supported fields are email and name.

Passwords stay in local form state and never enter query keys. The forms clear each password after the request or when the user closes the form. Session IP addresses are hidden unless showIpAddress is true.

Configure custom roles with the same names in Better Auth and the UI plugin:

adminPlugin({
  allowMultipleRoles: false,
  defaultRole: "member",
  impersonationRedirectTo: "/",
  pageSize: 25,
  roles: ["member", "support", "admin"],
  showIpAddress: false
})

Set allowMultipleRoles to false to make the create and edit forms accept one role. This option does not change adminRoles, which controls administrator access.

The public Admin client does not provide account disconnection, global organization administration, or a Sentinel dashboard. These views are not part of this integration.

User button behavior

adminPlugin() contributes <StopImpersonating /> through the userMenuItems slot. <UserButton /> places it above sign out.

The action renders only when session.session.impersonatedBy is present. Selecting it calls authClient.admin.stopImpersonating() and refreshes the cached session before the pending state completes.

import { StopImpersonating } from "@better-auth-ui/heroui/plugins"

<StopImpersonating />

Prop

Type

Options

adminPlugin({
  localization: {
    stopImpersonating: "Return to admin"
  }
})

Prop

Type

Localization

Prop

Type

Mutation API

import { useStopImpersonating } from "@better-auth-ui/react/plugins/admin"

const stopImpersonating = useStopImpersonating(authClient)

Use the hook when you need the same behavior outside the user button. It restores the admin session and awaits invalidation of the shared session query.

Last updated on

On this page