BTST
PluginsQuickstartDocs
Live Blog

From research to product evaluation

Evaluating a publishing workflow for an app you already own?

See what the BTST Blog plugin adds to an existing React or Next.js app
BTST

Open-source TypeScript features for the React application, data, and deployment you already own.

Released plugins

  • Blog
  • AI Chat
  • CMS
  • Form Builder
  • UI Builder
  • Kanban
  • Comments
  • Media
  • Route Docs
  • OpenAPI
  • Better Auth UI

Resources

  • Quickstart
  • Documentation
  • All plugins
  • Live Blog
  • GitHub (opens in a new tab)
© 2026 BTST. Open source under the MIT License.
AI Chat
September 14, 2026ReactBetter Auth UI

Customize BTST Sign-In Pages with Better Auth UI Overrides

Change sign-in copy, card styling, and per-page localization while preserving session refresh, redirects, and server-side auth capabilities.

Customize BTST Sign-In Pages with Better Auth UI Overrides

To change the wording, spacing, or layout of a BTST sign-in page, start with the auth plugin's provider overrides. You can customize an individual page while keeping the companion's form handling, validation, and navigation.

This guide targets @btst/better-auth-ui@2.0.0 with BTST v3. It assumes that your Better Auth server and the companion's auth/account routes already work. If they do not, follow the integration guide first and check the compatible dependency versions.

Choose the configuration that owns the change#

The companion separates shared auth settings from individual view props:

ChangeConfiguration
Connect the Better Auth browser clientoverrides.auth.authClient
Refresh server-rendered state after a session changesoverrides.auth.onSessionChange
Set the default destination after authenticationoverrides.auth.redirectTo
Change sign-in copy or card stylingoverrides.auth.pageProps.signIn
Customize the sign-up view separatelyoverrides.auth.pageProps.signUp
Configure account details or avatar handlingoverrides.account

Keep these objects in the existing StackProvider. A second auth client or an extra provider around one form can create two independently configured parts of the interface.

Customize one page#

This helper returns an auth override object. Pass your existing browser client and framework refresh callback, then use the result as overrides.auth:

TS
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
import type { AuthPluginOverrides } from "@btst/better-auth-ui/client";

export function createAuthOverrides(
  authClient: AuthPluginOverrides["authClient"],
  onSessionChange: NonNullable<AuthPluginOverrides["onSessionChange"]>,
): AuthPluginOverrides {
  return {
    authClient,
    onSessionChange,
    redirectTo: "/pages/account/settings",
    pageProps: {
      signIn: {
        className: "w-full max-w-md",
        classNames: {
          title: "text-2xl font-semibold",
          description: "text-sm",
        },
        localization: {
          SIGN_IN: "Sign in to your workspace",
          SIGN_IN_DESCRIPTION: "Use the email associated with your account.",
        },
      },
      signUp: {
        localization: {
          SIGN_UP: "Create your account",
        },
      },
    },
  };
}

The example uses the CLI's default /pages mount. If your site runtime mounts BTST under /p, the redirect should be /p/account/settings instead. The API handler path, commonly /api/auth, is a separate setting.

Keep the framework callback you already use: router.refresh() in Next.js, revalidator.revalidate() in React Router, or router.invalidate() in TanStack Start. Changing card copy should not remove the session synchronization your application needs.

Understand localization scope#

The released sign-in page reads pageProps.signIn, then forwards its props to AuthView. That view merges page localization over the shared context localization. Consequently, a page-specific SIGN_IN value wins for that view without replacing the sign-up page's copy.

Localization keys can appear more than once inside a view. Check the rendered heading, button, and supporting links after changing a key. For a distinct header or footer, AuthPageProps also exposes cardHeader and cardFooter; use those when the same translation key cannot express the intended layout.

A few translated strings do not make the entire authentication flow localized. Check password-reset pages, validation messages, provider names, server errors, and email templates. Your application must also set the appropriate document language. Do not assume the companion translates emails sent by your Better Auth server.

Keep presentation and server capabilities aligned#

Provider overrides include switches for features such as magic links, email OTP, and passkeys. Showing one of these controls does not configure its server endpoint, delivery callback, credentials, or database schema. Enable the matching Better Auth server and client integrations before exposing the control.

Similarly, hiding sign-up in the UI is a presentation decision. If registration must be closed, enforce that policy on the server. A user can call an endpoint without visiting your sign-in page.

Verify the actual auth flow#

Check the page at a narrow viewport and with keyboard navigation. Labels should remain visible, error text should fit, and focus should reach every interactive control. Avoid replacing accessible field labels with placeholders or adding CSS that hides validation messages.

Then test a failed sign-in, successful sign-in, sign-out, and return to a protected server-rendered page. Confirm that the expected redirect still works and the page reflects the new session. If authentication succeeds but protected content remains stale, inspect the session refresh callback before rebuilding the form.

The companion documentation covers the shared integration. The released auth override types, sign-in implementation, and AuthView define the customization behavior described here.

In This Post

Choose the configuration that owns the changeCustomize one pageUnderstand localization scopeKeep presentation and server capabilities alignedVerify the actual auth flow