Documentation Index
Fetch the complete documentation index at: https://docs.snackbase.dev/llms.txt
Use this file to discover all available pages before exploring further.
The SnackBase SDK provides React hooks and context providers for seamless integration with React applications.
Installation
Install the SDK and React peer dependency:
npm install @snackbase/sdk react
yarn add @snackbase/sdk react
pnpm add @snackbase/sdk react
React 18 or higher is required for the React integration.
Setup
1. Wrap with Provider
Wrap your application with SnackBaseProvider:
import { SnackBaseProvider } from "@snackbase/sdk/react";
function App() {
return (
<SnackBaseProvider
baseUrl="https://api.example.com"
apiKey={process.env.SNACKBASE_API_KEY}
defaultAccount="my-account"
>
<YourApp />
</SnackBaseProvider>
);
}
2. Use Hooks
Use the provided hooks in your components:
import { useAuth, useRecord } from "@snackbase/sdk/react";
function Profile() {
const { user, login, logout } = useAuth();
const { data: profile, loading } = useRecord("profiles", user?.id);
if (!user) {
return <button onClick={() => login(email, password)}>Login</button>;
}
return (
<div>
<h1>Welcome, {user.email}</h1>
{loading ? <p>Loading...</p> : <pre>{JSON.stringify(profile, null, 2)}</pre>}
<button onClick={logout}>Logout</button>
</div>
);
}
Provider Props
| Prop | Type | Required | Description |
|---|
baseUrl | string | Yes | API base URL |
apiKey | string | No | API key for server authentication |
defaultAccount | string | No | Default account slug |
timeout | number | No | Request timeout (ms) |
maxRetries | number | No | Max retry attempts |
storageBackend | StorageBackend | No | Token storage backend |
enableLogging | boolean | No | Enable request logging |
logLevel | LogLevel | No | Logging level |
Environment-Specific Setup
Development
<SnackBaseProvider
baseUrl={process.env.NEXT_PUBLIC_SNACKBASE_URL!}
defaultAccount="dev-account"
enableLogging={true}
logLevel="debug"
>
<App />
</SnackBaseProvider>
Production
<SnackBaseProvider
baseUrl={process.env.NEXT_PUBLIC_SNACKBASE_URL!}
apiKey={process.env.SNACKBASE_API_KEY}
enableLogging={false}
>
<App />
</SnackBaseProvider>
With Next.js
App Router
// app/layout.tsx
import { SnackBaseProvider } from "@snackbase/sdk/react";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<SnackBaseProvider
baseUrl={process.env.NEXT_PUBLIC_SNACKBASE_URL!}
>
{children}
</SnackBaseProvider>
</body>
</html>
);
}
Pages Router
// pages/_app.tsx
import type { AppProps } from "next/app";
import { SnackBaseProvider } from "@snackbase/sdk/react";
export default function App({ Component, pageProps }: AppProps) {
return (
<SnackBaseProvider
baseUrl={process.env.NEXT_PUBLIC_SNACKBASE_URL!}
>
<Component {...pageProps} />
</SnackBaseProvider>
);
}
With Vite
// src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import { SnackBaseProvider } from "@snackbase/sdk/react";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<SnackBaseProvider
baseUrl={import.meta.env.VITE_SNACKBASE_URL}
>
<App />
</SnackBaseProvider>
</React.StrictMode>
);
Access Client Directly
For advanced use cases, access the client directly:
import { useSnackBase } from "@snackbase/sdk/react";
function AdvancedComponent() {
const client = useSnackBase();
useEffect(() => {
// Use client directly
client.collections.list().then((collections) => {
console.log("Collections:", collections);
});
}, [client]);
return <div>Check console for collections</div>;
}
Server-Side Rendering
For SSR, skip provider on server:
import { SnackBaseProvider } from "@snackbase/sdk/react";
function App({ children }: { children: React.ReactNode }) {
// Only provide on client
if (typeof window === "undefined") {
return <>{children}</>;
}
return (
<SnackBaseProvider
baseUrl={process.env.NEXT_PUBLIC_SNACKBASE_URL!}
>
{children}
</SnackBaseProvider>
);
}
TypeScript Support
The React integration is fully typed:
import { useAuth, useRecord } from "@snackbase/sdk/react";
import type { User, Post } from "@snackbase/sdk";
function Profile() {
const { user } = useAuth<User>();
const { data: post } = useRecord<Post>("posts", "post-id");
// user and post are fully typed
console.log(user?.email);
console.log(post?.title);
}
Complete Example
import { SnackBaseProvider, useAuth, useRecord } from "@snackbase/sdk/react";
function App() {
return (
<SnackBaseProvider
baseUrl="https://api.example.com"
defaultAccount="my-account"
>
<Main />
</SnackBaseProvider>
);
}
function Main() {
const { user, login, logout, isLoading } = useAuth();
if (isLoading) {
return <div>Loading...</div>;
}
if (!user) {
return <LoginForm onLogin={login} />;
}
return (
<div>
<header>
<h1>Welcome, {user.email}</h1>
<button onClick={logout}>Logout</button>
</header>
<Dashboard />
</div>
);
}
function LoginForm({ onLogin }: { onLogin: (credentials: any) => Promise<void> }) {
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const form = e.currentTarget;
const email = (form.elements.namedItem("email") as HTMLInputElement).value;
const password = (form.elements.namedItem("password") as HTMLInputElement).value;
await onLogin({ email, password });
};
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" placeholder="Email" required />
<input name="password" type="password" placeholder="Password" required />
<button type="submit">Login</button>
</form>
);
}
function Dashboard() {
const { user } = useAuth();
const { data: profile, loading, error } = useRecord("profiles", user?.id || "");
if (loading) return <div>Loading profile...</div>;
if (error) return <div>Error loading profile</div>;
return (
<div>
<h2>Profile</h2>
<pre>{JSON.stringify(profile, null, 2)}</pre>
</div>
);
}
Next Steps