Skip to main content

supabase-architecture-variants

Use when choosing how to integrate Supabase into a specific stack — setting up Next.js SSR auth flows, wiring an SPA or React Native client, configuring mobile deep links, or designing multi-tenant data isolation. Covers where the client runs (browser vs server) and which key it uses (anon respects RLS, service_role bypasses it). Trigger with phrases like "supabase next.js", "supabase SSR", "supabase react native", "supabase SPA", "supabase serverless", "supabase multi-tenant", "supabase server component", "supabase architecture", "supabase service_role server".

소스 정보

저장소
jeremylongshore/claude-code-plugins-plus-skills
최근 소스 활동
2026년 7월 17일 23:53
감지된 SKILL.md 언어
영어
스타
2,604
포크
378

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
9 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
supabase-architecture-variants
description
Use when choosing how to integrate Supabase into a specific stack — setting up Next.js SSR auth flows, wiring an SPA or React Native client, configuring mobile deep links, or designing multi-tenant data isolation. Covers where the client runs (browser vs server) and which key it uses (anon respects RLS, service_role bypasses it). Trigger with phrases like "supabase next.js", "supabase SSR", "supabase react native", "supabase SPA", "supabase serverless", "supabase multi-tenant", "supabase server component", "supabase architecture", "supabase service_role server".
allowed-tools
Read, Write, Edit, Bash(supabase:*), Bash(npx:*), Grep
version
1.53.0
license
MIT
author
Jeremy Longshore <jeremy@intentsolutions.io>
tags
["saas","supabase","architecture","nextjs","ssr","spa","mobile","multi-tenant","serverless"]
compatibility
Designed for Claude Code, also compatible with Codex and OpenClaw
# Supabase Architecture Variants ## Overview Every Supabase `createClient` configuration turns on two questions: **where the client runs** (browser vs server) and **which key it uses** (`anon` respects RLS; `service_role` bypasses it). This skill supplies production-ready patterns for five architectures — Next.js SSR, SPA, Mobile, Serverless Edge Functions, and Multi-tenant isolation. ## Prerequisites - `@supabase/supabase-js` v2+ installed - `@supabase/ssr` package for Next.js SSR (v0.5+) - Supabase project with URL, `anon` key, and `service_role` key - TypeScript project with generated database types (`supabase gen types typescript`) - For mobile: React Native with Expo or bare workflow ## Instructions Pick the architecture that matches the target stack, then follow the linked walkthrough for the full, copy-ready client setup. | Architecture | Client(s) | Key | Session storage | | -------------- | ----------- | ----- | ----------------- | | Next.js SSR | Server (cookies) + browser + admin | `anon` in-request, `service_role` server-only | HTTP cookies | | SPA (React/Vue) | Single browser client | `anon` only | `localStorage` | | Mobile (React Native) | Single native client | `anon` only | `AsyncStorage` | | Serverless (Edge Functions) | Per-request client | `anon` (forwarded JWT) or `service_role` | none (stateless) | | Multi-tenant | Any of the above | `anon` + RLS, or schema-per-tenant | per host pattern | ### Step 1 — Next.js SSR (App Router) Next.js App Router needs **two separate clients**: a server client that reads/writes auth cookies via `@supabase/ssr`, and a browser client for client components. A third `service_role` admin client is used only in Server Actions/Route Handlers and must **never** reach the browser. The browser client is the minimal skeleton: ```typescript // lib/supabase/client.ts 'use client' import { createBrowserClient } from '@supabase/ssr' import type { Database } from '../database.types' export function createSupabaseBrowser() { return createBrowserClient<Database>( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! // anon key only — respects RLS ) } ``` Full walkthrough — server client, admin client, middleware session refresh, server component usage, Server Actions, and the OAuth callback route: [Next.js SSR patterns](references/nextjs-ssr.md). ### Step 2 — SPA (React/Vue) and Mobile (React Native) SPAs and mobile apps both use a **single browser/native client with the `anon` key**; all authorization is enforced by RLS and the `service_role` key is never bundled. They differ only in session storage (`localStorage` for SPA, `AsyncStorage` for mobile) and OAuth handling (URL detection for SPA, deep links for mobile). Minimal SPA skeleton: ```typescript // src/lib/supabase.ts import { createClient } from '@supabase/supabase-js' import type { Database } from './database.types' export const supabase = createClient<Database>( import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_ANON_KEY, { auth: { autoRefreshToken: true, persistSession: true, detectSessionInUrl: true } } ) ``` Full walkthrough — SPA singleton + auth-state listener, React Query hooks, React Native `AsyncStorage` client, mobile OAuth with deep links, and Expo `app.json` config: [SPA and mobile patterns](references/spa-and-mobile.md). ### Step 3 — Serverless (Edge Functions) and Multi-Tenant Edge Functions create a **per-request** client from the forwarded JWT (stateless, no session persistence), escalating to `service_role` only for privileged operations. Multi-tenant isolation is either RLS-based (a `tenant_members` lookup gates every row) or schema-per-tenant. Full walkthrough — Edge Function per-request clients, admin escalation, RLS multi-tenant isolation, and tenant-scoped SDK queries: [serverless and multi-tenant patterns](references/serverless-and-multi-tenant.md). ## Output - Next.js SSR setup with server client (cookies-based auth), browser client, and middleware - Server Actions using admin client with `service_role` for privileged operations - SPA pattern with singleton client, React Query integration, and auth state listener - React Native setup with `AsyncStorage`, deep link OAuth, and in-app browser - Edge Function patterns for per-request auth and admin escalation - Multi-tenant RLS isolation with `tenant_members` lookup and scoped queries - Decision matrix for choosing the right architecture per stack ## Error Handling | Issue | Cause | Solution | | ------- | ------- | ---------- | | `AuthSessionMissingError` in Server Component | Cookies not passed to Supabase client | Use `createServerClient` from `@supabase/ssr` with cookie handlers | | OAuth redirect fails in React Native | Missing deep link scheme | Add `scheme` to app.json and configure Supabase redirect URL | | `service_role` key in client bundle | Wrong env var prefix (`NEXT_PUBLIC_`) | Remove `NEXT_PUBLIC_` prefix; only server code should access it | | Multi-tenant data leak | Missing RLS policy or missing `tenant_id` filter | Verify RLS is enabled and policies check `tenant_members` | | Edge Function `auth.getUser()` returns null | Missing Authorization header | Forward user's JWT from the client call | | Session not persisting on mobile | `AsyncStorage` not configured | Pass `AsyncStorage` in auth config; ensure package is installed | ## Examples Verify tenant isolation by impersonating a JWT and confirming RLS scopes the result: ```sql -- Test that RLS properly isolates tenants SET request.jwt.claims = '{"sub": "user-uuid-1"}'; -- Should only return projects for user-uuid-1's tenant SELECT * FROM public.projects; ``` More runnable examples — the Next.js OAuth callback route and further end-to-end flows: [Next.js SSR patterns](references/nextjs-ssr.md) and [examples](references/examples.md). ## Resources - [Supabase SSR (Next.js)](https://supabase.com/docs/guides/auth/server-side/nextjs) - [Supabase React Native](https://supabase.com/docs/guides/getting-started/tutorials/with-expo-react-native) - [Supabase Edge Functions](https://supabase.com/docs/guides/functions) - [Multi-Tenant with RLS](https://supabase.com/docs/guides/database/postgres/row-level-security) - [Supabase Auth Deep Linking](https://supabase.com/docs/guides/auth/native-mobile-deep-linking) - [@supabase/ssr Package](https://supabase.com/docs/guides/auth/server-side/overview) ## Next Steps After wiring the client for your architecture, review `supabase-known-pitfalls` for common mistakes and anti-patterns to avoid, then generate database types with `supabase gen types typescript` and enable RLS on every table before shipping.
GitHub에서 보기