Skip to content

chore: refactoring react server component client#1186

Open
joker23 wants to merge 2 commits intomainfrom
skz/sdk-2021/react-server
Open

chore: refactoring react server component client#1186
joker23 wants to merge 2 commits intomainfrom
skz/sdk-2021/react-server

Conversation

@joker23
Copy link
Contributor

@joker23 joker23 commented Mar 12, 2026

This PR is to finalize how the react server components can access server side LDClient. A few key points:

  • Developers will spin up a "ld server session" which is a wrapper around the global server sdk (which should be separately managed) on every request session. This wrapper would provide some React-esque capabilities to the underlying sdk.
  • This sdk session will be encapsulated in a react cache which should be cleaned after every request session.
  • Developers can also manage these sessions themselves as we provide the create wrapper function without having to deal with react cache.

This address:
SDK-2026
SDK-2021

Note

Medium Risk
Changes the server entrypoint API and behavior (removes createReactServerClient/contextProvider and no-op fallback, now throws in browser), which is potentially breaking for existing RSC integrations. Build output is also restructured into separate client/server bundles, which could affect packaging if misconfigured.

Overview
Refactors the React SDK server entrypoint to a context-bound “server session” API. createReactServerClient (and the LDContextProvider/LDReactServerOptions types) are removed in favor of createLDServerSession(client, context), which returns an LDServerSession whose variation methods no longer accept a context parameter.

Tightens runtime semantics and expands compatibility. Calling the server API in a browser now throws instead of returning a no-op client, and a new structural LDServerBaseClient interface is introduced to decouple from a concrete LDClient implementation.

Docs and examples are updated to the new session pattern, a Jest test suite is added for session binding/forwarding and the browser-guard error, and the build config is split into separate client/server outputs (client bundle gets a "use client" banner).

Written by Cursor Bugbot for commit 61658d1. This will update automatically on new commits. Configure here.


Open with Devin

@github-actions
Copy link
Contributor

@launchdarkly/js-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 25566 bytes
Compressed size limit: 26000
Uncompressed size: 125383 bytes

@github-actions
Copy link
Contributor

github-actions bot commented Mar 12, 2026

@launchdarkly/browser size report
This is the brotli compressed size of the ESM build.
Compressed size: 172375 bytes
Compressed size limit: 200000
Uncompressed size: 802016 bytes

@github-actions
Copy link
Contributor

@launchdarkly/js-client-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 22062 bytes
Compressed size limit: 24000
Uncompressed size: 114438 bytes

@github-actions
Copy link
Contributor

github-actions bot commented Mar 12, 2026

@launchdarkly/js-client-sdk size report
This is the brotli compressed size of the ESM build.
Compressed size: 24522 bytes
Compressed size limit: 25000
Uncompressed size: 84897 bytes

@joker23
Copy link
Contributor Author

joker23 commented Mar 12, 2026

@cursor review
@devin review

cursor[bot]

This comment was marked as resolved.

@joker23 joker23 force-pushed the skz/sdk-2021/react-server branch from 6e30ca5 to 562a3e6 Compare March 12, 2026 17:49
devin-ai-integration[bot]

This comment was marked as resolved.

@joker23 joker23 force-pushed the skz/sdk-2021/react-server branch from 848e4c8 to 562a3e6 Compare March 12, 2026 18:28
@joker23
Copy link
Contributor Author

joker23 commented Mar 12, 2026

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@joker23 joker23 marked this pull request as ready for review March 12, 2026 18:41
@joker23 joker23 requested a review from a team as a code owner March 12, 2026 18:41
// of meta with exclusions.
// eslint-disable-next-line no-param-reassign
opts.mangleProps = /^_([^m|_]|m[^e]|me[^t]|met[^a])/;
opts.banner = { js: '"use client";' };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the reason that we separated the client bundle and server bundle

@joker23 joker23 force-pushed the skz/sdk-2021/react-server branch from 562a3e6 to 4bcbba2 Compare March 12, 2026 19:28
devin-ai-integration[bot]

This comment was marked as resolved.

@joker23 joker23 force-pushed the skz/sdk-2021/react-server branch from 4bcbba2 to 61658d1 Compare March 12, 2026 20:32
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditching the context getter design and instead we are give the users a way to create a "scoped proxy" of the base server sdk for each request session that the LDClient is needed.

devin-ai-integration[bot]

This comment was marked as resolved.

@joker23 joker23 marked this pull request as draft March 13, 2026 15:03
@joker23
Copy link
Contributor Author

joker23 commented Mar 13, 2026

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

client.jsonVariationDetail(key, context, defaultValue),
allFlagsState: (options?: LDFlagsStateOptions) => client.allFlagsState(context, options),
};
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal helper createLDServerWrapper is publicly exported

Medium Severity

createLDServerWrapper is exported from LDServerSession.ts and re-exported via export * from './LDServerSession' in index.ts, making it part of the public API. However, it's only called internally by createLDServerSession and bypasses the cache() storage. If a user calls createLDServerWrapper directly, the session won't be stored in React's per-request cache, causing useLDServerSession() to return null — silently breaking the documented pattern. This function is an internal implementation detail and likely shouldn't be exported.

Additional Locations (1)
Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is by design in case developers do not want to use our cache implementation. This is the same reasoning as the ability to use named context in client components.

@joker23 joker23 force-pushed the skz/sdk-2021/react-server branch from fc1d11f to f2eee29 Compare March 13, 2026 16:25
@joker23 joker23 marked this pull request as ready for review March 13, 2026 21:06
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 new potential issues.

View 9 additional findings in Devin Review.

Open in Devin Review

Comment on lines +60 to +61
'createLDServerSession must only be called on the server. ' +
'Ensure this module is not imported from client components.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 createLDServerWrapper error message references wrong function name

The exported createLDServerWrapper function at packages/sdk/react/src/server/LDServerSession.ts:54 throws an error with the message 'createLDServerSession must only be called on the server.', but the function's actual name is createLDServerWrapper. Since createLDServerWrapper is publicly exported via packages/sdk/react/src/server/index.ts:3, a consumer calling it directly in a browser environment would receive a confusing error referencing a different function. The error message should either say createLDServerWrapper or the function should not be exported if it's only meant to be an internal implementation detail of createLDServerSession.

Suggested change
'createLDServerSession must only be called on the server. ' +
'Ensure this module is not imported from client components.',
'createLDServerWrapper must only be called on the server. ' +
'Ensure this module is not imported from client components.',
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +8 to +10
// cache() creates a per-request memoized store — each React render tree (request)
// gets its own isolated instance. The store is populated by LDIsomorphicProvider
// and read by serverBoolVariation / useBoolVariation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Stale comment references non-existent LDIsomorphicProvider and useBoolVariation

The comment at packages/sdk/react/src/server/LDServerSession.ts:8-10 states the cache store is "populated by LDIsomorphicProvider and read by serverBoolVariation / useBoolVariation", but none of these symbols exist in the server module. The store is actually populated by createLDServerSession and read by useLDServerSession. This misleads developers reading the code about how the caching mechanism works.

Suggested change
// cache() creates a per-request memoized store — each React render tree (request)
// gets its own isolated instance. The store is populated by LDIsomorphicProvider
// and read by serverBoolVariation / useBoolVariation.
// cache() creates a per-request memoized store — each React render tree (request)
// gets its own isolated instance. The store is populated by createLDServerSession
// and read by useLDServerSession.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant