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:
- A working
lib/auth.ts (better-auth server with memory adapter for the playground)
- A working
lib/auth-client.ts (better-auth client pointing at the correct base URL)
- A
app/p/[[...all]]/layout.tsx with StackProvider wired up with auth, account, and organization overrides
authClientPlugin, accountClientPlugin, and organizationClientPlugin registered in stack-client.tsx
@import "@btst/better-auth-ui/css" in globals.css
@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.ts — better-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
Summary
When the
better-auth-uiplugin is enabled in the playground, opening any auth route in the StackBlitz embed shows: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 nobetter-auth-uisupport whatsoever. When the playground generates a StackBlitz project with thebetter-auth-uiplugin enabled, the following required pieces are entirely absent:lib/auth.tsbetter-authserver instance — required to configure sessions, routes (/api/auth/[...]), and DB adapterlib/auth-client.tsbetter-authclient (createAuthClient()) — must be passed asauthClientto every plugin overrideapp/p/[[...all]]/layout.tsxStackProviderwithauth,account, andorganizationplugin overrides (includingauthClient,navigate,replace,Link,basePath,redirectTo)authClientPlugin/accountClientPlugin/organizationClientPlugininstack-client.tsx@btst/better-auth-ui/clientthat wire auth routes into the stackThe
better-auth-uicomponents calluseSession()internally, which expects anauthClientto have been threaded through the plugin overrides and itsAuthQueryProviderto be in the tree. Without any of the above, the call is made againstundefined, causing the crash.The current
stack-client.tsxtemplate only registers the other plugins (blog, cms, kanban, etc.) and has no mention ofbetter-auth-ui.Expected Behaviour
When the
better-auth-uiplugin is toggled on in the playground, the generated StackBlitz project should include:lib/auth.ts(better-auth server with memory adapter for the playground)lib/auth-client.ts(better-auth client pointing at the correct base URL)app/p/[[...all]]/layout.tsxwithStackProviderwired up withauth,account, andorganizationoverridesauthClientPlugin,accountClientPlugin, andorganizationClientPluginregistered instack-client.tsx@import "@btst/better-auth-ui/css"inglobals.css@btst/better-auth-ui(andbetter-auth) listed as dependenciesGuidance for Implementation
1. Add the missing codegen templates
All templates live under
scripts/codegen/files/nextjs/. New files needed:lib/auth.ts—better-authserver (see better-auth docs):lib/auth-client.ts— better-auth client:app/p/[[...all]]/layout.tsx— StackProvider with auth overrides (see plugin docs):2. Update
lib/stack-client.tsxtemplateAdd the three
better-auth-uiclient plugins alongside the existing ones:These additions should only be emitted by the codegen CLI when the
better-auth-uiplugin is selected — the CLI likely already has a conditional plugin registration pattern.3. Update
globals.csstemplateAppend
@import "@btst/better-auth-ui/css";when the plugin is enabled.4. Add
better-auth-uito Next.js API route handler (app/api/auth/[...all]/route.ts)The better-auth server needs a catch-all route:
5. Check the
setup-nextjs.shscriptThe script runs
btst initand may need a flag or an additional step to install@btst/better-auth-uiandbetter-authwhen the plugin is selected.References
scripts/codegen/files/nextjs/scripts/codegen/files/nextjs/lib/stack-client.tsxscripts/codegen/setup-nextjs.sh