Why this happens
Supabase's JavaScript client uses fetch. When the request can't complete at all (DNS failure, blocked connection, CORS rejection, invalid URL), the browser throws a generic TypeError: Failed to fetch and hides the real reason from your code. The Network tab still shows it. The usual causes, roughly in order:
- The env var is missing in production. The request goes to
undefined/auth/v1/token, or to your own domain. - Wrong project URL, for example a typo, an old project, or a deleted project. Shows as
ERR_NAME_NOT_RESOLVED. - The project is paused (Free plan inactivity).
- CORS on an Edge Function your login flow calls, often hidden behind a 500 error.
- Something on the user's side blocks it: an ad or privacy extension, a company firewall, or a network that blocks
*.supabase.co.
How to fix it, step by step
1. Find the failing request. On the live site, open DevTools → Network, tick Preserve log, and try to log in. Click the red request and read its URL and Status.
| You see | Meaning | Fix |
|---|---|---|
URL contains undefined or points at your own domain | Env var missing at build | Add VITE_SUPABASE_URL / NEXT_PUBLIC_SUPABASE_URL and the key to Production, then rebuild |
ERR_NAME_NOT_RESOLVED | Wrong or old project ref | Copy the URL from Supabase Connect, then rebuild |
CORS error on /functions/v1/... | Edge Function preflight or error response | Add CORS headers to every response (see the related guide) |
ERR_BLOCKED_BY_CLIENT | Browser extension | Test without extensions. Consider a Supabase custom domain |
| Times out or fails only on one network | Network or firewall block | Test on mobile data. Consider a custom domain |
2. Check the project is up. Open the Supabase dashboard. If it says Paused, click Resume project. You can also test from a terminal:
curl -i "https://<project-ref>.supabase.co/auth/v1/health" -H "apikey: <publishable-or-anon-key>"A 200 with a small JSON body means Auth is reachable.
3. Log what the client was built with. Temporarily add this to the client file to confirm the values that shipped. The URL is public, but don't log the key in full:
console.info('Supabase URL in this build:', import.meta.env.VITE_SUPABASE_URL);4. Avoid mixed content. Your site and the Supabase URL must both be https://.
5. Retest in a private window, with no extensions, on the live domain.
Fix prompt for your AI builder
Paste this into Lovable, Bolt, Cursor, Claude, ChatGPT, Replit, v0 or whichever tool you build with. Replace the bracketed parts first.
Login on https://yourdomain.com fails with "TypeError: Failed to fetch". In the Network tab, the failing request URL is: [paste] and the status/error is: [paste].
Please:
1. Make sure our Supabase client reads the URL and publishable/anon key from the correct build-time env vars, and throws a clear error if they're missing.
2. If the failing request is an Edge Function, make it answer OPTIONS with CORS headers and include the CORS headers on every response, including errors.
3. Show a friendly "Can't reach the server, please try again" message instead of a blank failure.
Don't change the login design, and don't put any secret key in front-end code.How to catch this next time
Several of these causes (a missing env var, a renamed project, a crashed client) take down the page itself, not just the login button.
Heedza opens your live landing, signup and login pages in a real browser on a schedule. It checks that each loads and that the email field is visible, and emails you a screenshot and a fix prompt when one doesn't. It doesn't submit your login form, so a request that fails only on submit still needs a manual test after deploys. Run the free scan on your live URL.