BETTER-AUTH. UI
Integrations

Next.js

This guide covers integrating @daveyplate/better-auth-ui into your Next.js project.

Starter Project

Want to skip the installation? Check out the starter here:

App Router

Follow these steps to set up @daveyplate/better-auth-ui in your Next.js project using the App Router:

Setting up AuthUIProvider

The first step is to set up the <AuthUIProvider> client component with your authClient, wrapping your layout. This is required to provide the context & hooks to your authentication components across your application.

app/providers.tsx
"use client"
 
import { AuthUIProvider } from "@daveyplate/better-auth-ui"
import Link from "next/link"
import { useRouter } from "next/navigation"
import type { ReactNode } from "react"
 
import { authClient } from "@/lib/auth-client"
 
export function Providers({ children }: { children: ReactNode }) {
    const router = useRouter()
 
    return (
        <AuthUIProvider
            authClient={authClient}
            navigate={router.push}
            replace={router.replace}
            onSessionChange={() => router.refresh()}
            LinkComponent={Link}
        >
            {children}
        </AuthUIProvider>
    )
}

Note: Since the Next.js App Router caches routes by default, navigation to protected routes may fail until you perform a router.refresh() to clear the cache. To prevent this issue, you must use router.refresh() in the provided onSessionChange callback. This forces Next.js to clear the router cache and reload middleware-protected content, ensuring subsequent navigations accurately reflect the current auth state.

Once configured, wrap your layout component with the Providers component:

app/layout.tsx
import type { ReactNode } from "react"
import { Providers } from "./providers"
 
export default function RootLayout({ children }: { children: ReactNode }) {
    return (
        <html lang="en">
            <body>
                <Providers>{children}</Providers>
            </body>
        </html>
    )
}

The <AuthUIProvider> can be fully customized with plugins, styles, localization and more. For more information and all available props, see the <AuthUIProvider> component documentation.

Creating Auth Pages

Create a dynamic route segment for authentication views in app/auth/[pathname]/page.tsx.

app/auth/[pathname]/page.tsx
import { AuthCard } from "@daveyplate/better-auth-ui"
import { authViewPaths } from "@daveyplate/better-auth-ui/server"
 
export function generateStaticParams() {
    return Object.values(authViewPaths).map((pathname) => ({ pathname }))
}
 
export default async function AuthPage(
    { params }: { params: Promise<{ pathname: string }> }
) {
    const { pathname } = await params
 
    return (
        <main className="flex flex-col grow p-4 items-center justify-center">
            <AuthCard pathname={pathname} />
        </main>
    )
}

The newly created dynamic route covers the following paths by default:

  • /auth/sign-in – Sign in via email/password and social providers
  • /auth/sign-up – New account registration
  • /auth/magic-link – Email login without a password
  • /auth/forgot-password – Trigger email to reset forgotten password
  • /auth/reset-password – Set new password after receiving reset link
  • /auth/sign-out – Log the user out of the application
  • /auth/settings – User account management page (requires authentication)
  • /auth/callback – Internal route to handle Auth callbacks (do not use directly)

Ensure that any links to the authentication process utilize these routes accordingly. All routes will render the <AuthCard /> component and automatically handle navigation and authentication flow.

Pages Router

Follow these steps to set up @daveyplate/better-auth-ui in your Next.js project using the Pages Router:

Setting up AuthUIProvider

First set up the <AuthUIProvider> within your custom App component in _app.tsx.

pages/_app.tsx
import type { AppProps } from "next/app"
import { AuthUIProvider } from "@daveyplate/better-auth-ui"
import { useRouter } from "next/router"
import Link from "next/link"
 
import { authClient } from "@/lib/auth-client"
 
export default function App({ Component, pageProps }: AppProps) {
    const router = useRouter()
 
    return (
        <AuthUIProvider
            authClient={authClient}
            navigate={router.push}
            replace={router.replace}
            onSessionChange={() => router.reload()}
            LinkComponent={Link}
        >
            <Component {...pageProps} />
        </AuthUIProvider>
    )
}

Now the authentication context is available across your entire application.

Creating Auth Pages

Create a page with a dynamic segment in your Pages directory in pages/auth/[pathname].tsx

pages/auth/[pathname].tsx
import { AuthCard } from "@daveyplate/better-auth-ui"
import { authViewPaths } from "@daveyplate/better-auth-ui/server"
 
export default function AuthPage({ pathname }: { pathname: string }) {
    return (
        <main className="flex flex-col grow p-4 items-center justify-center">
            <AuthCard pathname={pathname} />
        </main>
    )
}
 
export async function getStaticPaths() {
    return {
        paths: Object.values(authViewPaths).map((pathname) => ({ params: { pathname } })),
        fallback: false
    }
}
 
export async function getStaticProps({ params }: { params: { pathname: string } }) {
    return { props: { pathname: params.pathname } }
}

With this setup, the following routes will automatically handle their associated views:

  • /auth/sign-in – Sign in via email/password and social providers
  • /auth/sign-up – New user registration
  • /auth/magic-link – Magic link email login
  • /auth/forgot-password – Initiate forgotten password reset
  • /auth/reset-password – Reset password after receiving email
  • /auth/sign-out – Log user out of account
  • /auth/callback – Internal route to handle OAuth callbacks (do not navigate to this route directly)

On this page