Skip to main content
RapidDev - Software Development Agency
App Featuresauth-security20 min read

How to Add Social Login to Your App — Copy-Paste Prompts Included

Social login means a user clicks 'Sign in with Google' and Supabase Auth handles the OAuth handshake, creates the account, and returns a session — no password required. With Lovable or V0 you can have Google and GitHub login working in 1–2 hours for $0/month. Google OAuth is free, GitHub OAuth is free, and Apple Sign In requires an Apple Developer account ($99/yr) but has no per-login charge.

4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members

Feature spec

Beginner

Category

auth-security

Build with AI

1–2 hours with Lovable or V0

Custom build

2–3 days custom dev

Running cost

$0/mo (Google + GitHub); $99/yr if Apple Sign In enabled

Works on

Web

Everything it takes to ship Social Login — parts, prompts, and real costs.

TL;DR

Social login means a user clicks 'Sign in with Google' and Supabase Auth handles the OAuth handshake, creates the account, and returns a session — no password required. With Lovable or V0 you can have Google and GitHub login working in 1–2 hours for $0/month. Google OAuth is free, GitHub OAuth is free, and Apple Sign In requires an Apple Developer account ($99/yr) but has no per-login charge.

What Social Login Actually Does in Your App

Social login delegates authentication to a provider the user already trusts — Google, GitHub, or Apple. When a user clicks 'Sign in with Google', your app redirects to Google's login page, the user approves access, and Google redirects back to your /auth/callback route with a one-time code. Supabase Auth exchanges that code for a session token and creates (or retrieves) an auth.users row. The user never sets a password with your app. The product decision is which providers to offer: Google covers 90% of consumer use cases, GitHub covers developer-focused tools, and Apple is required if you plan to list on the iOS App Store. Each provider has its own credential setup in their respective developer consoles before any Lovable or V0 prompt can make it work.

What users consider table stakes in 2026

  • One-click sign-in per provider with a branded button following provider guidelines exactly (Google: white button with G icon, Apple: black button with Apple logo)
  • No password required for social-connected accounts — the provider identity is the credential
  • Avatar and display name pre-filled from the OAuth provider profile on first sign-in
  • Account linking when the same email is registered via two providers — not two separate accounts
  • Connected accounts section in profile settings so users can see and revoke linked providers
  • Graceful error state when the user closes the OAuth popup before completing — not a broken page

Anatomy of the Feature

Six components. Supabase Auth handles the heavy OAuth lifting — your work is the UI buttons, the callback handler, and the profile auto-fill on first login.

Layers:UIBackendService

Supabase Auth OAuth

Backend

supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: 'https://yourapp.com/auth/callback' } }) initiates the OAuth flow. Supabase handles the PKCE challenge, provider redirect, token exchange, and session creation. On first sign-in from a new provider, Supabase creates a row in auth.users and fires any configured auth triggers.

Note: The redirectTo URL must exactly match one of the allowed redirect URLs configured in Supabase Dashboard → Authentication → Redirect URLs. A mismatch silently returns a 400 error with no indication of which URL is wrong.

OAuth provider credentials

Service

Each provider requires developer credentials registered in their console: Google (Google Cloud Console → APIs & Services → Credentials → OAuth 2.0 Client ID), GitHub (Settings → Developer Settings → OAuth Apps), Apple (Apple Developer account → Certificates → Services IDs + private key). Credentials are stored in Supabase Dashboard → Authentication → Providers — never in your app code.

Note: Apple Sign In is the most complex: requires a $99/yr Apple Developer account, a Services ID (not just an App ID), a Key ID, and a Team ID. Budget an extra hour for Apple-specific setup compared to Google or GitHub.

Social login buttons

UI

One button per provider using the provider's official brand assets. Google requires the exact G logo and white background per their brand guidelines. Apple requires black background with the Apple logo. GitHub uses the Octicon mark. Built with shadcn/ui Button plus SVG icons inline. Never use a generic 'Sign in with Social' button — provider guidelines prohibit it and users distrust unlabeled buttons.

Note: Google's brand guidelines are the strictest: the button text must say exactly 'Sign in with Google' (not 'Login with Google'), and the Google G must appear on a white chip inside the button. Violating this can result in OAuth app suspension on review.

OAuth redirect handler

UI

A /auth/callback route (page in Next.js App Router, or path in Lovable's React Router) that receives the OAuth code from the provider redirect. It calls supabase.auth.exchangeCodeForSession() to trade the code for a Supabase session, then redirects the user to /dashboard or the original page they tried to access before login.

Note: Store the originally requested URL in sessionStorage before triggering OAuth so you can redirect back after the callback. Without this, all social logins dump users on /dashboard even if they were trying to reach a specific page.

Profile auto-fill

Backend

supabase.auth.onAuthStateChange() fires on sign-in and provides user.user_metadata containing name, avatar_url, email, and provider-specific fields from the OAuth token. On first sign-in (check user.created_at within the last few seconds), insert a row into the profiles table populated from user_metadata. On subsequent logins, update the avatar_url to keep it fresh since Google's signed URLs expire.

Note: Detect first sign-in by checking profiles table for the user_id before inserting. A Supabase database trigger (auth.users insert → profiles insert) is more reliable than relying on the client-side onAuthStateChange handler, which may not fire if the browser tab is closed mid-redirect.

Account linking (multi-provider)

Backend

Supabase Auth automatically links providers to the same account when the email address matches — a user who signed up with email/password and then clicks 'Sign in with Google' using the same email gets linked, not a duplicate account. The user.identities[] array tracks all linked providers. Expose a 'Connected accounts' section in profile settings showing each linked provider with an unlink button.

Note: Account linking must be enabled in Supabase Dashboard → Authentication → Settings. Without it, a user who registered with email/password and then tries Google OAuth with the same email gets a 'User already exists' error.

The data model

A profiles table stores display name and avatar, and an optional user_providers table tracks linked OAuth accounts for the 'Connected accounts' UI. Run this in the Supabase SQL editor:

schema.sql
1create table public.profiles (
2 id uuid primary key references auth.users(id) on delete cascade,
3 display_name text,
4 avatar_url text,
5 provider text,
6 created_at timestamptz not null default now(),
7 updated_at timestamptz not null default now()
8);
9
10alter table public.profiles enable row level security;
11
12create policy "Users can view own profile"
13 on public.profiles for select
14 using (auth.uid() = id);
15
16create policy "Users can update own profile"
17 on public.profiles for update
18 using (auth.uid() = id);
19
20create policy "Users can insert own profile"
21 on public.profiles for insert
22 with check (auth.uid() = id);
23
24-- Optional: track linked providers for 'Connected accounts' UI
25create table public.user_providers (
26 id uuid primary key default gen_random_uuid(),
27 user_id uuid references auth.users(id) on delete cascade not null,
28 provider text not null,
29 provider_user_id text,
30 linked_at timestamptz not null default now(),
31 unique (user_id, provider)
32);
33
34alter table public.user_providers enable row level security;
35
36create policy "Users can view own providers"
37 on public.user_providers for select
38 using (auth.uid() = user_id);
39
40-- Trigger to auto-create profile on new user
41create or replace function public.handle_new_user()
42returns trigger language plpgsql security definer set search_path = public
43as $$
44begin
45 insert into public.profiles (id, display_name, avatar_url, provider)
46 values (
47 new.id,
48 new.raw_user_meta_data ->> 'full_name',
49 new.raw_user_meta_data ->> 'avatar_url',
50 new.raw_app_meta_data ->> 'provider'
51 )
52 on conflict (id) do nothing;
53 return new;
54end;
55$$;
56
57create trigger on_auth_user_created
58 after insert on auth.users
59 for each row execute procedure public.handle_new_user();

Heads up: The database trigger is more reliable than client-side profile creation — it fires even if the user's browser closes during the OAuth redirect. The on conflict (id) do nothing ensures re-runs are safe.

Build it — pick your path

Each tool fits this feature differently. Switch tabs to compare fit, time, the exact steps, and a copy-paste prompt.

Full-stack, non-technical friendlyFit for this feature:

Fastest path to working social login. Lovable generates the OAuth buttons, callback handler, and profile auto-fill from a single prompt. Only manual step is adding OAuth credentials in the provider consoles and the Supabase Dashboard.

Step by step

  1. 1Set up Google OAuth credentials: go to console.cloud.google.com → APIs & Services → Credentials → Create OAuth 2.0 Client ID; set Authorized redirect URI to your Lovable published URL + /auth/callback
  2. 2Set up GitHub OAuth app: go to github.com → Settings → Developer Settings → OAuth Apps → New OAuth App; set Authorization callback URL to your published URL + /auth/callback
  3. 3In Supabase Dashboard → Authentication → Providers, enable Google (paste Client ID and Secret) and GitHub (paste Client ID and Secret); add your published URL to Redirect URLs
  4. 4Paste the prompt below into Lovable Agent Mode and let it generate the login page, callback route, and profile creation
  5. 5Click Publish and test OAuth on the published URL — never in the preview iframe
Paste into Lovable
Add social login to this app using Supabase Auth. On the login and registration pages, add a 'Sign in with Google' button (white background, Google G icon, correct Google brand guidelines) and a 'Sign in with GitHub' button (dark background, GitHub Octicon icon). Both buttons call supabase.auth.signInWithOAuth with the correct provider and redirectTo set to the production URL plus /auth/callback. Create a /auth/callback page that calls supabase.auth.exchangeCodeForSession() and then redirects to /dashboard. On first sign-in from any OAuth provider, auto-create a profiles table row with display_name and avatar_url taken from user.user_metadata. In the user profile settings page, add a 'Connected accounts' section that shows which OAuth providers are currently linked to the account. Add an error state for when the user closes the OAuth popup before completing: show a dismissible banner 'Sign-in cancelled — please try again'. Include a note in the UI to remind users and developers that OAuth only works on the published URL, not in the preview.

Where this path bites

  • OAuth completely fails in the Lovable preview iframe — you must test on the published URL; this is not a bug in the generated code
  • Redirect URL in Supabase Auth and in each OAuth app must be updated to match your custom domain after publishing — this step is manual and easy to miss
  • Apple OAuth requires an Apple Developer account ($99/yr) and significantly more setup than Google or GitHub — prompt for it separately only when needed

Third-party services you'll need

Social login costs nothing at the OAuth level. You only pay for Supabase once you need production SLA, and Apple if you add Apple Sign In:

ServiceWhat it doesFree tierPaid from
Google OAuth (Google Identity API)Sign in with Google — handles identity verification and returns user profile with name, email, avatarFree — no per-sign-in charge; requires a Google Cloud project (also free) and OAuth 2.0 credentialsFree
GitHub OAuthSign in with GitHub — ideal for developer-facing tools; returns GitHub username, avatar, and emailFree — register an OAuth App under GitHub Settings → Developer SettingsFree
Apple Sign InRequired for iOS App Store listings; Apple provides a privacy relay email option that hides the user's real addressNo per-sign-in charge$99/yr Apple Developer Program membership required for credentials
Supabase AuthManages OAuth token exchange, user creation, session management, and provider linking across all OAuth providersAll OAuth providers included in free tier (50K MAU)Pro $25/mo (100K MAU + production uptime SLA)

Swipe the table sideways to see pricing.

What it costs to run

Drag through the tiers to see how your monthly bill scales with users — no surprises later.

Estimated monthly running cost

$0/mo

All OAuth providers are free per-sign-in; Supabase free tier covers 50K MAU comfortably; Apple Developer Program is a one-time $99/yr if Apple login is added

Estimates use verified 2026 pricing and assume typical usage per user. Your real bill depends on activity, storage, and third-party plans.

What breaks when AI tools build this

The failures people actually hit on their first build — the symptom, why it happens, and the exact fix.

OAuth redirect fails in Lovable and V0 preview

Symptom: signInWithOAuth() opens a redirect to the provider's login page and expects to return to your /auth/callback route at a publicly registered URL. The Lovable preview iframe runs on a dynamic sandbox subdomain that is not registered as a valid OAuth redirect URI. Google and GitHub return an error before the user even sees a login prompt.

Fix: Test OAuth exclusively on the published Lovable URL or the deployed Vercel URL. In Lovable, click Publish first, then open the live URL in a new browser tab. In V0, deploy to Vercel before running any OAuth test. Add a note in the Lovable project description so you do not forget this after the next session.

redirect_uri_mismatch after deploying to a custom domain

Symptom: When you connect a custom domain (yourdomain.com) to Lovable or Vercel, the OAuth callback URL changes. The Google Cloud Console and Supabase Dashboard still have your previous URL (*.lovable.app or *.vercel.app) as the authorized redirect. Every social login attempt returns a 400 redirect_uri_mismatch error.

Fix: After every domain change, update two places: (1) Supabase Dashboard → Authentication → Redirect URLs — add the new callback URL; (2) each OAuth provider console (Google Cloud, GitHub Developer Settings) — add the new authorized redirect URI. Both must be updated for each provider. Keep the old URLs too so existing sessions are not broken.

Same email from two providers creates duplicate accounts

Symptom: A user registered with email/password, then clicks 'Sign in with Google' using the same email address. If the 'Link providers' setting is not enabled in Supabase, Supabase creates a second auth.users row with the same email. The user now has two separate accounts and their data is split between them.

Fix: Enable 'Automatically link identities' in Supabase Dashboard → Authentication → Settings. With this enabled, signing in with a new provider that matches an existing email attaches the new identity to the existing user record rather than creating a duplicate. Test this edge case explicitly before launch by registering with email first and then signing in with Google.

Apple Sign In privacy relay email breaks profile creation

Symptom: Apple lets users hide their real email and provides a randomized @privaterelay.appleid.com address instead. Any profile creation logic that validates email domain format or rejects non-standard domains will reject Apple users. Apple's privacy relay also means you cannot use email as a stable identifier for Apple accounts.

Fix: Accept @privaterelay.appleid.com as a valid email address — never validate email domains on account creation. Store Apple's stable user ID (from user.identities[0].id) separately as the primary identifier for Apple users rather than relying on email. Test Apple Sign In with both the 'Share email' and 'Hide email' options to verify both code paths work.

Google avatar URL expires and breaks profile pictures

Symptom: Google OAuth returns a profile picture URL that is a signed Google CDN link. These links expire. Storing the URL at first sign-in and never updating it means profile pictures show as broken images within days to weeks.

Fix: On every sign-in event (not just first sign-in), update avatar_url in the profiles table with the latest value from user.user_metadata.avatar_url. Alternatively, download and re-upload the image to Supabase Storage on first sign-in — you then own the URL and it never expires. The onAuthStateChange handler is the right place to trigger this update.

Best practices

1

Offer Google as the first and most prominent social login — it covers the broadest user base and has the simplest setup

2

Register OAuth credentials in provider consoles before generating any code — you need the Client ID and Secret to configure Supabase Auth, and the Supabase redirect URL to configure the OAuth app

3

Store the user's intended destination in sessionStorage before triggering OAuth so you can redirect them back to the right page after the callback completes

4

Use a Supabase database trigger to create the profiles row on new user creation rather than relying on client-side onAuthStateChange — the trigger fires even if the browser tab closes mid-redirect

5

Keep old redirect URLs in Supabase and OAuth app settings when adding a new domain — removing them breaks existing sessions

6

Implement a 'Connected accounts' UI so users can see which providers are linked and optionally unlink them — users who switch from Google to email/password need a way to manage this

7

For Apple Sign In, always test both the 'Share my email' and 'Hide my email' flows — they produce different user objects and both must work

When You Need Custom Social Login Development

Lovable and V0 handle standard identity-only OAuth flows (sign in, get name and avatar) with one prompt. Custom development is needed when OAuth becomes a data integration, not just an auth mechanism:

  • You need custom OAuth scopes to access provider APIs on behalf of the user — Google Calendar read, GitHub repository write, Slack workspace data — requiring server-side token storage, refresh logic, and scope management
  • Multi-tenant architecture where different client organizations use different OAuth app credentials, requiring per-workspace credential routing at the auth layer
  • Provider access token must be stored and refreshed for server-side API calls hours or days after the user's session — a full token lifecycle management system beyond what the standard Supabase session covers
  • SAML or enterprise SSO via Okta, Azure AD, or a corporate identity provider — a fundamentally different protocol from OAuth that requires a separate integration layer

RapidDev builds these features for production

Real auth, database, and payments — fixed price, delivered in weeks. You own 100% of the code.

Get a fixed-price quote

Frequently asked questions

Do I need Google's permission to add 'Sign in with Google'?

You need to register an OAuth 2.0 client in Google Cloud Console, but this is a self-service process that takes about 10 minutes and is free. You do not need Google's approval for standard identity-only OAuth (sign in, get name and email). If you request sensitive scopes beyond identity — like Google Drive or Gmail access — Google requires an OAuth verification review, which can take weeks.

What is the easiest social login to add — Google or GitHub?

Both take about 10 minutes to configure in their respective consoles. Google has stricter button branding requirements. GitHub's setup is slightly simpler because there is no project or API enablement step — just create an OAuth App in Developer Settings. For a developer-facing tool, GitHub is often more meaningful to users; for a consumer app, Google reaches more people.

Can a user have both a password and social login?

Yes. Supabase Auth supports multiple identities per user. A user can sign up with email/password and later link their Google account, or vice versa. With 'Automatically link identities' enabled in Supabase Dashboard, signing in with Google after registering with the same email automatically links both methods to a single account.

What happens to a user's data if they revoke OAuth access?

Revoking OAuth access in Google or GitHub removes that provider's ability to issue new tokens — but it does not delete the user's account or data in your app. Their Supabase auth.users row and all associated data remain intact. The user simply cannot sign in with that provider anymore until they re-authorize. Add a fallback path (email/password or another linked provider) so they do not get locked out.

Is Apple Sign In required if I want to list my app on the App Store?

If your app offers any third-party social login (Google, Facebook, etc.), Apple requires you to also offer Sign in with Apple when submitting to the App Store. This is Apple's policy for native iOS apps. For web apps accessed through a mobile browser, Apple Sign In is optional. Budget extra time for Apple setup — it requires a $99/yr Developer account, a Services ID, and a private key.

How do I add more OAuth providers later without breaking existing accounts?

Adding a new provider to Supabase Auth does not affect existing accounts. Enable the new provider in Supabase Dashboard → Authentication → Providers, configure credentials, and add the new button to your login page. Existing users can link the new provider from their profile settings. The only risk is if you fail to handle the case where a new provider returns the same email as an existing account — ensure 'link identities' is enabled to prevent duplicates.

Can I get the user's Google profile picture?

Yes. After sign-in, user.user_metadata.avatar_url contains the Google profile picture URL. Store it in your profiles table. Be aware that Google's CDN URLs expire — update the avatar_url on each subsequent sign-in event from onAuthStateChange to keep it fresh, or copy the image to Supabase Storage on first sign-in so you control the URL permanently.

What are Google's brand guidelines for the sign-in button?

Google requires: button text must say exactly 'Sign in with Google' (not 'Login with Google'); the Google G logo must appear in full color on a white or light chip; the button must be at least 40px tall; do not distort or recolor the G logo. Violations can result in your OAuth app being flagged during Google's periodic review. Lovable and V0 both generate compliant buttons from the prompts on this page.

RapidDev

Need this feature production-ready?

RapidDev builds social login into real apps — auth, database, payments — at $13K–$25K.

Book a free consultation

30-min call. No commitment.

Want this built for you?

We ship production apps at a fixed price — $13K–$25K, 6–10 weeks, source code yours. You've seen what it takes; we do it every week.

Get a fixed-price quote

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.