Installation
Install the SDK and add the provider to your React app.
Prerequisites
- React 18+
- Node.js 18+
- A BuildBase account (sign up here)
Tip
Three shortcuts. npx buildbase init below does every step on this page in an
app you already have. The Next.js
starter has them done
already. And in Claude Code, Cursor, Codex or Copilot, the BuildBase
skill will do them in your own app.
Install the SDK
npm install @buildbase/sdkOr let the CLI write these files
The SDK ships a buildbase command. In an existing app, init does what the
rest of this page describes:
npm install @buildbase/sdk
npx buildbase init --org-id <your 24-character org id>It reads your package.json to tell Next.js, Vite and Express apart, then
writes the provider, the three auth routes, a webhook route and .env.example
plus .env.local, and wraps your root layout. On Next.js that is ten files.
Four things worth knowing before you run it:
- It never overwrites. A file that exists is kept and reported, and an environment variable you have already filled in is left alone.
- Secrets stay empty. It writes the keys and leaves the values blank, and it refuses a secret passed as a command-line argument.
- Running it twice is safe. The second run prints
already configuredand changes nothing. .env.localis only written if git ignores it. Otherwise you get.env.exampleand a line explaining why.
Needs @buildbase/sdk
0.0.79 or
later. A Pages Router app is refused rather than filled with App Router files,
and Remix is detected with a pointer to the guide.
Import the styles
Add this import at the top of your app's entry file. This loads styles for all pre-built UI components.
import '@buildbase/sdk/css';Create the provider
import { ApiVersion } from '@buildbase/sdk';
import { SaaSOSProvider } from '@buildbase/sdk/react';
import '@buildbase/sdk/css';
function BuildBaseProvider({ children }: { children: React.ReactNode }) {
return (
<SaaSOSProvider
serverUrl="https://api.console.buildbase.app"
version={ApiVersion.V1}
orgId="your-org-id"
auth={{
clientId: 'your-client-id',
redirectUrl: 'http://localhost:3000/callback',
callbacks: {
getSession: async () => {
// Restore session ID from your httpOnly cookie
const res = await fetch('/api/auth/session');
const data = await res.json();
return data.sessionId ?? null;
},
handleAuthentication: async (code) => {
// Exchange the auth code for a session on your backend
const res = await fetch('/api/auth/verify', {
method: 'POST',
body: JSON.stringify({ code }),
});
const data = await res.json();
return { sessionId: data.sessionId };
},
onSignOut: async () => {
// Clear the session cookie on your backend
await fetch('/api/auth/signout', { method: 'POST' });
},
},
}}
>
{children}
</SaaSOSProvider>
);
}
export default BuildBaseProvider;Provider props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
serverUrl | string | Yes | - | API server URL (must be valid URL) |
version | ApiVersion | Yes | - | API version - use ApiVersion.V1 |
orgId | string | Yes | - | Organization ID (24 hex characters, from Settings → General) |
auth | IAuthConfig | No | - | Auth config with clientId, redirectUrl, and callbacks |
locale | SDKLocale | No | 'en' | UI language ('en', 'es', 'fr', 'de', 'ja', 'zh', 'hi', 'ar') |
defaultPermissions | Record<string, string[]> | No | - | Default app-level permissions per role |
getCheckoutStripeParams | async callback | No | - | Called before every Stripe checkout to return metadata, referral IDs, etc. |
ui | SDKUIConfig | No | - | Show/hide parts of the SDK UI (settings sections, row actions, switcher) and override UI strings. Visibility options only hide UI - they never bypass permissions |
loadingComponent | ReactNode or render function | No | Built-in spinner | Content for the full-screen loading overlay shown during auth code exchange. Pass a function to receive { message } |
tracking | TrackingOptions | No | - | Tracking & Tags: consent mode ('auto', 'granted', 'denied'), automatic page views, event hooks and debug logging. Tags themselves are set in the console. See Tracking |
mcp | McpConnectionConfig | No | - | MCP server connection info (url required; optional name, docsUrl, clients, prompt). Enables the "connect an agent" guide on the Connected Agents settings screen |
Auth callbacks
| Callback | Required | Description |
|---|---|---|
getSession | Yes | Restore session on page refresh (read from httpOnly cookie via server) |
handleAuthentication | Yes | Exchange OAuth code for { sessionId } (set httpOnly cookie on server) |
onSignOut | Yes | Clear session on sign out (clear httpOnly cookie on server) |
onSessionExpired | No | Called when session is missing, expired, or invalid. Receives reason. |
handleEvent | No | Listen to SDK events (workspace switch, auth state changes) |
onWorkspaceChange | No | Called before workspace switch - receives { workspace, user, role } |
Wrap your app
import BuildBaseProvider from './BuildBaseProvider';
function App() {
return (
<BuildBaseProvider>
<Dashboard />
</BuildBaseProvider>
);
}What you need from the BuildBase dashboard
- orgId - Found in Settings > General after creating your organization.
- clientId - Found in User management > Access > Authentication after creating an auth client.
- redirectUrl - The URL BuildBase redirects to after sign-in. Add this to your client's redirect URLs in User management > Access > Authentication. For local development, use
http://localhost:3000/callback. - clientSecret - Shown in full once, in the dialog that appears when the auth client is created. Afterwards every screen shows only its first and last five characters, so copy it before closing that dialog. Lost it? Open the client and choose Regenerate - the new secret is shown once in the same way, and the old one stops working immediately. It is a server-side value: keep it out of
NEXT_PUBLIC_variables (see Production).
Next Steps
- Quickstart - Build a working app with auth in 5 minutes.