Skip to content

Playground: better-auth-ui plugin crash #113

@olliethedev

Description

@olliethedev

Summary

When the better-auth-ui plugin is enabled in the playground, opening any auth route in the StackBlitz embed shows:

Something went wrong!
Cannot read properties of undefined (reading 'useSession')

Reproduction URL:
https://www.better-stack.ai/playground?seeds=blog,cms,form-builder,ui-builder,kanban&plugins=blog,ai-chat,cms,form-builder,ui-builder,kanban,comments,media,better-auth-ui,open-api&view=preview

Root Cause

The codegen CLI templates (scripts/codegen/files/nextjs/) have no better-auth-ui support whatsoever. When the playground generates a StackBlitz project with the better-auth-ui plugin enabled, the following required pieces are entirely absent:

Missing file Why it's needed
lib/auth.ts better-auth server instance — required to configure sessions, routes (/api/auth/[...]), and DB adapter
lib/auth-client.ts better-auth client (createAuthClient()) — must be passed as authClient to every plugin override
app/p/[[...all]]/layout.tsx StackProvider with auth, account, and organization plugin overrides (including authClient, navigate, replace, Link, basePath, redirectTo)
authClientPlugin / accountClientPlugin / organizationClientPlugin in stack-client.tsx The three client-side plugins from @btst/better-auth-ui/client that wire auth routes into the stack

The better-auth-ui components call useSession() internally, which expects an authClient to have been threaded through the plugin overrides and its AuthQueryProvider to be in the tree. Without any of the above, the call is made against undefined, causing the crash.

The current stack-client.tsx template only registers the other plugins (blog, cms, kanban, etc.) and has no mention of better-auth-ui.

Expected Behaviour

When the better-auth-ui plugin is toggled on in the playground, the generated StackBlitz project should include:

  1. A working lib/auth.ts (better-auth server with memory adapter for the playground)
  2. A working lib/auth-client.ts (better-auth client pointing at the correct base URL)
  3. A app/p/[[...all]]/layout.tsx with StackProvider wired up with auth, account, and organization overrides
  4. authClientPlugin, accountClientPlugin, and organizationClientPlugin registered in stack-client.tsx
  5. @import "@btst/better-auth-ui/css" in globals.css
  6. @btst/better-auth-ui (and better-auth) listed as dependencies

Guidance for Implementation

1. Add the missing codegen templates

All templates live under scripts/codegen/files/nextjs/. New files needed:

lib/auth.tsbetter-auth server (see better-auth docs):

import { betterAuth } from "better-auth"
// Use memory adapter for playground; swap for real DB adapter in production
export const auth = betterAuth({
  database: { /* memory or drizzle adapter */ },
  emailAndPassword: { enabled: true },
})

lib/auth-client.ts — better-auth client:

import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient({
  baseURL: process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000",
})

app/p/[[...all]]/layout.tsx — StackProvider with auth overrides (see plugin docs):

"use client"
import { StackProvider } from "@btst/stack/context"
import { authClient } from "@/lib/auth-client"
import Link from "next/link"
import { useRouter } from "next/navigation"

export default function PagesLayout({ children }) {
  const router = useRouter()
  const authConfig = {
    authClient,
    navigate: router.push,
    replace: router.replace,
    onSessionChange: () => router.refresh(),
    Link,
  }
  return (
    <StackProvider basePath="/p" overrides={{
      auth: { ...authConfig, basePath: "/p/auth", redirectTo: "/p/account/settings" },
      account: { ...authConfig, basePath: "/p/account" },
      organization: { ...authConfig, basePath: "/p/org", organization: { basePath: "/p/org" } },
    }}>
      {children}
    </StackProvider>
  )
}

2. Update lib/stack-client.tsx template

Add the three better-auth-ui client plugins alongside the existing ones:

import {
  authClientPlugin,
  accountClientPlugin,
  organizationClientPlugin,
} from "@btst/better-auth-ui/client"

// inside createStackClient plugins:
auth: authClientPlugin({ siteBaseURL: baseURL, siteBasePath: "/p" }),
account: accountClientPlugin({ siteBaseURL: baseURL, siteBasePath: "/p" }),
organization: organizationClientPlugin({ siteBaseURL: baseURL, siteBasePath: "/p" }),

These additions should only be emitted by the codegen CLI when the better-auth-ui plugin is selected — the CLI likely already has a conditional plugin registration pattern.

3. Update globals.css template

Append @import "@btst/better-auth-ui/css"; when the plugin is enabled.

4. Add better-auth-ui to Next.js API route handler (app/api/auth/[...all]/route.ts)

The better-auth server needs a catch-all route:

import { auth } from "@/lib/auth"
import { toNextJsHandler } from "better-auth/next-js"
export const { GET, POST } = toNextJsHandler(auth)

5. Check the setup-nextjs.sh script

The script runs btst init and may need a flag or an additional step to install @btst/better-auth-ui and better-auth when the plugin is selected.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions