fix: Switch to @supabase/ssr for browser client

- Use createBrowserClient from @supabase/ssr instead of supabase-js
- Stores auth session in cookies (not localStorage) for SSR compatibility
- Server actions can now access authenticated user sessions
- Fixes 'Nicht autorisiert' error in split creation
This commit is contained in:
2025-12-25 23:20:53 +01:00
parent 2286867447
commit 462d27ea7b
3 changed files with 13 additions and 16 deletions

View File

@@ -1,7 +1,6 @@
import { createClient as createSupabaseClient } from '@supabase/supabase-js'; import { createBrowserClient } from '@supabase/ssr';
import type { SupabaseClient } from '@supabase/supabase-js'; import type { SupabaseClient } from '@supabase/supabase-js';
// Use globalThis to persist across HMR reloads in development
const globalForSupabase = globalThis as typeof globalThis & { const globalForSupabase = globalThis as typeof globalThis & {
supabaseBrowserClient?: SupabaseClient; supabaseBrowserClient?: SupabaseClient;
}; };
@@ -11,19 +10,9 @@ export function createClient() {
return globalForSupabase.supabaseBrowserClient; return globalForSupabase.supabaseBrowserClient;
} }
// Use supabase-js directly with isSingleton to suppress the warning globalForSupabase.supabaseBrowserClient = createBrowserClient(
globalForSupabase.supabaseBrowserClient = createSupabaseClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
{
auth: {
// Suppress "Multiple GoTrueClient instances" warning
// This is safe because we use a singleton pattern
storageKey: 'sb-auth-token',
persistSession: true,
detectSessionInUrl: true,
},
}
); );
return globalForSupabase.supabaseBrowserClient; return globalForSupabase.supabaseBrowserClient;

View File

@@ -33,9 +33,16 @@ export async function proxy(request: NextRequest) {
} }
); );
// Debug: Log all cookies
const url = new URL(request.url);
const allCookies = request.cookies.getAll();
const sbCookies = allCookies.filter(c => c.name.startsWith('sb-'));
if (!url.pathname.startsWith('/_next') && !url.pathname.includes('.')) {
console.log('[Proxy] Cookies:', sbCookies.map(c => `${c.name}=${c.value.slice(0, 20)}...`));
}
const { data: { user } } = await supabase.auth.getUser(); const { data: { user } } = await supabase.auth.getUser();
const url = new URL(request.url);
const isStatic = url.pathname.startsWith('/_next') || url.pathname.includes('/icon-') || url.pathname === '/favicon.ico'; const isStatic = url.pathname.startsWith('/_next') || url.pathname.includes('/icon-') || url.pathname === '/favicon.ico';
if (!isStatic) { if (!isStatic) {

View File

@@ -73,7 +73,8 @@ export async function createSplit(data: CreateSplitData): Promise<{
const supabase = await createClient(); const supabase = await createClient();
try { try {
const { data: { user } } = await supabase.auth.getUser(); const { data: { user }, error: authError } = await supabase.auth.getUser();
console.log('[createSplit] Auth result:', { userId: user?.id, authError });
if (!user) { if (!user) {
return { success: false, error: 'Nicht autorisiert' }; return { success: false, error: 'Nicht autorisiert' };
} }