Your app uses the PKCE flow. When someone asks for a link, the browser stores a secret (the code verifier) locally. The link only works in that same browser. Laptop request → phone click = different browser, no verifier, failure. Gmail's in-app browser counts as a different browser too.
Fix: switch magic links to the token_hash flow, which is verified server-side and doesn't need the verifier.
- Supabase → Authentication → Email Templates → Magic Link, change the link to:
<a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email">Log in</a>- Add a route
/auth/confirmthat does:
const { error } = await supabase.auth.verifyOtp({ type: 'email', token_hash })and redirects to the app on success.
Now the link works in any browser on any device.