Email Login
Add passwordless email login to your app. Users receive a magic link with no passwords to remember and no password resets to handle.
How It Works
Section titled “How It Works”- User enters their email address
- They receive a magic link via email
- Clicking the link logs them in
- Session is maintained across page refreshes
No password storage, no forgotten password flows, no security vulnerabilities from weak passwords.
Quick Setup
Section titled “Quick Setup”-
Set up your auth provider
app/layout.tsx import { PrivyStack } from '@varity-labs/ui-kit';export default function RootLayout({ children }) {return (<html><body><PrivyStack loginMethods={['email']}>{children}</PrivyStack></body></html>);} -
Add the login button
components/LoginButton.tsx import { PrivyLoginButton } from '@varity-labs/ui-kit';export function LoginButton() {return (<PrivyLoginButton>Sign in with Email</PrivyLoginButton>);}
Custom Login Button
Section titled “Custom Login Button”Build your own login button using the usePrivy hook:
import { usePrivy, useLogin } from '@varity-labs/ui-kit';
export function CustomEmailLogin() { const { ready, authenticated } = usePrivy(); const { login } = useLogin();
if (!ready) { return <button disabled>Loading...</button>; }
if (authenticated) { return <span>Already logged in</span>; }
return ( <button onClick={login} className="bg-blue-600 text-white px-4 py-2 rounded-lg" > Continue with Email </button> );}Accessing User Email
Section titled “Accessing User Email”After login, access the user’s email from the user object:
import { usePrivy } from '@varity-labs/ui-kit';
export function UserProfile() { const { user } = usePrivy();
if (!user) return null;
return ( <div> <p>Email: {user.email?.address}</p> <p>Verified: {user.email?.verified ? 'Yes' : 'No'}</p> </div> );}Email Login Flow
Section titled “Email Login Flow”The typical user experience:
1. User clicks "Sign in with Email"2. Modal appears asking for email address3. User enters email and clicks "Continue"4. Magic link email is sent (arrives in ~5 seconds)5. User clicks link in email6. User is logged in and redirected back to your appHandling Login Success
Section titled “Handling Login Success”Execute custom logic when a user successfully logs in:
import { PrivyLoginButton } from '@varity-labs/ui-kit';
export function LoginWithCallback() { const handleSuccess = (user) => { // Track login analytics analytics.track('user_logged_in', { email: user.email?.address, method: 'email', });
// Redirect to dashboard router.push('/dashboard'); };
const handleError = (error) => { console.error('Login failed:', error); toast.error('Login failed. Please try again.'); };
return ( <PrivyLoginButton onSuccess={handleSuccess} onError={handleError} > Sign in with Email </PrivyLoginButton> );}Protected Content
Section titled “Protected Content”Only show content to logged-in users:
import { PrivyProtectedRoute, usePrivy } from '@varity-labs/ui-kit';
function DashboardContent() { const { user } = usePrivy();
return ( <div> <h1>Welcome, {user?.email?.address}!</h1> <p>This is your private dashboard.</p> </div> );}
export default function Dashboard() { return ( <PrivyProtectedRoute> <DashboardContent /> </PrivyProtectedRoute> );}Email-Only Mode
Section titled “Email-Only Mode”To only allow email login (no social providers):
<PrivyStack loginMethods={['email']}> {children}</PrivyStack>This simplifies the login modal to only show an email input field.
Next Steps
Section titled “Next Steps”- Social Login - Add Google, Twitter, Discord
- Storage Quick Start - Upload and store files