From 2f3be5426fc3cecb699b2ea4bf4f5e33deeb0b54 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 6 Jun 2026 05:12:55 +0000 Subject: [PATCH] fix(actions): skip Supabase fetch at build time when env vars unset The /indian-river-direct/stops page and sitemap prerender at build time and call getPublicStopsForBrand / getActiveStopsForSitemap / getBrandSettingsPublic. Those actions fetch NEXT_PUBLIC_SUPABASE_URL via Supabase REST. During the GitHub/Gitea build, the Supabase secret is unset (or the value is ".supabase.co" which doesn't resolve), so the fetch errors with ECONNREFUSED and the build aborts. Return [] / not-configured when the env vars are missing so the prerender can complete. Runtime behavior is unchanged when the vars are set. --- src/actions/brand-settings.ts | 9 +++++++-- src/actions/stops.ts | 15 +++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/actions/brand-settings.ts b/src/actions/brand-settings.ts index 939af8e..8182617 100644 --- a/src/actions/brand-settings.ts +++ b/src/actions/brand-settings.ts @@ -271,8 +271,13 @@ export async function getBrandSettings(brandId: string): Promise { - const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; - const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!; + const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; + const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + // Build-time prerender runs before Supabase env is configured. Return + // a not-configured result; the page falls back to slug-based defaults. + if (!supabaseUrl || !supabaseKey) { + return { success: false, error: "Supabase not configured", wholesaleEnabled: undefined }; + } const response = await fetch( `${supabaseUrl}/rest/v1/rpc/get_brand_settings_by_slug`, diff --git a/src/actions/stops.ts b/src/actions/stops.ts index dec3cbd..681906e 100644 --- a/src/actions/stops.ts +++ b/src/actions/stops.ts @@ -110,8 +110,11 @@ export type StopForSitemap = { }; export async function getActiveStopsForSitemap(): Promise { - const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; - const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!; + const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; + const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + // Build-time prerender runs before Supabase env is configured. Returning + // an empty list lets the sitemap render with only the static URLs. + if (!supabaseUrl || !supabaseKey) return []; // Get all active stops with their brand slug const response = await fetch( @@ -155,8 +158,12 @@ export async function getPublicStopsForBrand( ): Promise { if (!brandSlug) return []; - const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; - const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!; + const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; + const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + // Build-time prerender runs before Supabase env is configured. Returning + // an empty list lets the page render with zero stops; at runtime the + // fetch path is unchanged. + if (!supabaseUrl || !supabaseKey) return []; const response = await fetch( `${supabaseUrl}/rest/v1/rpc/get_public_stops_for_brand`,