Skip to main content

Supabase Setup

Complete guide for setting up Supabase as your database and authentication provider for SvelteBolt.

Create Supabase Account​

  1. Go to supabase.com
  2. Click Start your project
  3. Sign up with GitHub, Google, or email
  4. Verify your email if required

Create New Project​

  1. Click + New Project
  2. Choose your organization (or create one)
  3. Fill in project details:
    • Name: sveltebolt-app (or your preferred name)
    • Database Password: Generate a strong password (save it!)
    • Region: Choose closest to your users
  4. Click Create new project
  5. Wait 2-3 minutes for setup to complete

Get API Keys​

Once your project is ready:

  1. Go to Project Settings → Data API and API Keys
  2. Copy these values to your .env file:
    PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co
    PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6...
    SUPABASE_SERVICE_ROLE_SECRET=eyJhbGciOiJIUzI1NiIsInR5cCI6...

Database Schema Setup​

SvelteBolt includes database migrations. Apply them to your Supabase project:

  1. Install Supabase CLI:

    npm install -g supabase
  2. Login to Supabase:

    supabase login
  3. Link your project:

    supabase link --project-ref your-project-id
  4. Apply migrations:

    supabase db push

Option 2: Manual SQL Setup​

  1. Go to your Supabase dashboard
  2. Navigate to SQL Editor
  3. Copy and run this SQL:
-- Create table for public profiles
create table public.profiles (
id uuid not null references auth.users on delete cascade,
name text,
avatar_url text,
bio text,
company_name text,
website text,
primary key (id)
);
-- Create table for subscriptions
create table public.subscriptions (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users on delete cascade,
customer_id text unique,
email text unique,
status text,
plan text,
interval text,
amount numeric(10, 2),
current_period_end timestamp with time zone,
cancel_at_period_end boolean,
updated_at timestamp with time zone
);
-- Create table for contact requests
create table public.contact_requests (
id uuid primary key default gen_random_uuid(),
name text,
email text,
message text,
created_at timestamp with time zone default now()
);
-- Enable Row Level Security
alter table public.profiles enable row level security;
alter table public.subscriptions enable row level security;
alter table public.contact_requests enable row level security;
--- Policies
CREATE POLICY "Can only view own profile data." ON public.profiles FOR
SELECT USING (auth.uid() = id);
--
CREATE POLICY "Can only update own profile data." ON public.profiles FOR
UPDATE USING (auth.uid() = id);
--
CREATE POLICY "Can only view own subscription" ON public.subscriptions FOR
SELECT TO authenticated USING (auth.uid() = user_id);
--
CREATE POLICY "Allow anyone to create contact requests" ON public.contact_requests FOR
INSERT TO authenticated,
anon WITH CHECK (true);
-- Create Function to create profile
CREATE FUNCTION public.create_profile() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER
SET search_path = public AS $$ BEGIN
INSERT INTO public.profiles (id, name, bio, avatar_url, company_name, website)
VALUES (
NEW.id,
NEW.raw_user_meta_data->>'name',
NEW.raw_user_meta_data->>'bio',
NEW.raw_user_meta_data->>'avatar_url',
NEW.raw_user_meta_data->>'company_name',
NEW.raw_user_meta_data->>'website'
);
RETURN NEW;
END;
$$;
-- Create Trigger to create profile
CREATE TRIGGER create_profile_trigger
AFTER
INSERT ON auth.users FOR each ROW EXECUTE PROCEDURE public.create_profile();
-- Create storage bucket for avatars
INSERT INTO storage.buckets (id, name, public)
VALUES ('avatars', 'avatars', true);
-- Allow authenticated users to insert files into the avatars bucket
CREATE POLICY "Allow authenticated users to insert files into avatars bucket" ON storage.objects FOR
INSERT WITH CHECK (
auth.uid() IS NOT NULL
AND bucket_id = 'avatars'
);
-- Allow authenticated users to update their own files in the avatars bucket
CREATE POLICY "Allow authenticated users to update their own files in avatars bucket" ON storage.objects FOR
UPDATE USING (
auth.uid() = owner
AND bucket_id = 'avatars'
);
-- Allow authenticated users to select their own files in the avatars bucket
CREATE POLICY "Allow authenticated users to select their own files in avatars bucket" ON storage.objects FOR
SELECT USING (
auth.uid() = owner
AND bucket_id = 'avatars'
);
-- Allow authenticated users to delete their own files in the avatars bucket
CREATE POLICY "Allow authenticated users to delete their own files in avatars bucket" ON storage.objects FOR DELETE USING (
auth.uid() = owner
AND bucket_id = 'avatars'
);
-- Create function to update subscription when a new user is created
-- This covers the case where a user subscribes before creating an account
CREATE OR REPLACE FUNCTION public.update_subscription_on_user_creation() RETURNS TRIGGER LANGUAGE plpgsql SECURITY DEFINER AS $$ BEGIN -- Update existing subscription with user_id if email matches
UPDATE public.subscriptions
SET user_id = NEW.id
WHERE email = NEW.email
AND user_id IS NULL;
RETURN NEW;
END;
$$;
-- Create trigger to call the function after user insertion
CREATE TRIGGER update_subscription_trigger
AFTER
INSERT ON auth.users FOR EACH ROW EXECUTE FUNCTION public.update_subscription_on_user_creation();

Enable Email Authentication​

  1. Go to Authentication → URL Configuration
  2. Under Site URL, add your domain:
    • Development: http://localhost:5173
    • Production: https://yourdomain.com
  3. Under Redirect URLs, add:
    • http://localhost:5173/api/auth/callback
    • https://yourdomain.com/api/auth/callback

Add Email Templates​

  1. Go to Authentication → Emails

Confirm signup​

<h2>Confirm your signup</h2>
<p>Follow this link to confirm your user:</p>
<p><a href="{{ .SiteURL }}/api/auth/confirm?token_hash={{ .TokenHash }}&type=email">Confirm your mail</a></p>

Password reset​

<h2>Reset Password</h2>

<p>Follow this link to reset the password for your user:</p>
<p>
<a
href="{{ .SiteURL }}/api/auth/confirm?token_hash={{ .TokenHash }}&type=recovery&next=/dashboard/settings/account/update-password"
>Reset Password</a
>
</p>
<h2>Magic Link</h2>

<p>Follow this link to login:</p>
<p><a href="{{ .SiteURL }}/api/auth/confirm?token_hash={{ .TokenHash }}&type=magiclink">Log In</a></p>

Configure Social Login (Optional)​

SvelteBolt comes pre-configured with Google, GitHub, and Twitter OAuth providers. To enable them:

Quick Setup​

  1. Go to Authentication → Providers in your Supabase dashboard
  2. Enable the providers you want to use
  3. Add your OAuth app credentials from each provider
  4. Use the redirect URL format: https://your-project-id.supabase.co/auth/v1/callback

Example: Google OAuth Setup​

  1. Go to Authentication → Providers
  2. Enable Google
  3. Add your Google OAuth credentials:
    • Client ID: From Google Cloud Console
    • Client Secret: From Google Cloud Console
  4. Add redirect URL to Google Cloud Console:
    • https://your-project-id.supabase.co/auth/v1/callback

Example: GitHub OAuth Setup​

  1. Enable GitHub in providers
  2. Add GitHub OAuth app credentials
  3. Set redirect URL in GitHub app settings

Adding More Providers​

SvelteBolt supports all Supabase OAuth providers including Discord, LinkedIn, Microsoft, and more.

📖 For detailed instructions on adding new OAuth providers, see the Authentication Guide

Test Database Connection​

  1. Start your SvelteBolt development server:

    bun run dev
  2. Visit http://localhost:5173

  3. Try signing up with an email

  4. Check your Supabase dashboard → Authentication → Users

  5. Verify the user appears and a profile is created

Production Considerations​

  • Backups: Enable automatic backups in project settings
  • Database Size: Monitor usage in dashboard
  • Rate Limiting: Configure in project settings
  • Custom Domain: Set up custom domain for auth emails
  • Environment: Use separate projects for dev/staging/prod

Troubleshooting​

Connection Issues:

  • Verify API keys are correct
  • Check project is not paused
  • Ensure database password is correct

Authentication Issues:

  • Verify redirect URLs are configured
  • Check email templates are enabled
  • Confirm site URL matches your domain

Migration Issues:

  • Run migrations one at a time if errors occur
  • Check for syntax errors in SQL
  • Verify you have proper permissions

Next Steps​