← All components
Supabase Auth Pages (Login + Callback)
Adds a /login page (email magic link) styled with shadcn/ui Button, and the /auth/callback route handler that exchanges the OAuth/magic-link code for a session.
Copy the files below, or open this folder on GitHub. Each file is stamped with a limited-use licence, generator and date. SHA-256 is of the published catalog bytes, before the stamp.
- id
- supabase-auth-ui
- stack
- Next.js
- version
- 1.1.0
- compatibility
- nextjs >=16 <17 · react >=19 <20
- requires
- supabase-client, shadcn-ui
- env vars
- —
Verified passing · daily buildIntegrity sha256:e7fe10fcd959a1e4…
Files (2)
app/login/page.tsx · sha256:e7fe10fcd959a1e4…
// Licensed by BotKelp — https://www.botkelp.com
'use client';
import { useState, type FormEvent } from 'react';
import { useSupabase } from '@/components/supabase-provider';
import { Button } from '@/components/ui/button';
export default function LoginPage() {
const supabase = useSupabase();
const [email, setEmail] = useState('');
const [status, setStatus] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle');
async function handleSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault();
setStatus('sending');
const { error } = await supabase.auth.signInWithOtp({
email,
options: { emailRedirectTo: `${window.location.origin}/auth/callback` },
});
setStatus(error ? 'error' : 'sent');
}
return (
<main className="mx-auto flex min-h-screen max-w-sm flex-col justify-center gap-4 p-6">
<h1 className="text-2xl font-semibold">Sign in</h1>
<form onSubmit={handleSubmit} className="flex flex-col gap-3">
<input
type="email"
required
value={email}
onChange={(event) => setEmail(event.target.value)}
placeholder="you@example.com"
className="rounded-md border border-slate-200 px-3 py-2"
/>
<Button type="submit" disabled={status === 'sending'}>
{status === 'sending' ? 'Sending link…' : 'Send magic link'}
</Button>
</form>
{status === 'sent' && <p className="text-sm text-slate-600">Check your email for a login link.</p>}
{status === 'error' && <p className="text-sm text-red-600">Something went wrong. Try again.</p>}
</main>
);
}