Documentation Index
Fetch the complete documentation index at: https://docs.capx.ai/llms.txt
Use this file to discover all available pages before exploring further.
Features
- PostgreSQL database with Row Level Security
- Real-time subscriptions
- Authentication with social providers
- File storage with CDN
- Edge Functions
- Vector embeddings for AI
Quick Start
npx capx-compose@latest my-app --plugins= supabase
cd my-app
npm run dev
Configuration
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_KEY=your_service_key
Client Setup
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
export default supabase;
Authentication
Email/Password Auth
async function signUp(email: string, password: string) {
const { data, error } = await supabase.auth.signUp({
email,
password,
options: {
emailRedirectTo: `${window.location.origin}/auth/callback`,
},
});
return { data, error };
}
async function signIn(email: string, password: string) {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
return { data, error };
}
Social Authentication
async function signInWithProvider(provider: 'google' | 'github' | 'twitter') {
const { data, error } = await supabase.auth.signInWithOAuth({
provider,
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
});
return { data, error };
}
Session Management
function useUser() {
const [user, setUser] = useState(null);
useEffect(() => {
// Get initial session
supabase.auth.getSession().then(({ data: { session } }) => {
setUser(session?.user ?? null);
});
// Listen for auth changes
const { data: { subscription } } = supabase.auth.onAuthStateChange(
(_event, session) => {
setUser(session?.user ?? null);
}
);
return () => subscription.unsubscribe();
}, []);
return user;
}
Database Operations
CRUD Operations
// Create
async function createPost(post: Post) {
const { data, error } = await supabase
.from('posts')
.insert(post)
.select()
.single();
return { data, error };
}
// Read
async function getPosts() {
const { data, error } = await supabase
.from('posts')
.select('*, author:users(name, avatar)')
.order('created_at', { ascending: false });
return { data, error };
}
// Update
async function updatePost(id: string, updates: Partial<Post>) {
const { data, error } = await supabase
.from('posts')
.update(updates)
.eq('id', id)
.select()
.single();
return { data, error };
}
// Delete
async function deletePost(id: string) {
const { error } = await supabase
.from('posts')
.delete()
.eq('id', id);
return { error };
}
Best Practices
- RLS Policies: Always enable Row Level Security
- Type Safety: Generate TypeScript types from schema
- Connection Pooling: Use connection pooling for high traffic
- Caching: Implement proper caching strategies
- Error Handling: Handle network and permission errors
Resources