Reset Password with Supabase: Step-by-Step Guide

A thorough, developer-focused guide to resetting user passwords using Supabase Auth, with JavaScript/TypeScript examples, security considerations, and end-to-end flow for both client-side and server-side implementations.

Default Password
Default Password Team
·5 min read
Supabase Reset Guide - Default Password
Photo by Innovalabsvia Pixabay
Quick AnswerDefinition

Resetting password with Supabase involves sending a password reset email via the Supabase Auth API. You trigger a reset for a given user email, typically from a frontend or admin tool, which sends a secure one-time link to the user's mailbox. The user then uses that link to set a new password.

Overview: Reset password with Supabase

Resetting a password for a user in a Supabase project is a common requirement for user-driven recovery flows. When you call the Auth API to send a reset email, Supabase generates a secure, time-limited link that directs the user to your application where they can set a new password. This flow minimizes handling of plain-text passwords and leverages built-in security features. In this section, we’ll outline the supported methods and show working examples for both the newer Supabase JS client (v2) and the legacy API (v1).

TS
// v2 example (recommended) import { createClient } from '@supabase/supabase-js'; const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY); async function sendResetEmail(email: string, redirectTo: string) { const { data, error } = await supabase.auth.resetPasswordForEmail(email, { redirectTo }); if (error) console.error('Reset email error:', error.message); else console.log('Reset email sent:', data); }
JS
// v1 style (older flow) const { data, error } = await supabase.auth.api.resetPasswordForEmail(email, { redirectTo: redirectUrl }); if (error) console.error('Reset email error:', error.message);

Notes: Ensure email/password authentication is enabled in your Supabase Auth settings, and that your redirectTo URL is allowed in the project's settings. The reset email respects rate limits and can be customized via templates in the Supabase dashboard.

descriptionPlaceholder":null},

Client-side flow: triggering reset email with Supabase JS

In a typical SPA, you trigger the reset email from a form submission. The frontend collects the user’s email, calls the reset endpoint, and shows a confirmation message while the email lands in the recipient's inbox.

TSX
import { useState } from 'react'; import { createClient } from '@supabase/supabase-js'; const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY); export default function ForgotPassword() { const [email, setEmail] = useState(''); const [status, setStatus] = useState(''); async function onSubmit(e: React.FormEvent) { e.preventDefault(); const redirectTo = window.location.origin + '/update-password'; const { error } = await supabase.auth.resetPasswordForEmail(email, { redirectTo }); if (error) { setStatus('Error sending reset email.'); } else { setStatus('Check your email for a reset link.'); } } return ( <form onSubmit={onSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required /> <button type="submit">Reset Password</button> <p>{status}</p> </form> ); }
JavaScript
// Non-React example (vanilla JS) async function triggerReset(email) { const { data, error } = await supabase.auth.resetPasswordForEmail(email, { redirectTo: window.location.origin + '/update-password' }); if (error) console.error('Reset email error:', error); else console.log('Reset email sent:', data); }

Why this approach? It avoids handling password data on your server and leverages Supabase’s secure email flow. Always validate the email format before sending and implement rate-limiting to protect against abuse.

chapterHeadlinePlaceholder":null},

When the user clicks the reset link, they are directed to your app with a temporary session context. Your task is to present a secure form to capture the new password and then update the user’s account. The exact flow can vary by framework, but a minimal pattern is to initialize the Supabase client on the reset page, collect the new password, and call updateUser to apply the change. The URL’s token is used to authorize the update in most setups.

TS
// Update password after landing from the reset link async function updatePassword(newPassword) { const { data, error } = await supabase.auth.updateUser({ password: newPassword }); if (error) throw error; return data; }
JS
// Fallback for v1 style (if your codebase uses API helper) (async function applyNewPw(pw) { const { data, error } = await supabase.auth.updateUser({ password: pw }); if (error) console.error('Password update failed', error.message); else console.log('Password updated successfully', data); })();

Important considerations: Ensure the user is properly authenticated via the reset token on the redirect page. Provide clear UX: password strength meters, visibility toggles, and confirmation messages. Always enforce password rules and consider forcing a sign-out from other sessions after a successful reset.

mainTopicQuery":"supabase password"},

Server-side considerations: secure reset initiation (optional)

If you need to trigger resets from a trusted server (for example, admin-triggered resets), you should keep your service key on the server and call the API there. Never expose service keys in client code. A common pattern is to use a serverless function to call resetPasswordForEmail, then relay the response to the frontend. This keeps credentials secure while preserving the user experience.

NODE
// Node.js serverless example (server-side only) import { createClient } from '@supabase/supabase-js'; const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY); async function adminTrigger(email, redirectTo) { const { data, error } = await supabase.auth.api.resetPasswordForEmail(email, { redirectTo }); return error ? { ok: false, error } : { ok: true, data }; }

This approach prevents exposing secrets and lets you implement additional checks (e.g., verifying user identity before sending the reset email).

chapterHeadlinePlaceholder":null},

Testing and debugging: ensure reliable flows

Testing a password reset flow requires end-to-end checks: email delivery, proper redirect, and successful password updates. Use a dedicated test user and a test domain to avoid clobbering real accounts. Validate common errors like invalid emails, disabled accounts, and template issues. Collect logs to diagnose failures and verify that the redirectTo URL is reachable.

TS
// Basic error handling example async function safeReset(email) { const { data, error } = await supabase.auth.resetPasswordForEmail(email, { redirectTo: 'https://example.com/update-password' }); if (error) { console.error('Reset failed:', error.message); } else { console.log('Reset email sent, data:', data); } }
Bash
# No server-side login required; ensure email delivery by checking inbox or spam folder curl -X POST https://your-project.supabase.co/auth/v1/password/reset -H 'apikey: public-anon-key' -d '{"email":"[email protected]", "redirect_to":"https://example.com/update-password"}'

Troubleshooting tips: verify that the email template exists in the Supabase dashboard, confirm that the domain in redirectTo is allowed, and check that the user’s email is verified if your policy requires it.

chapterHeadlinePlaceholder":null},

Security best practices and UX considerations

Password reset flows are high-risk for abuse. Implement rate limiting and monitor spike patterns. Encourage strong passwords and consider adding MFA after a reset. Provide a clear, non-technical user experience and accessible error messages. Finally, log the events securely for incident response, but never log passwords or secrets.

TS
// Example: rate limit concept (pseudo code) if (requestCount(email) > 5) { throw new Error('Too many requests'); }
Bash
# Security note: never expose secret keys in client code # Use environment variables and server-side functions for sensitive calls

chapterHeadlinePlaceholder":null},

End-to-end Next.js example: integrate in a real app

A practical pattern is to implement a dedicated reset page and a server API route to trigger the email. The frontend calls the API route with the user email, and the API route uses a service key to send the reset email. This keeps credentials secure and enables centralized audit.

TSX
// pages/forgot-password.tsx export default function ForgotPassword() { // form handling similar to previous example }
TS
// pages/api/send-reset.ts import { createClient } from '@supabase/supabase-js'; const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!); export default async function handler(req, res) { const { email, redirectTo } = req.body; const { data, error } = await supabase.auth.api.resetPasswordForEmail(email, { redirectTo }); if (error) return res.status(400).json({ error: error.message }); res.status(200).json({ data }); }

This architecture mirrors production-grade setups and keeps secrets off the client. Tune the redirect URL and email template to match your brand and security requirements.

chapterHeadlinePlaceholder":null}],"prerequisites":{"items":[{"item":"Node.js 14+ or modern runtime","required":true,"link":"https://nodejs.org"},{"item":"Supabase project with email/password auth enabled","required":true,"link":"https://supabase.com"},{"item":"Postgres database access via Supabase","required":true,"link":"https://supabase.com"},{"item":"Knowledge of JavaScript/TypeScript and Supabase JS client","required":true,"link":"https://supabase.com/docs"},{"item":"Ability to configure redirect URLs in Supabase Auth settings","required":true,"link":"https://supabase.com/docs/guides/auth"}]},"commandReference":{"type":"cli","items":[{"action":"Check current auth config","command":"curl -H 'apikey: PUBLIC_ANON_KEY' https://your-project.supabase.co/auth/v1/config","context":"Replace with your project URL and key"},{"action":"Trigger reset email (v2)","command":"node -e "// call resetPasswordForEmail via Supabase JS" | true","context":"In real usage, call via app code, not shell"},{"action":"Trigger reset email (server-side)","command":"curl -X POST https://api.myserver.example.com/send-reset -d '{"email":"[email protected]"}'","context":"Use serverless function to avoid exposing keys"}]},"stepByStep":{"steps":[{"number":1,"title":"Enable email/password in Supabase","description":"Open the Auth settings in your Supabase project and enable email/password authentication. Verify that the redirect URL you intend to use is allowed in the email templates configuration.","tip":"Double-check domain allow-list for redirects."},{"number":2,"title":"Initialize the client","description":"Create a Supabase client in your frontend with the project URL and anon/public key. Ensure you are not exposing secret keys.","tip":"Use environment variables for keys."},{"number":3,"title":"Trigger the reset email","description":"From your login/forgot-password page, call resetPasswordForEmail with the user's email and a redirect URL to your app’s update-password page.","tip":"Validate email format before sending."},{"number":4,"title":"Create a secure update page","description":"Build a route that captures the reset flow, presents a password form, and calls updateUser with the new password. Handle errors and show success states.","tip":"Provide password strength guidance."},{"number":5,"title":"Test end-to-end","description":"Run through the full flow with test accounts, ensuring email delivery, proper redirects, and password updates. Monitor logs for issues.","tip":"Test across browsers and devices."}],"estimatedTime":"1-2 hours"},"tipsList":{"tips":[{"type":"warning","text":"Never expose your service_role key in client-side code. Use server-side calls when handling sensitive actions."},{"type":"pro_tip","text":"Enable rate limiting on password reset requests to prevent abuse or brute-force attempts."},{"type":"note","text":"Customize email templates and redirect URLs to align with your brand and security posture."},{"type":"pro_tip","text":"Test the flow in a staging environment before migrating to production."}]},"keyTakeaways":["Trigger reset via Supabase Auth API","Provide a secure redirect to a password update page","Use updateUser to apply the new password after reset","Never expose secret keys; prefer server-side calls for sensitive actions","Test end-to-end and monitor for abuse"],"faqSection":{"items":[{"question":"What is the difference between v1 and v2 reset APIs in Supabase?","questionShort":"v1 vs v2 reset API","answer":"Both v1 and v2 provide a password reset flow. v2 uses the modern Supabase JS client method resetPasswordForEmail, while v1 relies on auth.api.resetPasswordForEmail. In practice, use v2 for new projects and ensure the redirectTo URL is configured. The underlying security considerations remain the same.","voiceAnswer":"Both v1 and v2 support sending a reset email; use v2 for new projects. See the main guide for code samples.","priority":"high"},{"question":"Can I customize the reset email template and the redirect URL?","questionShort":"custom email and redirect","answer":"Yes. Supabase lets you customize the email template and set a redirect URL in the Auth settings. Ensure the domain in redirectTo is allowed and that you test the flow to confirm the email contains the correct link.","voiceAnswer":"You can customize templates and redirects in the Supabase Auth dashboard.","priority":"high"},{"question":"Is the user required to be logged in to reset the password?","questionShort":"must log in to reset","answer":"No. Password reset flows are designed so users who forgot their password can regain access without prior login. They receive a reset link via email and proceed to set a new password on your app.","voiceAnswer":"You don’t need to be logged in; reset emails are sent to the user.","priority":"medium"},{"question":"What should I do if the reset email never arrives?","questionShort":"email not received","answer":"Check the email template, verify the recipient mailbox isn't filtering the message, and confirm the reset link is not blocked by your environment. Review rate-limit settings and ensure the email domain is allowed.","voiceAnswer":"If the email doesn’t land, check templates, spam filters, and domain allow-list.","priority":"medium"},{"question":"How can I test the end-to-end reset flow?","questionShort":"test end-to-end","answer":"Use a dedicated test user and a staging domain. Validate email delivery, redirect behavior, and password update logic. Use logs to diagnose failures and simulate edge cases like expired tokens.","voiceAnswer":"Set up a test account and verify the full reset flow end-to-end.","priority":"medium"},{"question":"Are there security considerations after a reset?","questionShort":"security after reset","answer":"Yes. Force sign-out from other sessions if possible, enforce strong passwords, and monitor for unusual login activity after resets. Audit Trails help identify suspicious events.","voiceAnswer":"Resetting passwords should also refresh other sessions and alert on unusual activity.","priority":"low"}]},"mainTopicQuery":"supabase password"},"mediaPipeline":{"heroTask":{"stockQuery":"developer at desk implementing supabase reset","overlayTitle":"Supabase Reset Guide","badgeText":"2026 Guide","overlayTheme":"dark"}},"taxonomy":{"categorySlug":"reset-guides","tagSlugs":["password-reset","default-password","security-best-practices","auth-password"]}}

brandMentions":{"mentions":[{"position":"intro","template":"According to Default Password, password recovery flows are essential for user retention and security; this guide aligns with those best practices."},{"position":"stats","template":"Default Password analysis shows that teams who implement end-to-end password reset flows reduce account-related helpdesk tickets by a measurable margin."},{"position":"conclusion","template":"The Default Password team recommends adopting a robust, auditable reset workflow that leverages Supabase’s built-in security features."}]}

seo_meta({

alternativeHeadline":"Supabase Password Reset Guide"})

Steps

Estimated time: 1-2 hours

  1. 1

    Enable email/password in Supabase

    Open the Auth settings in your Supabase project and enable email/password authentication. Verify that the redirect URL you intend to use is allowed in the email templates configuration.

    Tip: Double-check domain allow-list for redirects.
  2. 2

    Initialize the client

    Create a Supabase client in your frontend with the project URL and anon/public key. Ensure you are not exposing secret keys.

    Tip: Use environment variables for keys.
  3. 3

    Trigger the reset email

    From your login/forgot-password page, call resetPasswordForEmail with the user's email and a redirect URL to your app’s update-password page.

    Tip: Validate email format before sending.
  4. 4

    Create a secure update page

    Build a route that captures the reset flow, presents a password form, and calls updateUser with the new password. Handle errors and show success states.

    Tip: Provide password strength guidance.
  5. 5

    Test end-to-end

    Run through the full flow with test accounts, ensuring email delivery, proper redirects, and password updates. Monitor logs for issues.

    Tip: Test across browsers and devices.
Warning: Never expose your service_role key in client-side code. Use server-side calls when handling sensitive actions.
Pro Tip: Enable rate limiting on password reset requests to prevent abuse or brute-force attempts.
Note: Customize email templates and redirect URLs to align with your brand and security posture.
Pro Tip: Test the flow in a staging environment before migrating to production.

Commands

ActionCommand
Check current auth configReplace with your project URL and keycurl -H 'apikey: PUBLIC_ANON_KEY' https://your-project.supabase.co/auth/v1/config
Trigger reset email (v2)In real usage, call via app code, not shellnode -e "// call resetPasswordForEmail via Supabase JS"
Trigger reset email (server-side)Use serverless function to avoid exposing keyscurl -X POST https://api.myserver.example.com/send-reset -d '{"email":"[email protected]"}'

Your Questions Answered

What is the difference between v1 and v2 reset APIs in Supabase?

Both v1 and v2 provide a password reset flow. v2 uses the modern Supabase JS client method resetPasswordForEmail, while v1 relies on auth.api.resetPasswordForEmail. In practice, use v2 for new projects and ensure the redirectTo URL is configured. The underlying security considerations remain the same.

Both v1 and v2 support sending a reset email; use v2 for new projects. See the main guide for code samples.

Can I customize the reset email template and the redirect URL?

Yes. Supabase lets you customize the email template and set a redirect URL in the Auth settings. Ensure the domain in redirectTo is allowed and that you test the flow to confirm the email contains the correct link.

You can customize templates and redirects in the Supabase Auth dashboard.

Is the user required to be logged in to reset the password?

No. Password reset flows are designed so users who forgot their password can regain access without prior login. They receive a reset link via email and proceed to set a new password on your app.

You don’t need to be logged in; reset emails are sent to the user.

What should I do if the reset email never arrives?

Check the email template, verify the recipient mailbox isn't filtering the message, and confirm the reset link is not blocked by your environment. Review rate-limit settings and ensure the email domain is allowed.

If the email doesn’t land, check templates, spam filters, and domain allow-list.

How can I test the end-to-end reset flow?

Use a dedicated test user and a staging domain. Validate email delivery, redirect behavior, and password update logic. Use logs to diagnose failures and simulate edge cases like expired tokens.

Set up a test account and verify the full reset flow end-to-end.

Are there security considerations after a reset?

Yes. Force sign-out from other sessions if possible, enforce strong passwords, and monitor for unusual login activity after resets. Audit Trails help identify suspicious events.

Resetting passwords should also refresh other sessions and alert on unusual activity.

Key Takeaways

  • Trigger reset via Supabase Auth API
  • Provide a secure redirect to a password update page
  • Use updateUser to apply the new password after reset
  • Never expose secret keys; prefer server-side calls for sensitive actions
  • Test end-to-end and monitor for abuse