Check the actual failure first
A DNS lookup failure, a CORS error, and a Supabase authorization error have different causes. Try the same project URL directly and through the playground, then test from the affected browser network. Connectivity restrictions vary by network and time.
Configure the Supabase SDK’s HTTP fetch
Use the helper below with the SDK’s global.fetch option. It accepts a URL or a Request and preserves the HTTP method, headers, body, and cancellation signal. Keep the original Supabase project URL in createClient().
async function proxiedSupabaseFetch(
input: RequestInfo | URL,
init?: RequestInit,
): Promise<Response> {
// Normalize strings, URLs, and Request objects, preserving the SDK's headers and body.
const request = new Request(input, init);
const params = new URLSearchParams({
key: 'YOUR_CORSPROXY_KEY',
url: request.url,
});
return fetch('https://corsproxy.io/?' + params, {
method: request.method,
headers: request.headers,
body: ['GET', 'HEAD'].includes(request.method) ? undefined : await request.blob(),
signal: request.signal,
});
} import { createClient } from '@supabase/supabase-js';
// Define proxiedSupabaseFetch from the example above in the same module.
const supabase = createClient(
'https://YOUR_PROJECT.supabase.co',
'YOUR_SUPABASE_PUBLISHABLE_KEY',
{ global: { fetch: proxiedSupabaseFetch } },
);
const { data, error } = await supabase.from('todos').select('*');
if (error) throw error;
console.log(data); Use a Supabase publishable key or legacy anon key in browser code. Keep Supabase secret and service-role keys on your server. Your CORSPROXY key is separate from the Supabase key; Supabase still evaluates authentication and row-level security.
What this integration routes
The fetch hook covers HTTP requests made through that SDK instance, such as database queries and HTTP function calls. Response content types, upload sizes, and bandwidth must fit your CORSPROXY plan. Free supports JSON and text; Hobby adds raw images and PDFs; Production supports server requests and additional non-video content types.
Configure Realtime separately
Supabase Realtime opens a WebSocket connection. Changing global.fetch does not route that connection. CORSPROXY’s paid WebSocket support requires a separate Realtime transport integration; test channel joins, reconnects, and authentication before relying on it.
Read Supabase’s Realtime protocol.
Verify redirects, storage links, and authentication flows
OAuth and magic-link flows can navigate the browser to URLs outside the fetch hook. Storage URLs used directly in an image or download element also need their own request path. Test each flow your app uses; the HTTP hook does not provide complete project coverage.
Supabase client configuration · Image delivery · Deployment checklist
