Supabase客户端初始化 #
一、基础客户端初始化 #
1.1 安装依赖 #
bash
# npm
npm install @supabase/supabase-js
# yarn
yarn add @supabase/supabase-js
# pnpm
pnpm add @supabase/supabase-js
1.2 基础初始化 #
typescript
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://your-project.supabase.co'
const supabaseKey = 'your-anon-key'
const supabase = createClient(supabaseUrl, supabaseKey)
1.3 完整配置选项 #
typescript
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.SUPABASE_URL!
const supabaseKey = process.env.SUPABASE_ANON_KEY!
const supabase = createClient(supabaseUrl, supabaseKey, {
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
flowType: 'implicit',
storage: window.localStorage,
storageKey: 'supabase.auth.token',
debug: false,
},
global: {
headers: {
'x-custom-header': 'custom-value',
},
},
db: {
schema: 'public',
},
realtime: {
params: {
eventsPerSecond: 10,
},
},
})
二、React项目集成 #
2.1 基础集成 #
typescript
// lib/supabase.ts
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.REACT_APP_SUPABASE_URL!
const supabaseKey = process.env.REACT_APP_SUPABASE_ANON_KEY!
export const supabase = createClient(supabaseUrl, supabaseKey)
2.2 在组件中使用 #
tsx
// components/UserList.tsx
import { useState, useEffect } from 'react'
import { supabase } from '../lib/supabase'
interface User {
id: number
name: string
email: string
}
export function UserList() {
const [users, setUsers] = useState<User[]>([])
const [loading, setLoading] = useState(true)
useEffect(() => {
fetchUsers()
}, [])
async function fetchUsers() {
const { data, error } = await supabase
.from('users')
.select('*')
if (error) {
console.error('Error fetching users:', error)
} else {
setUsers(data || [])
}
setLoading(false)
}
if (loading) return <div>Loading...</div>
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
2.3 使用Auth Helpers #
bash
# 安装Auth Helpers
npm install @supabase/auth-helpers-react @supabase/auth-helpers-nextjs
tsx
// App.tsx
import { SessionContextProvider } from '@supabase/auth-helpers-react'
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.REACT_APP_SUPABASE_URL!,
process.env.REACT_APP_SUPABASE_ANON_KEY!
)
function App() {
return (
<SessionContextProvider supabaseClient={supabase}>
<YourApp />
</SessionContextProvider>
)
}
三、Next.js项目集成 #
3.1 安装依赖 #
bash
npm install @supabase/supabase-js @supabase/auth-helpers-nextjs
3.2 创建客户端 #
typescript
// 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!
)
}
typescript
// 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 {
// Server Component中调用setAll会失败
// 这是预期的行为
}
},
},
}
)
}
3.3 在Server Component中使用 #
tsx
// app/users/page.tsx
import { createClient } from '@/lib/supabase/server'
export default async function UsersPage() {
const supabase = await createClient()
const { data: users, error } = await supabase
.from('users')
.select('*')
if (error) {
return <div>Error loading users</div>
}
return (
<ul>
{users?.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
3.4 在Client Component中使用 #
tsx
// components/UserForm.tsx
'use client'
import { useState } from 'react'
import { createClient } from '@/lib/supabase/client'
export function UserForm() {
const [name, setName] = useState('')
const supabase = createClient()
async function handleSubmit(e: React.FormEvent) {
e.preventDefault()
const { error } = await supabase
.from('users')
.insert({ name })
if (error) {
console.error('Error:', error)
} else {
setName('')
}
}
return (
<form onSubmit={handleSubmit}>
<input
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter name"
/>
<button type="submit">Add User</button>
</form>
)
}
3.5 中间件配置 #
typescript
// middleware.ts
import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return request.cookies.getAll()
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value }) =>
request.cookies.set(name, value)
)
supabaseResponse = NextResponse.next({
request,
})
cookiesToSet.forEach(({ name, value, options }) =>
supabaseResponse.cookies.set(name, value, options)
)
},
},
}
)
const {
data: { session },
} = await supabase.auth.getSession()
if (!session && request.nextUrl.pathname.startsWith('/protected')) {
const url = request.nextUrl.clone()
url.pathname = '/login'
return NextResponse.redirect(url)
}
return supabaseResponse
}
export const config = {
matcher: [
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
}
四、Vue项目集成 #
4.1 安装依赖 #
bash
npm install @supabase/supabase-js
4.2 创建插件 #
typescript
// plugins/supabase.ts
import { createClient } from '@supabase/supabase-js'
import type { App } from 'vue'
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseKey)
export default {
install(app: App) {
app.provide('supabase', supabase)
}
}
4.3 注册插件 #
typescript
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import supabase from './plugins/supabase'
const app = createApp(App)
app.use(supabase)
app.mount('#app')
4.4 在组件中使用 #
vue
<!-- components/UserList.vue -->
<script setup lang="ts">
import { ref, onMounted, inject } from 'vue'
import type { SupabaseClient } from '@supabase/supabase-js'
const supabase = inject('supabase') as SupabaseClient
interface User {
id: number
name: string
email: string
}
const users = ref<User[]>([])
const loading = ref(true)
onMounted(async () => {
const { data, error } = await supabase
.from('users')
.select('*')
if (error) {
console.error('Error:', error)
} else {
users.value = data || []
}
loading.value = false
})
</script>
<template>
<div v-if="loading">Loading...</div>
<ul v-else>
<li v-for="user in users" :key="user.id">
{{ user.name }}
</li>
</ul>
</template>
4.5 使用Composable #
typescript
// composables/useSupabase.ts
import { inject } from 'vue'
import type { SupabaseClient } from '@supabase/supabase-js'
export function useSupabase() {
const supabase = inject('supabase') as SupabaseClient
return supabase
}
vue
<!-- 使用composable -->
<script setup lang="ts">
import { useSupabase } from '../composables/useSupabase'
const supabase = useSupabase()
</script>
五、React Native集成 #
5.1 安装依赖 #
bash
npm install @supabase/supabase-js
npm install react-native-url-polyfill
npm install @react-native-async-storage/async-storage
5.2 创建客户端 #
typescript
// lib/supabase.ts
import 'react-native-url-polyfill/auto'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'YOUR_SUPABASE_URL'
const supabaseKey = 'YOUR_SUPABASE_ANON_KEY'
export const supabase = createClient(supabaseUrl, supabaseKey, {
auth: {
storage: AsyncStorage,
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
})
5.3 在组件中使用 #
tsx
// screens/HomeScreen.tsx
import { useState, useEffect } from 'react'
import { View, Text, FlatList } from 'react-native'
import { supabase } from '../lib/supabase'
export function HomeScreen() {
const [users, setUsers] = useState([])
useEffect(() => {
fetchUsers()
}, [])
async function fetchUsers() {
const { data, error } = await supabase
.from('users')
.select('*')
if (!error && data) {
setUsers(data)
}
}
return (
<View>
<FlatList
data={users}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<Text>{item.name}</Text>
)}
/>
</View>
)
}
六、SvelteKit集成 #
6.1 安装依赖 #
bash
npm install @supabase/supabase-js @supabase/auth-helpers-sveltekit
6.2 创建客户端 #
typescript
// src/lib/supabaseClient.ts
import { createClient } from '@supabase/supabase-js'
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public'
export const supabase = createClient(
PUBLIC_SUPABASE_URL,
PUBLIC_SUPABASE_ANON_KEY
)
6.3 服务端Hooks #
typescript
// src/hooks.server.ts
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public'
import { createServerClient } from '@supabase/ssr'
import type { Handle } from '@sveltejs/kit'
export const handle: Handle = async ({ event, resolve }) => {
event.locals.supabase = createServerClient(
PUBLIC_SUPABASE_URL,
PUBLIC_SUPABASE_ANON_KEY,
{
cookies: {
getAll() {
return event.cookies.getAll()
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value, options }) =>
event.cookies.set(name, value, { ...options, path: '/' })
)
},
},
}
)
event.locals.safeGetSession = async () => {
const {
data: { session },
} = await event.locals.supabase.auth.getSession()
return session
}
return resolve(event, {
filterSerializedResponseHeaders(name) {
return name === 'content-range'
},
})
}
七、配置选项详解 #
7.1 Auth配置 #
typescript
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: true,
flowType: 'implicit' | 'pkce',
storage: customStorage,
storageKey: 'supabase.auth.token',
debug: false,
}
7.2 自定义存储 #
typescript
// 自定义存储适配器
const customStorage = {
getItem: (key: string) => {
return localStorage.getItem(key)
},
setItem: (key: string, value: string) => {
localStorage.setItem(key, value)
},
removeItem: (key: string) => {
localStorage.removeItem(key)
},
}
const supabase = createClient(url, key, {
auth: {
storage: customStorage,
},
})
7.3 全局配置 #
typescript
global: {
headers: {
'x-application-name': 'my-app',
},
fetch: customFetch,
}
八、类型定义 #
8.1 生成类型 #
bash
# 登录Supabase
supabase login
# 链接项目
supabase link --project-ref your-project-ref
# 生成类型
supabase gen types typescript --local > lib/database.types.ts
8.2 使用类型 #
typescript
// lib/database.types.ts
export type Json =
| string
| number
| boolean
| null
| { [key: string]: Json | undefined }
| Json[]
export interface Database {
public: {
Tables: {
users: {
Row: {
id: number
name: string
email: string
created_at: string
}
Insert: {
id?: number
name: string
email: string
created_at?: string
}
Update: {
id?: number
name?: string
email?: string
created_at?: string
}
}
}
}
}
typescript
// 使用类型
import { createClient } from '@supabase/supabase-js'
import type { Database } from './database.types'
const supabase = createClient<Database>(url, key)
// 现在有完整的类型支持
const { data } = await supabase
.from('users')
.select('*')
// data 类型为 { id: number; name: string; email: string; created_at: string }[]
九、错误处理 #
9.1 统一错误处理 #
typescript
// lib/supabase-error.ts
export function handleSupabaseError(error: any) {
if (error) {
console.error('Supabase Error:', error)
switch (error.code) {
case 'PGRST116':
return '数据不存在'
case '23505':
return '数据已存在'
case '42501':
return '权限不足'
default:
return error.message || '操作失败'
}
}
return null
}
9.2 使用示例 #
typescript
import { handleSupabaseError } from './lib/supabase-error'
async function fetchUser(id: number) {
const { data, error } = await supabase
.from('users')
.select('*')
.eq('id', id)
.single()
const errorMessage = handleSupabaseError(error)
if (errorMessage) {
throw new Error(errorMessage)
}
return data
}
十、总结 #
客户端初始化检查清单:
| 步骤 | 状态 |
|---|---|
| 安装依赖 | ☐ |
| 创建客户端 | ☐ |
| 配置环境变量 | ☐ |
| 测试连接 | ☐ |
| 生成类型定义 | ☐ |
| 配置错误处理 | ☐ |
下一步,让我们学习数据库基础操作!
最后更新:2026-03-28