The automatic dedupe applies to fetch() calls with the same URL and options inside one render. supabase-js does use fetch internally, but not in a way you can rely on for that. Wrap your function in React's cache, which dedupes by arguments for the duration of one request:
import { cache } from "react";
export const getProduct = cache(async (id: string) => {
const supabase = await createClient();
const { data } = await supabase.from("products").select("*").eq("id", id).single();
return data;
});Now generateMetadata and the page share one result. It's per request, not a cross-request cache, so no stale data risk.