Project Setup¶
Tạo Supabase Project¶
Step 1: Đăng ký tài khoản¶
Step 2: Tạo project mới¶
1. Dashboard → New Project
2. Điền thông tin:
- Name: my-project
- Database Password: (strong password)
- Region: Singapore (ap-southeast-1)
3. Create new project
4. Đợi ~2 phút để provision
Project Credentials¶
Lấy credentials từ Dashboard¶
Project Settings → API
- Project URL: https://xxx.supabase.co
- anon (public) key: eyJhbGciOiJIUzI1NiIs...
- service_role key: eyJhbGciOiJIUzI1NiIs... (SECRET!)
Environment Variables¶
# .env.local (Next.js)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...
# Server-side only (NEVER expose to client)
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIs...
Warning: KHÔNG BAO GIỜ expose
service_rolekey ở client-side!
Cài đặt Supabase Client¶
Install package¶
Tạo client (Browser)¶
// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr';
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
}
Tạo client (Server)¶
// lib/supabase/server.ts
import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';
export async function createClient() {
const cookieStore = await cookies();
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
);
} catch {}
},
},
}
);
}
Client cho Cloudflare Workers¶
// lib/supabase/edge.ts
import { createClient } from '@supabase/supabase-js';
import { getRequestContext } from '@cloudflare/next-on-pages';
let supabaseClient: ReturnType<typeof createClient> | null = null;
export function getSupabase() {
if (supabaseClient) return supabaseClient;
const { env } = getRequestContext();
supabaseClient = createClient(
env.NEXT_PUBLIC_SUPABASE_URL,
env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
{
auth: {
persistSession: false, // Edge không có persistent storage
autoRefreshToken: false,
},
}
);
return supabaseClient;
}
Service Role Client¶
Dùng cho server-side operations cần bypass RLS:
// lib/supabase/admin.ts
import { createClient } from '@supabase/supabase-js';
// ONLY use on server-side!
export function createAdminClient() {
return createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!, // Bypasses RLS
{
auth: {
autoRefreshToken: false,
persistSession: false,
},
}
);
}
Khi nào dùng service_role: - Migrations, seeding - Background jobs - Admin operations - Webhooks từ external services
Type Generation¶
Generate TypeScript types từ database¶
# Install Supabase CLI
npm install -g supabase
# Login
supabase login
# Generate types
supabase gen types typescript --project-id your-project-id > types/supabase.ts
Sử dụng generated types¶
// types/supabase.ts (generated)
export type Database = {
public: {
Tables: {
users: {
Row: { id: string; email: string; created_at: string };
Insert: { id?: string; email: string; created_at?: string };
Update: { id?: string; email?: string; created_at?: string };
};
};
};
};
// lib/supabase/client.ts
import { createBrowserClient } from '@supabase/ssr';
import type { Database } from '@/types/supabase';
export function createClient() {
return createBrowserClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
}
// Usage - fully typed!
const { data } = await supabase.from('users').select('*');
// data is typed as Database['public']['Tables']['users']['Row'][]
Project Structure¶
project/
├── lib/
│ └── supabase/
│ ├── client.ts # Browser client
│ ├── server.ts # Server client (Next.js)
│ ├── edge.ts # Edge client (Cloudflare)
│ └── admin.ts # Service role client
│
├── types/
│ └── supabase.ts # Generated types
│
├── supabase/
│ ├── config.toml # Local dev config
│ ├── migrations/ # SQL migrations
│ └── seed.sql # Seed data
│
└── .env.local # Environment variables
Hands-on Exercise¶
Setup project mới¶
# 1. Tạo Supabase project trên dashboard
# 2. Setup trong Next.js project
npm install @supabase/supabase-js @supabase/ssr
# 3. Tạo .env.local
echo "NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co" >> .env.local
echo "NEXT_PUBLIC_SUPABASE_ANON_KEY=xxx" >> .env.local
# 4. Tạo client files (copy từ slides)
# 5. Test connection
// app/test/page.tsx
import { createClient } from '@/lib/supabase/server';
export default async function TestPage() {
const supabase = await createClient();
const { data, error } = await supabase.from('users').select('*').limit(1);
return (
<div>
<h1>Supabase Connection Test</h1>
{error ? (
<p>Error: {error.message}</p>
) : (
<pre>{JSON.stringify(data, null, 2)}</pre>
)}
</div>
);
}
Tổng kết¶
Setup Checklist¶
- [ ] Tạo Supabase project
- [ ] Lưu credentials vào .env.local
- [ ] Install @supabase/supabase-js
- [ ] Tạo client utilities
- [ ] Generate TypeScript types
- [ ] Test connection
Key Points¶
- anon key = public, safe for client
- service_role key = secret, server-only
- Type generation = better DX
- Separate clients cho browser/server/edge
Q&A¶
- Region nào phù hợp cho dự án của bạn?
- Đã setup được connection chưa?
- Có lỗi gì không?