Initialize Supabase Next app

This commit is contained in:
2026-05-23 13:24:39 -06:00
parent c9038a8f3c
commit 5bed4dcf11
56 changed files with 9851 additions and 3 deletions

11
lib/supabase/client.ts Normal file
View File

@@ -0,0 +1,11 @@
import { createBrowserClient } from "@supabase/ssr";
import { getSupabaseEnv } from "@/lib/supabase/env";
export function createClient() {
const { supabaseUrl, supabasePublishableKey } = getSupabaseEnv();
return createBrowserClient(
supabaseUrl,
supabasePublishableKey,
);
}

19
lib/supabase/env.ts Normal file
View File

@@ -0,0 +1,19 @@
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabasePublishableKey =
process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY ??
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
export const hasSupabaseEnv = Boolean(supabaseUrl && supabasePublishableKey);
export function getSupabaseEnv() {
if (!supabaseUrl || !supabasePublishableKey) {
throw new Error(
"Missing Supabase environment variables. Set NEXT_PUBLIC_SUPABASE_URL and either NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY or NEXT_PUBLIC_SUPABASE_ANON_KEY.",
);
}
return {
supabaseUrl,
supabasePublishableKey,
};
}

79
lib/supabase/proxy.ts Normal file
View File

@@ -0,0 +1,79 @@
import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";
import { hasEnvVars } from "../utils";
import { getSupabaseEnv } from "@/lib/supabase/env";
export async function updateSession(request: NextRequest) {
let supabaseResponse = NextResponse.next({
request,
});
// If the env vars are not set, skip proxy check. You can remove this
// once you setup the project.
if (!hasEnvVars) {
return supabaseResponse;
}
const { supabaseUrl, supabasePublishableKey } = getSupabaseEnv();
// With Fluid compute, don't put this client in a global environment
// variable. Always create a new one on each request.
const supabase = createServerClient(
supabaseUrl,
supabasePublishableKey,
{
cookies: {
getAll() {
return request.cookies.getAll();
},
setAll(cookiesToSet) {
cookiesToSet.forEach(({ name, value }) => {
request.cookies.set(name, value);
});
supabaseResponse = NextResponse.next({
request,
});
cookiesToSet.forEach(({ name, value, options }) => {
supabaseResponse.cookies.set(name, value, options);
});
},
},
},
);
// Do not run code between createServerClient and
// supabase.auth.getClaims(). A simple mistake could make it very hard to debug
// issues with users being randomly logged out.
// IMPORTANT: If you remove getClaims() and you use server-side rendering
// with the Supabase client, your users may be randomly logged out.
const { data } = await supabase.auth.getClaims();
const user = data?.claims;
if (
request.nextUrl.pathname !== "/" &&
!user &&
!request.nextUrl.pathname.startsWith("/login") &&
!request.nextUrl.pathname.startsWith("/auth")
) {
// no user, potentially respond by redirecting the user to the login page
const url = request.nextUrl.clone();
url.pathname = "/auth/login";
return NextResponse.redirect(url);
}
// IMPORTANT: You *must* return the supabaseResponse object as it is.
// If you're creating a new response object with NextResponse.next() make sure to:
// 1. Pass the request in it, like so:
// const myNewResponse = NextResponse.next({ request })
// 2. Copy over the cookies, like so:
// myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
// 3. Change the myNewResponse object to fit your needs, but avoid changing
// the cookies!
// 4. Finally:
// return myNewResponse
// If this is not done, you may be causing the browser and server to go out
// of sync and terminate the user's session prematurely!
return supabaseResponse;
}

36
lib/supabase/server.ts Normal file
View File

@@ -0,0 +1,36 @@
import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";
import { getSupabaseEnv } from "@/lib/supabase/env";
/**
* Especially important if using Fluid compute: Don't put this client in a
* global variable. Always create a new client within each function when using
* it.
*/
export async function createClient() {
const cookieStore = await cookies();
const { supabaseUrl, supabasePublishableKey } = getSupabaseEnv();
return createServerClient(
supabaseUrl,
supabasePublishableKey,
{
cookies: {
getAll() {
return cookieStore.getAll();
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) => {
cookieStore.set(name, value, options);
});
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have proxy refreshing
// user sessions.
}
},
},
},
);
}