Start Here
Quick Start
Connect a Next.js app to Banata Auth in under 10 minutes. Install packages, set up auth routes, and add sign-in pages.
This guide walks you through adding Banata Auth to a Next.js application. By the end, you'll have working sign-up, sign-in, and session management.
Prerequisites
Before writing code, set up your Banata project:
- Sign in to the Banata dashboard.
- Create a project (or use your default project).
- Enable auth methods — go to Authentication > Methods and turn on at least one method (e.g., Email & Password).
- Configure providers — if you enabled social OAuth, add your provider credentials under Authentication > Providers.
- Set up email — if you're using email-based auth, configure an email provider under Emails > Providers and customize your templates under Email Templates.
- Create an API key — go to API Keys, create a new key, and copy it immediately. The raw key is only shown once.
Step 1: Install Packages
npm install @banata-auth/nextjs @banata-auth/react@banata-auth/nextjs— handles the auth route proxy and server-side auth helpers@banata-auth/react— provides pre-built sign-in/sign-up UI components
Step 2: Set Environment Variables
Create or update your .env.local file:
NEXT_PUBLIC_SITE_URL=http://localhost:3000
BANATA_API_KEY=sk_test_your_project_key
# Optional: only set this if you use a custom Banata auth domain
# or a self-hosted deployment. Hosted Banata defaults to:
# https://auth.banata.dev
# BANATA_AUTH_URL=https://auth.yourcompany.com| Variable | Description |
|---|---|
NEXT_PUBLIC_SITE_URL | Your app's public URL |
BANATA_API_KEY | Your project-scoped API key (keep this server-side only) |
BANATA_AUTH_URL | Optional override for custom/self-hosted Banata auth domains |
Important:
BANATA_API_KEYmust not have theNEXT_PUBLIC_prefix. It should only be accessible on the server.
Step 3: Create Server Auth Helpers
This file initializes the server-side auth connection to Banata. The API key binds your app to your Banata project.
// src/lib/auth-server.ts
import { createBanataAuthServer } from "@banata-auth/nextjs/server";
function requireEnv(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Missing required environment variable: ${name}`);
return value;
}
export const {
handler,
isAuthenticated,
getToken,
preloadAuthQuery,
fetchAuthQuery,
fetchAuthMutation,
fetchAuthAction,
} = createBanataAuthServer({
apiKey: requireEnv("BANATA_API_KEY"),
authUrl: process.env.BANATA_AUTH_URL,
});If you do not pass authUrl, the helper automatically uses https://auth.banata.dev.
Here's what each export does:
| Export | Purpose |
|---|---|
handler | Route handler for /api/auth — proxies auth requests to Banata |
isAuthenticated | Check if the current request has a valid session |
getToken | Get the current auth token for server-side API calls |
preloadAuthQuery | Preload a Convex query with auth context |
fetchAuthQuery | Execute a Convex query with auth context |
fetchAuthMutation | Execute a Convex mutation with auth context |
fetchAuthAction | Execute a Convex action with auth context |
Step 4: Create the Auth Route
This catch-all route proxies all /api/auth/* requests from your app to Banata. This keeps auth cookies on your domain.
// src/app/api/auth/[...all]/route.ts
import { handler } from "@/lib/auth-server";
export const { GET, POST, PUT, PATCH, DELETE, OPTIONS } = handler;Your browser makes auth requests to your app's /api/auth endpoint — never directly to the Banata backend.
Step 5: Create the Browser Auth Client
This client-side module is what your React components use to trigger sign-in, sign-up, sign-out, and other auth actions.
// src/lib/auth-client.ts
"use client";
import { createAuthClient } from "@banata-auth/react/plugins";
export const authClient = createAuthClient({
baseURL: "/api/auth",
});The baseURL points to your own app's auth route (Step 4), not the Banata backend URL.
Step 6: Add Sign-In and Sign-Up Pages
Sign-In Page
// src/app/sign-in/page.tsx
"use client";
import Link from "next/link";
import { SignInForm } from "@banata-auth/react";
import { authClient } from "@/lib/auth-client";
export default function SignInPage() {
return (
<SignInForm
authClient={authClient}
callbackURL="/"
title="Sign in"
description="Welcome back! Sign in to continue."
footer={<Link href="/sign-up">Create an account</Link>}
/>
);
}Sign-Up Page
// src/app/sign-up/page.tsx
"use client";
import Link from "next/link";
import { SignUpForm } from "@banata-auth/react";
import { authClient } from "@/lib/auth-client";
export default function SignUpPage() {
return (
<SignUpForm
authClient={authClient}
callbackURL="/"
title="Create account"
description="Sign up to get started."
footer={<Link href="/sign-in">Already have an account?</Link>}
/>
);
}The SignInForm and SignUpForm components automatically render the right fields and social buttons based on what auth methods you've enabled in the Banata dashboard.
Step 7: Protect Your Pages
Use the isAuthenticated helper to guard server-rendered pages:
// src/app/page.tsx
import { redirect } from "next/navigation";
import { isAuthenticated } from "@/lib/auth-server";
export default async function HomePage() {
const signedIn = await isAuthenticated();
if (!signedIn) {
redirect("/sign-in");
}
return <div>Welcome! You are signed in.</div>;
}Verify It Works
Start your development server and test the full flow:
- Open
/sign-upand create a new account. - After sign-up, verify you're redirected to your app.
- Open
/api/auth/get-sessionin your browser — you should see your session data. - Go to the Banata dashboard and check Users — the new user should appear there.
- Try signing out and signing back in at
/sign-in.
Configuring Banata by Code (Optional)
The dashboard is the easiest way to configure your project, but you can also use the SDK to manage configuration programmatically:
npm install @banata-auth/sdkimport { BanataAuth } from "@banata-auth/sdk";
const banata = new BanataAuth({
apiKey: process.env.BANATA_API_KEY!,
baseUrl: "https://auth.banata.dev",
});
// Enable auth methods
await banata.configuration.saveDashboardConfig({
authMethods: {
emailPassword: true,
emailOtp: true,
},
emailPassword: {
requireEmailVerification: true,
autoSignIn: true,
},
});
// Customize branding
await banata.configuration.saveBrandingConfig({
primaryColor: "#0f766e",
bgColor: "#f5f5f4",
borderRadius: 14,
});Changes made by the SDK update the same configuration the dashboard reads — they're always in sync.
Troubleshooting
Sign-in form renders but authentication fails
- Verify the auth method is enabled in the dashboard (e.g., Email & Password is toggled on).
- Check that provider credentials are configured if using social OAuth.
- Confirm
BANATA_API_KEYis set in your server environment. - If you set
BANATA_AUTH_URL, verify it points at your Banata auth domain and not a raw*.convex.cloudURL.
Sign-in succeeds but the app shows no session
- Make sure your browser is calling
/api/authon your app's origin, not the Banata backend URL directly. - Verify the auth route file exists at
src/app/api/auth/[...all]/route.ts. - Check
/api/auth/get-sessionin your browser — it should return session data.
Email verification or password reset emails aren't arriving
- Configure an email provider under Emails > Providers in the dashboard.
- Make sure the relevant email type is enabled under Emails > Configuration.
- Customize your templates under Email Templates.
Hitting rate limits during testing
Banata rate-limits auth endpoints to prevent abuse. If you're hitting limits during development:
- Wait a minute for the rate limit window to reset.
- Use different email addresses for each sign-up test.
- Avoid rapidly resubmitting forms.
Next Steps
Now that your app is connected to Banata, explore these topics:
- Next.js Integration — Deep dive into the Next.js package
- React Components — UI components and auth hooks
- Email & Password — Configure email/password sign-in
- Social OAuth — Add Google, GitHub, and other providers
- Organizations — Add multi-tenant workspaces