Search for custom domains and Supabase and you will find two completely different problems wearing the same name. Sorting out which one you have saves a lot of wasted effort, because the solutions do not overlap.
- A vanity project URL — you want
api.yourapp.cominstead ofabcdefgh.supabase.cofor your project's API and auth. Supabase does this. - End-user custom domains — you want your customers to each connect their own domain to the app you built on Supabase. Supabase does not do this.
Case 1 — A custom domain for your Supabase project
This rebrands your single project endpoint so auth links and API calls use your domain. It is a paid Custom Domains add-on, configured with the CLI:
supabase domains create \
--project-ref abcdefgh \
--custom-hostname api.yourapp.com
# then add the CNAME + TXT records it prints, and activate:
supabase domains activate --project-ref abcdefghYou add a CNAME for api.yourapp.com plus the verification TXT records Supabase returns, wait for validation, and activate. That is the whole feature — one hostname, your project. Verify the records with the CNAME checker.
Case 2 — Letting your users bring their own domains
This is the one people actually mean when they are building a multi-tenant product on Supabase, and it is not a Supabase feature. Supabase runs your database, auth, and APIs; it does not route app.yourcustomer.com to the right tenant or issue a certificate for it. That happens at your app's web edge.
You need three things, none of which Supabase provides:
- A certificate per customer hostname, issued on demand.
- Host-based routing that maps the domain to a tenant and fails closed on unknown hosts.
- Real client IP forwarding to your app.
Your Supabase queries stay exactly the same — you just scope them by the tenant you resolved from the host. The mechanics of doing this yourself are in the complete guide, and the framework-specific routing lives in guides like Next.js and Node/Express.
The one-API-call way
Put cnames.dev in front of your app (wherever it is hosted) and register each user's domain. SSL, routing, and forwarding are handled; your Supabase-backed app just reads the resolved tenant:
curl -X POST https://api.cnames.dev/v1/domains \
-H "Authorization: Bearer sk_live_..." \
-d '{"hostname":"app.customer.com","origin":"your-frontend.internal"}'This is the standard pattern for website builders built on Supabase. The production reality at scale is in how we run SSL for 5,000+ domains.