Building a Multi-Tenant SaaS on a Single Supabase Database
How I run seven branded sites — one Next.js codebase, one Supabase project. A practical walkthrough of hostname resolution, feature flags, data isolation with RLS, and tenant-aware routing.
The Problem Multi-Tenant Architectures Solve#
The standard answer to "I need multiple branded sites" is multiple codebases — one repo per brand, each deployed separately. It works, but it scales poorly. Bug fixes get applied to three repos instead of one. A new feature requires four deployments. Shared logic drifts out of sync. The maintenance overhead compounds fast.
The alternative is a single codebase that resolves its identity at runtime from the incoming request. One deployment, one database, one set of tests — but any number of distinct front-ends.
I use this pattern across seven live production sites built on the ExpertSapiens platform: expertsapiens.com, mrvisakorea.com, apostillefirst.com, seoulhomes.kr, seoultranslate.com, airlinkee.com, and rehovica.com. Each looks, behaves, and ranks as its own brand. They share one Next.js codebase and one Supabase project.
This post covers how it's built.
Step 1: A Typed Tenant Config#
The foundation is a TenantConfig object — a fully typed description of what a tenant is and what it can do. Every piece of tenant-specific behavior flows from this object, not from environment variables or string comparisons scattered through the code.
export type TenantId =
| "expertsapiens"
| "apostillefirst"
| "mrvisakorea"
| "seoulhomes"
| "seoultranslate"
| "link"
| "rehovica";
export interface TenantConfig {
id: TenantId;
name: string;
baseUrl: string;
tagline: string;
categoryFilter: string[] | null;
: | ;
: [];
: | ;
: ;
: ;
: ;
: ;
}
Freelance
Precisa de ajuda com isso?
Posso ajudar com migrações, novos produtos e performance web.
Entrar em contato →