diff --git a/apps/docs/content/guides/functions/cors.mdx b/apps/docs/content/guides/functions/cors.mdx
index dc357aae63d..46d7c4375b7 100644
--- a/apps/docs/content/guides/functions/cors.mdx
+++ b/apps/docs/content/guides/functions/cors.mdx
@@ -10,19 +10,16 @@ See the [example on GitHub](https://github.com/supabase/supabase/blob/master/exa
### Recommended setup
-We recommend adding a `cors.ts` file within a [`_shared` folder](/docs/guides/functions/quickstart#organizing-your-edge-functions) which makes it easy to reuse the CORS headers across functions:
+
-```ts cors.ts
-export const corsHeaders = {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
-}
-```
+**For `@supabase/supabase-js` v2.95.0 and later:** Import CORS headers directly from the SDK to ensure they stay synchronized with any new headers added to the client libraries.
-You can then import and use the CORS headers within your functions:
+
+
+Import `corsHeaders` from `@supabase/supabase-js/cors` to automatically get all required headers:
```ts index.ts
-import { corsHeaders } from '../_shared/cors.ts'
+import { corsHeaders } from '@supabase/supabase-js/cors'
console.log(`Function "browser-with-cors" up and running!`)
@@ -50,3 +47,24 @@ Deno.serve(async (req) => {
}
})
```
+
+This approach ensures that when new headers are added to the Supabase SDK, your Edge Functions automatically include them, preventing CORS errors.
+
+#### For versions before 2.95.0
+
+If you're using `@supabase/supabase-js` before v2.95.0, you'll need to hardcode the CORS headers. Add a `cors.ts` file within a [`_shared` folder](/docs/guides/functions/quickstart#organizing-your-edge-functions):
+
+```ts _shared/cors.ts
+export const corsHeaders = {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
+}
+```
+
+Then import it in your function:
+
+```ts index.ts
+import { corsHeaders } from '../_shared/cors.ts'
+
+// ... rest of your function code
+```
diff --git a/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx b/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx
index 5bb06cb71e8..8d6c208e3c3 100644
--- a/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx
+++ b/apps/docs/content/guides/functions/examples/cloudflare-turnstile.mdx
@@ -23,7 +23,7 @@ supabase functions new cloudflare-turnstile
And add the code to the `index.ts` file:
```ts index.ts
-import { corsHeaders } from '../_shared/cors.ts'
+import { corsHeaders } from '@supabase/supabase-js/cors' // v2.95.0+
console.log('Hello from Cloudflare Trunstile!')
diff --git a/apps/docs/content/guides/functions/troubleshooting.mdx b/apps/docs/content/guides/functions/troubleshooting.mdx
index 39fe091cca9..2c538c71797 100644
--- a/apps/docs/content/guides/functions/troubleshooting.mdx
+++ b/apps/docs/content/guides/functions/troubleshooting.mdx
@@ -112,25 +112,26 @@ For invocation or CORS issues:
```tsx
// ✅ Proper CORS handling
+import { corsHeaders } from '@supabase/supabase-js/cors' // v2.95.0+
+
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
- return new Response(null, {
- status: 200,
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
- },
- })
+ return new Response('ok', { headers: corsHeaders })
}
// Your function logic here
- return new Response('Success', {
- headers: { 'Access-Control-Allow-Origin': '*' },
+ return new Response(JSON.stringify({ status: 'Success' }), {
+ headers: { ...corsHeaders, 'Content-Type': 'application/json' },
})
})
```
+
+
+For `@supabase/supabase-js` versions before v2.95.0, you'll need to hardcode the CORS headers. See the [CORS guide](/docs/guides/functions/cors) for details.
+
+
+
There are two debugging tools available: Invocations and Logs. Invocations shows the Request and Response for each execution, while Logs shows any platform events, including deployments and errors.
---
diff --git a/examples/edge-functions/supabase/functions/_shared/cors.ts b/examples/edge-functions/supabase/functions/_shared/cors.ts
index 2ac4d89b14a..a418716bcf4 100644
--- a/examples/edge-functions/supabase/functions/_shared/cors.ts
+++ b/examples/edge-functions/supabase/functions/_shared/cors.ts
@@ -1,3 +1,11 @@
+// NOTE: For @supabase/supabase-js v2.95.0 and later, you can import CORS headers
+// directly from the SDK instead of hardcoding them:
+//
+// import { corsHeaders } from 'jsr:@supabase/supabase-js@2/cors'
+//
+// This ensures your CORS headers stay synchronized with any new headers added to the SDK.
+// For versions before 2.95.0, use this hardcoded configuration:
+
export const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
diff --git a/examples/edge-functions/supabase/functions/browser-with-cors/index.ts b/examples/edge-functions/supabase/functions/browser-with-cors/index.ts
index 8028c11592a..ae656f8859d 100644
--- a/examples/edge-functions/supabase/functions/browser-with-cors/index.ts
+++ b/examples/edge-functions/supabase/functions/browser-with-cors/index.ts
@@ -2,7 +2,11 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
-import { corsHeaders } from '../_shared/cors.ts'
+// For @supabase/supabase-js v2.95.0+, import CORS headers directly from the SDK:
+import { corsHeaders } from 'jsr:@supabase/supabase-js@2/cors'
+
+// For older versions, use a shared cors.ts file:
+// import { corsHeaders } from '../_shared/cors.ts'
console.log(`Function "browser-with-cors" up and running!`)
diff --git a/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts b/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts
index 5d94fe3404f..f877a1c59b6 100644
--- a/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts
+++ b/examples/edge-functions/supabase/functions/get-tshirt-competition/index.ts
@@ -3,7 +3,10 @@
// This enables autocomplete, go to definition, etc.
import { createClient } from 'npm:supabase-js@2'
-import { corsHeaders } from '../_shared/cors.ts'
+// New approach (v2.95.0+)
+import { corsHeaders } from 'jsr:@supabase/supabase-js@2/cors'
+// For older versions:
+// import { corsHeaders } from '../_shared/cors.ts'
console.log(`Function "get-tshirt-competition" up and running!`)
diff --git a/examples/edge-functions/supabase/functions/read-storage/index.ts b/examples/edge-functions/supabase/functions/read-storage/index.ts
index db5ea0a3488..72e492898ad 100644
--- a/examples/edge-functions/supabase/functions/read-storage/index.ts
+++ b/examples/edge-functions/supabase/functions/read-storage/index.ts
@@ -3,11 +3,13 @@
// This enables autocomplete, go to definition, etc.
import { createClient } from 'npm:supabase-js@2'
-
-const corsHeaders = {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey',
-}
+// New approach (v2.95.0+)
+import { corsHeaders } from 'jsr:@supabase/supabase-js@2/cors'
+// For older versions, use hardcoded headers:
+// const corsHeaders = {
+// 'Access-Control-Allow-Origin': '*',
+// 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
+// }
Deno.serve(async (req) => {
// read a text file from storage and print its contents
diff --git a/examples/edge-functions/supabase/functions/restful-tasks/index.ts b/examples/edge-functions/supabase/functions/restful-tasks/index.ts
index 3b6084f2d69..3addd3448e9 100644
--- a/examples/edge-functions/supabase/functions/restful-tasks/index.ts
+++ b/examples/edge-functions/supabase/functions/restful-tasks/index.ts
@@ -3,12 +3,14 @@
// This enables autocomplete, go to definition, etc.
import { createClient, SupabaseClient } from 'npm:supabase-js@2'
-
-const corsHeaders = {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey',
- 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE',
-}
+// New approach (v2.95.0+)
+import { corsHeaders } from 'jsr:@supabase/supabase-js@2/cors'
+// For older versions, use hardcoded headers:
+// const corsHeaders = {
+// 'Access-Control-Allow-Origin': '*',
+// 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
+// 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE',
+// }
interface Task {
name: string
diff --git a/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts b/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts
index c344baafe63..118f4c4593f 100644
--- a/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts
+++ b/examples/edge-functions/supabase/functions/select-from-table-with-auth-rls/index.ts
@@ -3,7 +3,10 @@
// This enables autocomplete, go to definition, etc.
import { createClient } from 'npm:supabase-js@2'
-import { corsHeaders } from '../_shared/cors.ts'
+// New approach (v2.95.0+)
+import { corsHeaders } from 'jsr:@supabase/supabase-js@2/cors'
+// For older versions:
+// import { corsHeaders } from '../_shared/cors.ts'
console.log(`Function "select-from-table-with-auth-rls" up and running!`)