Supabase Setup
Complete guide for setting up Supabase as your database and authentication provider for SvelteBolt.
Create Supabase Account
- Go to supabase.com
- Click Start your project
- Sign up with GitHub, Google, or email
- Verify your email if required
Create New Project
- Click + New Project
- Choose your organization (or create one)
- 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
- Name:
- Click Create new project
- Wait 2-3 minutes for setup to complete
Get API Keys
Once your project is ready:
- Go to Project Settings → Data API and API Keys
- 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:
Option 1: Using Supabase CLI (Recommended)
-
Install Supabase CLI:
npm install -g supabase
-
Login to Supabase:
supabase login
-
Link your project:
supabase link --project-ref your-project-id
-
Apply migrations:
supabase db push
Option 2: Manual SQL Setup
- Go to your Supabase dashboard
- Navigate to SQL Editor
- 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
- Go to Authentication → URL Configuration
- Under Site URL, add your domain:
- Development:
http://localhost:5173
- Production:
https://yourdomain.com
- Development:
- Under Redirect URLs, add:
http://localhost:5173/api/auth/callback
https://yourdomain.com/api/auth/callback
Add Email Templates
- 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>
Magic link
<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
- Go to Authentication → Providers in your Supabase dashboard
- Enable the providers you want to use
- Add your OAuth app credentials from each provider
- Use the redirect URL format:
https://your-project-id.supabase.co/auth/v1/callback
Example: Google OAuth Setup
- Go to Authentication → Providers
- Enable Google
- Add your Google OAuth credentials:
- Client ID: From Google Cloud Console
- Client Secret: From Google Cloud Console
- Add redirect URL to Google Cloud Console:
https://your-project-id.supabase.co/auth/v1/callback
Example: GitHub OAuth Setup
- Enable GitHub in providers
- Add GitHub OAuth app credentials
- 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
-
Start your SvelteBolt development server:
bun run dev
-
Visit
http://localhost:5173
-
Try signing up with an email
-
Check your Supabase dashboard → Authentication → Users
-
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
- Configure Stripe payments
- Add more OAuth providers
- Explore environment variables
- Review the [project structure](/Getting Started/project-structure)