Archived: This repository is no longer maintained. Our current work is Charming, the collaborative cloud for apps you build.
This is a Next.js project that demonstrates how to integrate BetterAuth with Tambo AI for user authentication and AI-powered chat functionality.
The integration works by:
- Authentication: Users authenticate through BetterAuth (email/password or social providers)
- Token Exchange: The app retrieves the
idTokenfrom BetterAuth's API - Tambo Integration: The
idTokenis passed to Tambo'sTamboProvideras theuserToken - User Context: Tambo uses this token to identify and manage user sessions in the AI chat
- Node.js 22.17.0 or later
- npm, yarn, pnpm, or bun
Create a .env.local file in the root directory with the following variables:
# BetterAuth Social Providers (optional)
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
# Tambo AI
TAMBO_API_KEY=your_tambo_api_key
NEXT_PUBLIC_TAMBO_API_KEY=your_tambo_public_api_key- Install dependencies:
npm install
# or
yarn install
# or
pnpm install
# or
bun install- Run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev- Open your browser: Navigate to http://localhost:3005 to see the application.
The authentication system is configured in src/lib/auth.ts:
import { betterAuth } from "better-auth";
import Database from "better-sqlite3";
export const auth = betterAuth({
database: new Database("./sqlite.db"),
emailAndPassword: {
enabled: true,
},
socialProviders: {
google: {
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
},
github: {
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
},
},
});The client-side authentication is handled in src/lib/auth-client.ts:
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
baseURL: "http://localhost:3005",
});
export const { signIn, signUp, useSession, getAccessToken } = authClient;BetterAuth's API routes are set up in src/app/api/auth/[...all]/route.ts:
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
export const { POST, GET } = toNextJsHandler(auth);The magic happens in the chat layout (src/app/chat/layout.tsx):
"use client";
import { getAccessToken } from "@/lib/auth-client";
import { TamboProvider } from "@tambo-ai/react";
import { useEffect, useState } from "react";
export default function ChatLayout({
children,
}: {
children: React.ReactNode;
}) {
const [userToken, setUserToken] = useState<string>();
useEffect(() => {
async function refresh() {
const token = await getAccessToken({
providerId: "google",
});
setUserToken(token.data?.idToken);
}
refresh();
}, []);
return (
<TamboProvider
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
userToken={userToken}
>
{children}
</TamboProvider>
);
}Key Integration Steps:
- Get ID Token:
getAccessToken()retrieves theidTokenfrom BetterAuth - Pass to Tambo: The
idTokenis passed asuserTokento theTamboProvider - User Context: Tambo uses this token to maintain user context across AI interactions
Users can authenticate through the login form (src/components/login-form.tsx):
- Email/Password: Direct authentication with BetterAuth
- Social Providers: Google and GitHub OAuth integration
- Redirect: Successful authentication redirects to
/chat
The chat interface (src/app/chat/page.tsx) uses Tambo's MessageThreadFull component:
import { MessageThreadFull } from "@/components/ui/message-thread-full";
export default function ChatPage() {
return (
<div className="flex h-screen w-full">
<MessageThreadFull className="flex-1" variant="default" />
</div>
);
}- The
idTokenfrom BetterAuth serves as the user identifier for Tambo - Tokens are handled securely through BetterAuth's built-in token management
- Authentication: Visit
/loginto authenticate - Chat: Visit
/chatto interact with the AI (requires authentication) - Database: SQLite database (
sqlite.db) stores user data locally