Your Clerk-Supabase sync is already implemented! The code automatically creates a Supabase user when someone logs in with Clerk.
When a user logs in via Clerk:
- Clerk authenticates the user (Google, email, etc.)
- Frontend calls
syncUserFromClerk()automatically - Supabase creates a user record with:
clerk_user_id: Clerk's user IDemail: User's emailname: User's full nameavatar_url: Profile picturerole: Defaults to 'learner'points: Starts at 0level: Starts at 'beginner'
Open your .env file and add:
# Clerk Configuration (Vite uses VITE_ prefix)
VITE_CLERK_PUBLISHABLE_KEY=pk_test_YOUR_KEY_HERE
# Supabase Configuration (you already have these)
VITE_SUPABASE_URL=https://oxyaqkxmqoyhqtmsmdhk.supabase.co
VITE_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Get your Clerk key from:
- Go to https://dashboard.clerk.com
- Select your application
- Click API Keys in sidebar
- Copy the Publishable Key (starts with
pk_test_orpk_live_)
The sync requires the users table to exist in Supabase:
./deploy-backend.shOr manually via Supabase Dashboard → SQL Editor → Run the migration files.
After updating .env:
# Stop current server (Ctrl+C)
# Then restart:
npm run devThe sync happens automatically. Here's what occurs:
- User clicks "Sign In"
- Clerk authentication popup appears
- User logs in with Google (or email)
- Auto-sync happens ✨
- User record created in Supabase
userstable - User can now upload videos, complete quizzes, earn points
- User logs in via Clerk
- Sync checks if user exists in Supabase
- If exists: Returns existing user
- If not: Creates new user
The sync is already implemented in multiple places:
Dashboard.tsx:
const { data: dbUser } = useQuery({
queryKey: ['user', clerkUser?.id],
queryFn: async () => {
return syncUserFromClerk(
clerkUser.id,
clerkUser.emailAddresses[0]?.emailAddress,
clerkUser.fullName || 'User',
clerkUser.imageUrl
);
},
});Upload.tsx:
// Same sync happens here tooVideoPlayer.tsx:
// And here!- Go to https://supabase.com/dashboard
- Select your project
- Click Table Editor → users
- Log in to your app with Clerk
- Refresh the users table → You should see a new row!
- Open your app
- Open DevTools (F12)
- Go to Console tab
- Log in
- You should see no errors related to user sync
- Log in
- Go to Upload page (/upload)
- If you see the form (not "Not authenticated"), sync worked!
- Solution: Wait 1-2 seconds after login for sync to complete
- The upload page now shows "Syncing account..." while this happens
- Solution: Deploy migrations (
./deploy-backend.sh) - Or manually run migrations in Supabase SQL Editor
- Check: Is .env file saved?
- Check: Did you restart npm run dev?
- Check: Is VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY correct?
- Check: Is VITE_CLERK_PUBLISHABLE_KEY in .env?
- Check: Did you restart dev server after adding it?
- Check: Is the key the Publishable Key (not Secret Key)?
The sync uses:
- Clerk for authentication (secure, handled by Clerk)
- Supabase Anon Key for database writes (protected by RLS policies)
- Row Level Security ensures users can only modify their own data
| Clerk Field | Supabase Column | Default Value |
|---|---|---|
user.id |
clerk_user_id |
(from Clerk) |
emailAddresses[0].emailAddress |
email |
(from Clerk) |
fullName or firstName |
name |
'User' |
imageUrl |
avatar_url |
(from Clerk) |
| - | role |
'learner' |
| - | points |
0 |
| - | level |
'beginner' |
| - | streak_count |
0 |
- Add your Clerk key to
.env - Restart
npm run dev - Try logging in
- Check Supabase → users table to see your user!
The sync is automatic - you don't need to do anything else! 🚀