Skip to content

feat(supabase): update X-Client-Info to structured metadata format#2359

Merged
grdsdev merged 2 commits into
masterfrom
feat/x-client-info
Jun 1, 2026
Merged

feat(supabase): update X-Client-Info to structured metadata format#2359
grdsdev merged 2 commits into
masterfrom
feat/x-client-info

Conversation

@mandarini

@mandarini mandarini commented May 12, 2026

Copy link
Copy Markdown
Contributor

Moved from: #2293
Author: @grdsdev

Summary

Changes X-Client-Info header from embedding the JS environment in the library identifier (supabase-js-node/2.105.0) to a structured semicolon-delimited key=value format (supabase-js/2.105.0; env=node).

This aligns with the cross-library structured metadata initiative (SDK-902) and allows new metadata fields to be added freely without requiring CORS config changes in Edge Functions.

Changes

  • packages/core/supabase-js/src/lib/constants.ts: Changed X-Client-Info value from supabase-js-${JS_ENV}/${version} to supabase-js/${version}; env=${JS_ENV}
  • packages/core/supabase-js/test/unit/constants.test.ts: Updated assertions to match new header format

Before / After

Before After
supabase-js-node/2.105.0 supabase-js/2.105.0; env=node
supabase-js-web/2.105.0 supabase-js/2.105.0; env=web
supabase-js-deno/2.105.0 supabase-js/2.105.0; env=deno
supabase-js-react-native/2.105.0 supabase-js/2.105.0; env=react-native

Motivation

Adding new standalone HTTP headers is a breaking change for supabase-js users running inside Edge Functions — they must explicitly allow each header in their CORS config. Since X-Client-Info is already in everyone's CORS allowlist, using it as an extensible structured field lets us add new metadata (platform, runtime version, etc.) safely in the future.

Testing

All 9 constants.test.ts unit tests pass. The other test-suite failures are pre-existing TypeScript issues in unrelated packages.

Acceptance Criteria

  • X-Client-Info uses key=value structured format
  • JS environment info preserved via env= key
  • All existing constants tests pass
  • No breaking changes to the header value semantics

Linear Issue

Closes: SDK-903
Parent: SDK-902


🤖 Generated with Claude Code /take

Change DEFAULT_HEADERS to use semicolon-delimited key=value pairs
instead of embedding the JS environment in the library identifier.

Old: supabase-js-node/2.105.0
New: supabase-js/2.105.0; env=node

This aligns with the proposed structured metadata format across all
Supabase client libraries, allowing new metadata fields to be added
without touching CORS config (X-Client-Info is already an allowed
header, while new standalone headers would require CORS updates in
Edge Functions).

Linear: SDK-903

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added the supabase-js Related to the supabase-js library. label May 12, 2026
@pkg-pr-new

pkg-pr-new Bot commented May 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

@supabase/auth-js

npm i https://pkg.pr.new/@supabase/auth-js@2359

@supabase/functions-js

npm i https://pkg.pr.new/@supabase/functions-js@2359

@supabase/postgrest-js

npm i https://pkg.pr.new/@supabase/postgrest-js@2359

@supabase/realtime-js

npm i https://pkg.pr.new/@supabase/realtime-js@2359

@supabase/storage-js

npm i https://pkg.pr.new/@supabase/storage-js@2359

@supabase/supabase-js

npm i https://pkg.pr.new/@supabase/supabase-js@2359

commit: 745605b

@grdsdev grdsdev marked this pull request as ready for review June 1, 2026 10:01
@grdsdev grdsdev requested a review from a team as a code owner June 1, 2026 10:01
grdsdev added a commit that referenced this pull request Jun 1, 2026
…ient-Info

Builds on #2359: renames the structured metadata key from `env` to
`runtime` and adds a `runtime-version` field where the version can be
deterministically extracted:

- Node.js: process.version (leading `v` stripped)
- Deno: Deno.version.deno
- Web / React Native: no version appended

Before: supabase-js/2.x.x; env=node
After:  supabase-js/2.x.x; runtime=node; runtime-version=22.13.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ient-Info (#2412)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@grdsdev grdsdev merged commit 3397c92 into master Jun 1, 2026
24 checks passed
@grdsdev grdsdev deleted the feat/x-client-info branch June 1, 2026 11:02
mandarini pushed a commit to supabase/supabase that referenced this pull request Jun 2, 2026
This PR updates @supabase/*-js libraries to version 2.107.0.

**Source**: manual

**Changes**:
- Updated @supabase/supabase-js to 2.107.0
- Updated @supabase/auth-js to 2.107.0
- Updated @supabase/realtime-js to 2.107.0
- Updated @supabase/postgest-js to 2.107.0
- Refreshed pnpm-lock.yaml

---

## Release Notes

## v2.107.0

## 2.107.0 (2026-06-02)

### 🚀 Features

- **auth:** remove navigator.locks-based mutex; introduce commit guard +
dispose() ([#2392](supabase/supabase-js#2392))
- **realtime:** allow httpSend to send binary payload
([#2400](supabase/supabase-js#2400))
- **supabase:** update X-Client-Info to structured metadata format
([#2359](supabase/supabase-js#2359))

### 🩹 Fixes

- **auth:** return AuthInvalidJwtError from getClaims for expired JWT
([#2395](supabase/supabase-js#2395))
- **auth:** recognize ?error= redirects in implicit grant gate
([#2407](supabase/supabase-js#2407))
- **auth): revert fix(auth:** encode client-id in oauth requests
([#2383](supabase/supabase-js#2383),
[#2417](supabase/supabase-js#2417))
- **postgrest:** return a structured error for non-JSON body on
successful responses
([#2398](supabase/supabase-js#2398))
- **release:** pin workspace:* sibling deps before JSR publish
([#2418](supabase/supabase-js#2418))
- **release:** publish gotrue-js legacy mirror via pnpm
([#2419](supabase/supabase-js#2419))

### ❤️ Thank You

- Claude Opus 4.7 (1M context)
- Claude Sonnet 4.6
- Eduardo Gurgel
- Guilherme Souza
- Katerina Skroumpelou @mandarini
- Omar Al Matar @Bewinxed
- youcef zr @youcefzemmar
- youcefzemmar

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
imor pushed a commit to supabase/supabase that referenced this pull request Jun 3, 2026
This PR updates @supabase/*-js libraries to version 2.107.0.

**Source**: manual

**Changes**:
- Updated @supabase/supabase-js to 2.107.0
- Updated @supabase/auth-js to 2.107.0
- Updated @supabase/realtime-js to 2.107.0
- Updated @supabase/postgest-js to 2.107.0
- Refreshed pnpm-lock.yaml

---

## Release Notes

## v2.107.0

## 2.107.0 (2026-06-02)

### 🚀 Features

- **auth:** remove navigator.locks-based mutex; introduce commit guard +
dispose() ([#2392](supabase/supabase-js#2392))
- **realtime:** allow httpSend to send binary payload
([#2400](supabase/supabase-js#2400))
- **supabase:** update X-Client-Info to structured metadata format
([#2359](supabase/supabase-js#2359))

### 🩹 Fixes

- **auth:** return AuthInvalidJwtError from getClaims for expired JWT
([#2395](supabase/supabase-js#2395))
- **auth:** recognize ?error= redirects in implicit grant gate
([#2407](supabase/supabase-js#2407))
- **auth): revert fix(auth:** encode client-id in oauth requests
([#2383](supabase/supabase-js#2383),
[#2417](supabase/supabase-js#2417))
- **postgrest:** return a structured error for non-JSON body on
successful responses
([#2398](supabase/supabase-js#2398))
- **release:** pin workspace:* sibling deps before JSR publish
([#2418](supabase/supabase-js#2418))
- **release:** publish gotrue-js legacy mirror via pnpm
([#2419](supabase/supabase-js#2419))

### ❤️ Thank You

- Claude Opus 4.7 (1M context)
- Claude Sonnet 4.6
- Eduardo Gurgel
- Guilherme Souza
- Katerina Skroumpelou @mandarini
- Omar Al Matar @Bewinxed
- youcef zr @youcefzemmar
- youcefzemmar

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
mandarini pushed a commit to supabase/ssr that referenced this pull request Jun 3, 2026
This PR updates `@supabase/supabase-js` to v2.107.0.

**Source**: manual

---

## Release Notes

## v2.107.0

## 2.107.0 (2026-06-02)

### 🚀 Features

- **auth:** remove navigator.locks-based mutex; introduce commit guard +
dispose() ([#2392](supabase/supabase-js#2392))
- **realtime:** allow httpSend to send binary payload
([#2400](supabase/supabase-js#2400))
- **supabase:** update X-Client-Info to structured metadata format
([#2359](supabase/supabase-js#2359))

### 🩹 Fixes

- **auth:** return AuthInvalidJwtError from getClaims for expired JWT
([#2395](supabase/supabase-js#2395))
- **auth:** recognize ?error= redirects in implicit grant gate
([#2407](supabase/supabase-js#2407))
- **auth): revert fix(auth:** encode client-id in oauth requests
([#2383](supabase/supabase-js#2383),
[#2417](supabase/supabase-js#2417))
- **postgrest:** return a structured error for non-JSON body on
successful responses
([#2398](supabase/supabase-js#2398))
- **release:** pin workspace:* sibling deps before JSR publish
([#2418](supabase/supabase-js#2418))
- **release:** publish gotrue-js legacy mirror via pnpm
([#2419](supabase/supabase-js#2419))

### ❤️ Thank You

- Claude Opus 4.7 (1M context)
- Claude Sonnet 4.6
- Eduardo Gurgel
- Guilherme Souza
- Katerina Skroumpelou @mandarini
- Omar Al Matar @Bewinxed
- youcef zr @youcefzemmar
- youcefzemmar
## v2.106.2

## 2.106.2 (2026-05-25)

### 🩹 Fixes

- **auth:** restore signup user response
([#2391](supabase/supabase-js#2391))
- **misc:** add react-native export condition for Hermes-safe resolution
([#2393](supabase/supabase-js#2393))

### ❤️ Thank You

- Myroslav Hryhschenko @BLOCKMATERIAL
- Vaibhav @7ttp

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

supabase-js Related to the supabase-js library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants