Skip to content
Launch Kit logo

Connect

Supabase

Create the project, paste three keys, enable Google and magic links, and add the profiles table the kit already queries.

Launch Kit uses Supabase for auth and Postgres. Sessions are cookies via @supabase/ssr. Middleware refreshes them. You do not replace libs/supabase.

Keys

Create a project at supabase.com. In Project Settings → API:

CredentialEnv varUsed by
Project URLNEXT_PUBLIC_SUPABASE_URLBrowser, server, middleware
anon public keyNEXT_PUBLIC_SUPABASE_ANON_KEYSame, with the user session
service_role secret keySUPABASE_SERVICE_ROLE_KEYStripe webhook only. Bypasses RLS

Auth providers

In Authentication → Providers:

  1. Enable Email. Magic links use signInWithOtp from /signin.
  2. Enable Google. Add the Google client ID and secret from Google Cloud.

Redirect URL the kit already uses:

text
http://localhost:3000/api/auth/callback

Add the production URL when you deploy: https://your-domain.com/api/auth/callback. Also add both origins under Authentication → URL Configuration.

Profiles table

Checkout, the billing portal, and the webhook all read a profiles table. It is not created for you. Run this in the SQL editor:

sql
create table public.profiles (
  id uuid primary key references auth.users (id) on delete cascade,
  email text,
  customer_id text,
  price_id text,
  has_access boolean not null default false,
  created_at timestamptz not null default now()
);

alter table public.profiles enable row level security;

create policy "Users can read their own profile"
  on public.profiles
  for select
  using (auth.uid() = id);

create policy "Users can update their own profile"
  on public.profiles
  for update
  using (auth.uid() = id);

create function public.handle_new_user()
returns trigger
language plpgsql
security definer
set search_path = public
as $$
begin
  insert into public.profiles (id, email)
  values (new.id, new.email);
  return new;
end;
$$;

create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();
ColumnWho writes itWhy
idAuth triggerMatches auth.users.id
emailAuth triggerGuest checkout lookup
customer_idStripe webhookBilling portal and subscription events
price_idStripe webhookInvoice / plan match
has_accessStripe webhookPaid access flag. Gate your product on this

The webhook can also create an auth user for guest checkout. The trigger still inserts the profile row.

What the kit already does

  • Server: await createClient() from @/libs/supabase/server
  • Browser: createClient() from @/libs/supabase/client
  • /dashboard redirects guests to config.auth.loginUrl
  • /api/auth/callback exchanges the code and sends the user to config.auth.callbackUrl

Protect another route by copying app/dashboard/layout.tsx. See Authentication.