Hey Vercel community!
I’m running into a browser-specific authentication issue that’s got me stumped. Hoping someone has encountered this before.
The Problem:
-
Using Next.js 14 App Router with Supabase auth + @supabasesupabasesupabasesupabase/ssr
-
Google OAuth works perfectly in Safari and Firefox
-
Chrome and Edge get stuck on a loading screen during the auth callback
-
No console errors, just infinite loading after successful OAuth redirect
What I’ve tried:
-
Fixed cookie handling in middleware (removed multiple NextResponse.next() calls)
-
Added proper SameSite=lax and secure flags
-
Excluded auth/callback from middleware matcher
-
Verified redirect URLs in Supabase dashboard
Current setup :
-
import { createServerClient } from "@supabase/ssr" import { NextResponse, type NextRequest } from "next/server" export async function middleware(request: NextRequest) { // Create response once and reuse it const response = NextResponse.next({ request: { headers: request.headers, }, }) const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { get(name: string) { return request.cookies.get(name)?.value }, set(name: string, value: string, options: any) { // Set cookie with Chromium-friendly options const cookieOptions = { ...options, httpOnly: false, // Allow client-side access for auth secure: process.env.NODE_ENV === 'production', sameSite: 'lax' as const, // More permissive for OAuth } response.cookies.set({ name, value, ...cookieOptions, }) }, remove(name: string, options: any) { const cookieOptions = { ...options, httpOnly: false, secure: process.env.NODE_ENV === 'production', sameSite: 'lax' as const, } response.cookies.set({ name, value: "", ...cookieOptions, }) }, }, } ) try { const { data: { session }, error, } = await supabase.auth.getSession() // Set cache headers to prevent caching of auth state response.headers.set("Cache-Control", "no-cache, no-store, must-revalidate, private") response.headers.set("Pragma", "no-cache") response.headers.set("Expires", "0") response.headers.set("Vary", "Cookie") // Add CORS headers for Chromium compatibility response.headers.set("Access-Control-Allow-Credentials", "true") if (session?.user) { response.headers.set("X-User-ID", session.user.id) response.headers.set("X-Session-Refreshed", new Date().toISOString()) } if (error) { console.log("[MIDDLEWARE] Auth error:", error.message) } } catch (error) { console.error("[MIDDLEWARE] Unexpected error:", error) } return response } export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) * - public folder files * - auth/callback (OAuth callback route - IMPORTANT!) */ "/((?!_next/static|_next/image|favicon.ico|auth/callback|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)", ], }
Questions:
-
Has anyone seen Chromium-specific issues with Supabase auth on Vercel?
-
Are there known Edge Runtime limitations affecting auth callbacks?
-
Any Vercel-specific configuration that helps with cross-browser OAuth?
-