Set up Supabase Authentication in Lovable by using the built-in Lovable Cloud integration: enable auth methods in Cloud tab > Users & Auth, configure redirect URLs with your lovable.app domain, and use supabase.auth.signInWithPassword() for email/password or supabase.auth.signInWithOAuth() for Google/GitHub. Always set the Supabase Site URL to your published domain (not localhost), add all deployment URLs to the allowed redirect list, and enable Row Level Security on tables to restrict data access by user.
Why Supabase Auth requires careful configuration in Lovable
Supabase Authentication is deeply integrated into Lovable Cloud, but it still requires proper configuration to work without errors. The most common issues are redirect URL mismatches (the auth flow redirects to localhost instead of your app), missing or incorrect environment variables, and Row Level Security not being enabled on database tables. Lovable Cloud manages a Supabase instance for each project automatically. The connection details (URL, anon key) are pre-configured. But OAuth providers (Google, GitHub), email templates, and security policies need manual setup. This is because Lovable cannot create OAuth credentials on your behalf — you need to register your app with Google or GitHub yourself. The Site URL setting in Supabase is especially critical. By default, it is set to http://localhost:3000. If you forget to change it to your lovable.app URL, all auth redirects go to localhost, which appears as a blank page or connection error for users.
- Supabase Site URL still set to localhost instead of the published lovable.app domain
- OAuth redirect URLs do not include the lovable.app domain or use the wrong format
- Row Level Security (RLS) not enabled on database tables — all data is publicly accessible
- OAuth provider credentials (client ID, client secret) not configured in Supabase Dashboard
- Session persistence not handled — user is logged out on page refresh
Error messages you might see
Invalid API KeyThe Supabase anon key is missing or incorrect. Lovable Cloud should set this automatically. Check Cloud tab > Secrets for VITE_SUPABASE_PUBLISHABLE_KEY. If deploying externally, set it on your hosting platform.
OAuth redirecting to localhost instead of production URLThe Supabase Site URL is still set to http://localhost:3000. Change it to your published URL in Supabase Dashboard > Authentication > URL Configuration.
Service for this project is restricted due to the following violations: exceed_storage_size_quotaThe Supabase project has exceeded its storage quota, blocking all operations including auth. This persists even after upgrading. Contact Supabase support to resolve the quota violation.
User already registeredThe email address is already in the auth.users table. This is not an error — the user needs to sign in instead of signing up. Add a toggle between sign-up and sign-in modes in your form.
Before you start
- A Lovable project connected to Lovable Cloud (Supabase backend)
- The project published to lovable.app (for OAuth redirect URLs)
- Google Cloud Console or GitHub Developer Settings access (for OAuth providers)
How to fix it
Enable auth methods in Lovable Cloud
Auth methods must be explicitly enabled before users can sign up or sign in
Enable auth methods in Lovable Cloud
Auth methods must be explicitly enabled before users can sign up or sign in
Click the + button next to Preview and open the Cloud tab. Go to Users & Auth. Here you can see enabled auth providers. Email/password is typically enabled by default. To add Google or GitHub sign-in, you need to configure the provider in the Supabase Dashboard (accessible through the Cloud tab or directly at supabase.com). Enable the providers you need and enter the OAuth credentials (client ID and secret from Google Cloud Console or GitHub Developer Settings).
// No auth methods configured// Users cannot sign up or sign in// Auth methods enabled in Cloud tab > Users & Auth:// Email/password: enabled (default)// Google OAuth: enabled (client ID + secret configured)// Magic links: enabled (email templates configured)Expected result: Users can sign up and sign in using the enabled methods.
Set the Supabase Site URL and redirect URLs
OAuth flows redirect to the Site URL after authentication — if it points to localhost, users see a blank page
Set the Supabase Site URL and redirect URLs
OAuth flows redirect to the Site URL after authentication — if it points to localhost, users see a blank page
In the Supabase Dashboard (accessible through Cloud tab), go to Authentication > URL Configuration. Set the Site URL to your published URL: https://your-app.lovable.app. Under Redirect URLs, add: https://your-app.lovable.app/**, https://your-app.lovable.app/auth/callback. If you have a custom domain, add that too. The wildcard (**) ensures all paths are allowed as redirect targets.
// Supabase Dashboard > Authentication > URL Configuration:// Site URL: http://localhost:3000 (wrong!)// Redirect URLs: (empty)// Supabase Dashboard > Authentication > URL Configuration:// Site URL: https://your-app.lovable.app// Redirect URLs:// https://your-app.lovable.app/**// https://your-app.lovable.app/auth/callback// https://custom-domain.com/** (if applicable)Expected result: OAuth redirects go to your published app URL. Users see the app after signing in, not a blank page.
Implement sign-in and sign-up in your app
The auth UI connects your app to Supabase's auth system with the correct session handling
Implement sign-in and sign-up in your app
The auth UI connects your app to Supabase's auth system with the correct session handling
Create a login page with sign-in and sign-up forms. Use supabase.auth.signUp() for new users and supabase.auth.signInWithPassword() for existing users. For OAuth, use supabase.auth.signInWithOAuth() with the redirectTo option pointing to your app's callback URL. Listen for auth state changes with supabase.auth.onAuthStateChange() to update the UI when users sign in or out.
// No auth UI or session handling// Email/password sign in:const { data, error } = await supabase.auth.signInWithPassword({ email: email, password: password,});// Google OAuth sign in:const { data, error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: 'https://your-app.lovable.app/auth/callback', },});// Listen for auth state changes:supabase.auth.onAuthStateChange((event, session) => { if (session) { setUser(session.user); } else { setUser(null); }});Expected result: Users can sign in with email/password or Google. The app updates its UI based on auth state.
Enable Row Level Security on database tables
Without RLS, any user can read and modify any row in your database — a critical security vulnerability
Enable Row Level Security on database tables
Without RLS, any user can read and modify any row in your database — a critical security vulnerability
In the Supabase Dashboard, go to Table Editor and select each table. Enable RLS by toggling it on. Then add policies that restrict access based on the authenticated user. A common policy allows users to only read and modify their own rows: using (auth.uid() = user_id). Ask Lovable to set up RLS policies by prompting in Agent Mode. If configuring RLS policies across multiple tables with different access patterns gets complex, RapidDev's engineers have secured databases across 600+ Lovable projects.
// RLS disabled — all data publicly accessible// Any user can read or modify any other user's data// RLS enabled with user-scoped policies:// SELECT: users can only read rows where user_id = auth.uid()// INSERT: users can only insert rows with their own user_id// UPDATE: users can only update their own rows// DELETE: users can only delete their own rows// Prompt to Lovable:// 'Enable Row Level Security on the orders table.// Add policies so users can only see, create, update,// and delete their own orders (where user_id matches// the authenticated user ID).'Expected result: Each user can only access their own data. Unauthenticated requests are blocked entirely.
Complete code example
1import { useState } from "react";2import { useNavigate } from "react-router-dom";3import { supabase } from "@/integrations/supabase/client";4import { Button } from "@/components/ui/button";5import { Input } from "@/components/ui/input";67const Login = () => {8 const [email, setEmail] = useState("");9 const [password, setPassword] = useState("");10 const [isSignUp, setIsSignUp] = useState(false);11 const [loading, setLoading] = useState(false);12 const [error, setError] = useState("");13 const navigate = useNavigate();1415 const handleEmailAuth = async (e: React.FormEvent) => {16 e.preventDefault();17 setLoading(true);18 setError("");1920 const { error } = isSignUp21 ? await supabase.auth.signUp({ email, password })22 : await supabase.auth.signInWithPassword({ email, password });2324 if (error) {25 setError(error.message);26 } else {27 navigate("/dashboard");28 }29 setLoading(false);30 };3132 const handleGoogleSignIn = async () => {33 await supabase.auth.signInWithOAuth({34 provider: "google",35 options: {36 redirectTo: `${window.location.origin}/auth/callback`,37 },38 });39 };4041 return (42 <div className="flex items-center justify-center min-h-screen">43 <div className="w-full max-w-sm space-y-6 p-6">44 <h1 className="text-2xl font-bold text-center">45 {isSignUp ? "Create Account" : "Sign In"}46 </h1>4748 <form onSubmit={handleEmailAuth} className="space-y-4">49 <Input type="email" placeholder="Email" value={email} onChange={(e) => setEmail(e.target.value)} />50 <Input type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} />51 {error && <p className="text-sm text-destructive">{error}</p>}52 <Button type="submit" className="w-full" disabled={loading}>53 {loading ? "Loading..." : isSignUp ? "Sign Up" : "Sign In"}54 </Button>55 </form>5657 <Button variant="outline" className="w-full" onClick={handleGoogleSignIn}>58 Continue with Google59 </Button>6061 <p className="text-sm text-center text-muted-foreground">62 {isSignUp ? "Already have an account?" : "Don't have an account?"}{" "}63 <button className="text-primary underline" onClick={() => setIsSignUp(!isSignUp)}>64 {isSignUp ? "Sign In" : "Sign Up"}65 </button>66 </p>67 </div>68 </div>69 );70};7172export default Login;Best practices to prevent this
- Always set the Supabase Site URL to your published domain — never leave it as localhost
- Add all deployment URLs to Supabase's Redirect URLs with wildcard: https://your-app.lovable.app/**
- Enable Row Level Security on every table and add user-scoped policies
- Use supabase.auth.onAuthStateChange() to handle session persistence across page refreshes
- Store auth state in a React Context provider that wraps the entire app
- Use the redirectTo option in OAuth calls to ensure users return to the correct page
- Handle auth errors gracefully — show user-friendly messages, not raw error codes
- Test auth flows in an incognito window to avoid cached session interference
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am setting up Supabase Authentication in my Lovable project. I need: 1. Email/password sign-up and sign-in 2. Google OAuth sign-in 3. Session persistence across page refreshes 4. Protected routes that redirect to login 5. Row Level Security policies for my tables Here is my current setup: [describe your current auth state] Please create the complete auth implementation including AuthProvider, Login page, and RLS policies.
Set up Supabase Authentication for my app. Create @src/pages/Login.tsx with email/password sign-in and sign-up forms, plus a Google OAuth button. Create @src/components/AuthProvider.tsx that uses onAuthStateChange to track the user session and provides it via React Context. Create @src/components/ProtectedRoute.tsx that redirects to /login if the user is not authenticated. Wrap the app with AuthProvider in @src/App.tsx. Use the redirectTo option in OAuth calls with window.location.origin.
Frequently asked questions
How do I set up Supabase Auth in Lovable?
Enable auth methods in Cloud tab > Users & Auth. Set the Site URL in Supabase Dashboard to your published domain. Create a login page with signInWithPassword() for email and signInWithOAuth() for Google. Add an AuthProvider with onAuthStateChange for session persistence.
Why does OAuth redirect to localhost?
The Supabase Site URL is still set to the default http://localhost:3000. Change it in Supabase Dashboard > Authentication > URL Configuration to your published URL: https://your-app.lovable.app.
How do I keep users logged in after page refresh?
Use supabase.auth.onAuthStateChange() in your AuthProvider. This listener fires when the page loads and detects existing sessions. Supabase stores the session in localStorage and auto-refreshes tokens.
What is Row Level Security and why do I need it?
RLS restricts database access based on the authenticated user. Without it, any user can read and modify any data. Enable RLS on every table and add policies like: users can only access rows where user_id matches their auth ID.
Can I use magic links instead of passwords?
Yes. Use supabase.auth.signInWithOtp({ email }) to send a magic link. The user clicks the link in their email and is automatically signed in. Configure email templates in Supabase Dashboard > Authentication > Email Templates.
What if I can't fix this myself?
If your auth setup involves multiple OAuth providers, complex RLS policies, and session management across different environments, RapidDev's engineers can configure everything. They have set up Supabase Auth across 600+ Lovable projects.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your issue.
Book a free consultation