BuildBaseBuildBase

Installation

Install the SDK and add the provider to your React app.

Prerequisites

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/sdk

Or 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 configured and changes nothing.
  • .env.local is only written if git ignores it. Otherwise you get .env.example and 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

PropTypeRequiredDefaultDescription
serverUrlstringYes-API server URL (must be valid URL)
versionApiVersionYes-API version - use ApiVersion.V1
orgIdstringYes-Organization ID (24 hex characters, from Settings → General)
authIAuthConfigNo-Auth config with clientId, redirectUrl, and callbacks
localeSDKLocaleNo'en'UI language ('en', 'es', 'fr', 'de', 'ja', 'zh', 'hi', 'ar')
defaultPermissionsRecord<string, string[]>No-Default app-level permissions per role
getCheckoutStripeParamsasync callbackNo-Called before every Stripe checkout to return metadata, referral IDs, etc.
uiSDKUIConfigNo-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
loadingComponentReactNode or render functionNoBuilt-in spinnerContent for the full-screen loading overlay shown during auth code exchange. Pass a function to receive { message }
trackingTrackingOptionsNo-Tracking & Tags: consent mode ('auto', 'granted', 'denied'), automatic page views, event hooks and debug logging. Tags themselves are set in the console. See Tracking
mcpMcpConnectionConfigNo-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

CallbackRequiredDescription
getSessionYesRestore session on page refresh (read from httpOnly cookie via server)
handleAuthenticationYesExchange OAuth code for { sessionId } (set httpOnly cookie on server)
onSignOutYesClear session on sign out (clear httpOnly cookie on server)
onSessionExpiredNoCalled when session is missing, expired, or invalid. Receives reason.
handleEventNoListen to SDK events (workspace switch, auth state changes)
onWorkspaceChangeNoCalled 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

  1. orgId - Found in Settings > General after creating your organization.
  2. clientId - Found in User management > Access > Authentication after creating an auth client.
  3. 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.
  4. 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.