← All solutions & integration guides

Supabase integration guide

Route Supabase HTTP requests through CORSPROXY

If your users’ network cannot reach your Supabase project but can reach CORSPROXY, an HTTP proxy can provide another request path. Test it on the affected network before changing your integration.

Updated

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