ROOT CAUSE FIX: All server-side Supabase clients (server-client, middleware-client, server-admin-client) now use SUPABASE_INTERNAL_URL (http://supabase-kong:8000) when available, with cookieOptions.name set to match the external URL's cookie key (e.g. sb-myeasycms-auth-token). This gives us: - Reliable Docker-internal networking (no hairpin NAT through Traefik) - Correct session cookie matching between browser and server - No more 500 errors on SSR pages that query Supabase Reverted per-page try/catch workarounds since root cause is now fixed.
56 lines
1.5 KiB
TypeScript
56 lines
1.5 KiB
TypeScript
import 'server-only';
|
|
import { type NextRequest, NextResponse } from 'next/server';
|
|
|
|
import { createServerClient } from '@supabase/ssr';
|
|
|
|
import { Database } from '../database.types';
|
|
import { getSupabaseClientKeys } from '../get-supabase-client-keys';
|
|
|
|
/**
|
|
* Creates a middleware client for Supabase.
|
|
*
|
|
* Uses SUPABASE_INTERNAL_URL when available for reliable Docker networking,
|
|
* with cookieOptions.name matching the external URL's cookie key.
|
|
*/
|
|
export function createMiddlewareClient<GenericSchema = Database>(
|
|
request: NextRequest,
|
|
response: NextResponse,
|
|
) {
|
|
const keys = getSupabaseClientKeys();
|
|
|
|
const internalUrl = process.env.SUPABASE_INTERNAL_URL;
|
|
const url = internalUrl || keys.url;
|
|
|
|
const cookieOptions = internalUrl
|
|
? { name: deriveCookieName(keys.url) }
|
|
: undefined;
|
|
|
|
return createServerClient<GenericSchema>(url, keys.publicKey, {
|
|
...(cookieOptions ? { cookieOptions } : {}),
|
|
cookies: {
|
|
getAll() {
|
|
return request.cookies.getAll();
|
|
},
|
|
setAll(cookiesToSet) {
|
|
cookiesToSet.forEach(({ name, value }) =>
|
|
request.cookies.set(name, value),
|
|
);
|
|
|
|
cookiesToSet.forEach(({ name, value, options }) =>
|
|
response.cookies.set(name, value, options),
|
|
);
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
function deriveCookieName(supabaseUrl: string): string {
|
|
try {
|
|
const hostname = new URL(supabaseUrl).hostname;
|
|
const ref = hostname.split('.')[0]!;
|
|
return `sb-${ref}-auth-token`;
|
|
} catch {
|
|
return 'sb-localhost-auth-token';
|
|
}
|
|
}
|