Skip to content

Commit 49da86c

Browse files
authored
docs: updating docs to clarify usage (#1205)
<!-- CURSOR_SUMMARY --> > [!NOTE] > **Low Risk** > Mostly documentation/comment and export-surface adjustments; minimal runtime impact aside from removing the `isServer` test/export and tightening what `LDReactContext` exports. > > **Overview** > Clarifies public API guidance across the React SDK (client creation, provider usage, initialization status, and server session patterns) via updated JSDoc and expanded `MIGRATING.md`, including stating a React 18+ support baseline and documenting `useFlag`/`useFlagDetail` as removed. > > Cleans up the export surface by switching `client/index.ts` to explicitly export `LDReactContext`/`initLDReactContext`, making `isServer()` internal-only (and removing its unit test), and deleting the temporary docs directory content. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 3d0039a. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/launchdarkly/js-core/pull/1205" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end -->
1 parent 3d1f68d commit 49da86c

19 files changed

Lines changed: 103 additions & 608 deletions

packages/sdk/react/__tests__/server/createLDServerSession.test.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { LDContext, LDFlagsStateOptions } from '@launchdarkly/js-server-sdk-common';
22

3-
import { createLDServerSession, isServer } from '../../src/server/index';
3+
import { createLDServerSession } from '../../src/server/index';
44

55
const context: LDContext = { kind: 'user', key: 'test-user' };
66

@@ -36,10 +36,6 @@ function makeMockBaseClient() {
3636
};
3737
}
3838

39-
it('isServer() returns true in a Node test environment', () => {
40-
expect(isServer()).toBe(true);
41-
});
42-
4339
it('getContext() returns the context passed at creation', () => {
4440
const client = makeMockBaseClient();
4541
const session = createLDServerSession(client, context);

packages/sdk/react/src/client/LDClient.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@ export interface LDReactClient extends LDClient {
4242
onContextChange(callback: (context: LDContextStrict) => void): () => void;
4343

4444
/**
45-
* Subscribes to initialization status changes triggered by `start()`. The callback is
46-
* invoked once `start()` resolves. If `start()` has already resolved when this is called,
47-
* the callback is invoked immediately with the last result.
45+
* Subscribes to initialization status changes triggered when the client is initialized.
4846
*
4947
* @param callback Function called with the initialization result.
5048
* @returns An unsubscribe function. Call it to stop receiving notifications.
@@ -54,9 +52,14 @@ export interface LDReactClient extends LDClient {
5452
): () => void;
5553

5654
/**
55+
* @internal
56+
*
5757
* Returns whether flag keys should be converted to camelCase in `useFlags()` and resolved from camelCase
5858
* in the individual variation hooks. Defaults to `true` when absent.
5959
*
60+
* @remarks
61+
* **NOTE:** This method is only used by `useFlags()` hook.
62+
*
6063
* @deprecated This method is deprecated and will be removed in a future major version.
6164
*
6265
* @returns {boolean} Whether flag keys should be converted to camelCase.
@@ -65,8 +68,7 @@ export interface LDReactClient extends LDClient {
6568
}
6669

6770
/**
68-
* The react context interface for the launchdarkly client. This will be the type that is
69-
* used in the `createContext` function.
71+
* The React context interface for the LaunchDarkly client.
7072
*/
7173
export interface LDReactClientContextValue {
7274
/**

packages/sdk/react/src/client/LDReactClient.tsx

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,8 @@ function noopDetail<T>(defaultValue: T): { value: T; kind: LDEvaluationReason['k
2121
}
2222

2323
/**
24-
* Returns a noop LDReactClient for use on the server. Never instantiates the browser SDK.
25-
* This is useful when dealing with applications that are using React Server Components.
26-
*
27-
* This fallback is helpful when compilers attempt to prerender components on build time.
28-
* This will enable the components to at least be prerendered with their default values.
29-
*
30-
* @privateRemarks TODO
31-
* I think we should move this and the server noop to a shared location... currently we
32-
* are separating everything to trivialize network boundary and tree shaking concerns.
33-
* But we shouldn't have any problems having some shared modules.
24+
* @privateRemarks
25+
* **WARNING:** This function is going to be removed soon! sdk-2043
3426
*/
3527
function createNoopReactClient(): LDReactClient {
3628
return {
@@ -89,23 +81,28 @@ function createNoopReactClient(): LDReactClient {
8981
* Creates a new instance of the LaunchDarkly client for React.
9082
*
9183
* @remarks
92-
* When called on the server, returns a noop client that never instantiates the browser SDK.
93-
* This function is exported so that developers can have more flexibility in client creation.
94-
* More so this is to preserve previous behavior of app developers managing their own client
95-
* instance.
84+
* **NOTE:** We recommend using the convenience factory function {@link createLDReactProvider}
85+
* instead of this function to create your client instance if you can.
9686
*
97-
* we DO NOT recommend using this client creation method.
87+
* This factory function is provided to allow the caller to have more control over their client instance.
88+
* When using this function, the caller is responsible for:
89+
* - calling `client.start()` before or after mounting.
90+
* - subscribing to client lifecycle events.
91+
*
92+
* Refer to {@link createLDReactProviderWithClient} for the default behavior.
9893
*
9994
* @example
10095
* ```tsx
10196
* import { createClient } from '@launchdarkly/react';
10297
* const client = createClient(clientSideID, context, options);
98+
*
99+
* await client.start();
103100
* ```
104101
*
105102
* @param clientSideID launchdarkly client side id @see https://launchdarkly.com/docs/sdk/concepts/client-side-server-side#client-side-id
106103
* @param context launchdarkly context @see https://launchdarkly.com/docs/sdk/concepts/context
107-
* @param options
108-
* @returns
104+
* @param options options for the client @see {@link LDReactClientOptions}
105+
* @returns the new client instance @see {@link LDReactClient}
109106
*/
110107
export function createClient(
111108
clientSideID: string,

packages/sdk/react/src/client/deprecated-hooks/flagKeyUtils.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/**
22
* Converts a flag key to camelCase, matching the behavior of the legacy
3-
* launchdarkly-react-client-sdk. Handles kebab-case, snake_case, dot.separated,
4-
* ALL_CAPS, and already-camelCased keys.
3+
* launchdarkly-react-client-sdk.
54
*
65
* Examples:
76
* 'my-flag-key' → 'myFlagKey'
@@ -13,8 +12,8 @@
1312
*/
1413
export function toCamelCase(key: string): string {
1514
return key
16-
.replace(/([a-z\d])([A-Z])/g, '$1 $2') // camelCase boundary: myFlag → my Flag, my2Flag → my2 Flag
17-
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2') // ALLCAPS boundary: HTMLParser → HTML Parser
15+
.replace(/([a-z\d])([A-Z])/g, '$1 $2')
16+
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
1817
.split(/[-._\s]+/)
1918
.filter(Boolean)
2019
.map((word, i) => {

packages/sdk/react/src/client/deprecated-hooks/useFlags.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ function toFlagsProxy<T extends LDFlagSet>(client: LDReactClient, rawFlags: T):
2121
// Pre-build the display object, filtering out $ system keys.
2222
// Mirrors getCamelizedKeysAndFlagMap in the old react-client-sdk.
2323
const displayFlags: LDFlagSet = {};
24-
const flagKeyMap: Record<string, string> = {}; // camelKey -> originalKey
24+
const flagKeyMap: Record<string, string> = {};
2525

2626
Object.keys(rawFlags as LDFlagSet)
27-
.filter((rawKey) => rawKey.indexOf('$') !== 0) // exclude system keys (matches old SDK)
27+
.filter((rawKey) => rawKey.indexOf('$') !== 0)
2828
.forEach((rawKey) => {
2929
if (useCamelCase) {
3030
const camelKey = toCamelCase(rawKey);
@@ -35,13 +35,10 @@ function toFlagsProxy<T extends LDFlagSet>(client: LDReactClient, rawFlags: T):
3535
}
3636
});
3737

38-
// Only a get trap — matches old SDK's toFlagsProxy scope.
3938
return new Proxy(displayFlags as T, {
4039
get(target, prop, receiver) {
4140
const currentValue = Reflect.get(target, prop, receiver);
4241

43-
// Only intercept own flag keys; pass through symbols and prototype methods.
44-
// Equivalent to old SDK: hasFlag(flagKeyMap, prop) || hasFlag(target, prop)
4542
if (typeof prop === 'symbol' || !Object.prototype.hasOwnProperty.call(target, prop)) {
4643
return currentValue;
4744
}
@@ -65,15 +62,7 @@ function toFlagsProxy<T extends LDFlagSet>(client: LDReactClient, rawFlags: T):
6562
}
6663

6764
/**
68-
* Returns all feature flags for the current context. Re-renders whenever any flag value changes.
69-
* Flag values are accessed via a proxy that triggers a `variation` call on each read, ensuring
70-
* evaluation events are sent to LaunchDarkly for accurate usage metrics.
71-
*
72-
* @remarks
73-
* When `useCamelCaseFlagKeys` is `true`, flag keys are converted to camelCase.
74-
* This means `"my-flag"` is accessible as `flags.myFlag`. Note that key collisions may occur
75-
* if two flag keys differ only in separators (e.g. `'my-flag'` and `'my.flag'` both map to
76-
* `'myFlag'` — last key wins), and Code References will not function correctly with camelCased keys.
65+
* Returns all feature flags for the current context.
7766
*
7867
* @param reactContext Optional React context to read from. Defaults to the global `LDReactContext`.
7968
* @returns All current flag values, optionally with camelCased keys, wrapped in a proxy that

packages/sdk/react/src/client/hooks/useInitializationStatus.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,7 @@ import type { LDReactClientContextValue } from '../LDClient';
66
import { LDReactContext } from '../provider/LDReactContext';
77

88
/**
9-
* The result of `useInitializationStatus`. Represents the current initialization
10-
* state of the LaunchDarkly client.
11-
*
12-
* @remarks
13-
* This replaces `useLDClientError` from `launchdarkly-react-client-sdk`. It provides
14-
* richer information: both the initialization state and the error (if any).
15-
*
16-
* Use `useInitializationStatus().error` to access the error,
17-
* and `useInitializationStatus().status` to determine the full state.
9+
* Represents the current initialization state of the LaunchDarkly client.
1810
*/
1911
export type InitializationStatus =
2012
| { status: 'unknown' }

packages/sdk/react/src/client/hooks/useVariation.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { LDReactClientContextValue } from '../LDClient';
44
import useVariationCore from './useVariationCore';
55

66
/**
7-
* Returns the boolean variation of a feature flag, re-rendering only when that specific flag changes.
7+
* Returns the boolean variation of a feature flag.
88
*
99
* @param key The feature flag key.
1010
* @param defaultValue The value to return if the flag is not available.
@@ -25,7 +25,7 @@ export function useBoolVariation(
2525
}
2626

2727
/**
28-
* Returns the string variation of a feature flag, re-rendering only when that specific flag changes.
28+
* Returns the string variation of a feature flag.
2929
*
3030
* @param key The feature flag key.
3131
* @param defaultValue The value to return if the flag is not available.
@@ -46,7 +46,7 @@ export function useStringVariation(
4646
}
4747

4848
/**
49-
* Returns the numeric variation of a feature flag, re-rendering only when that specific flag changes.
49+
* Returns the numeric variation of a feature flag.
5050
*
5151
* @param key The feature flag key.
5252
* @param defaultValue The value to return if the flag is not available.
@@ -67,7 +67,7 @@ export function useNumberVariation(
6767
}
6868

6969
/**
70-
* Returns the JSON variation of a feature flag, re-rendering only when that specific flag changes.
70+
* Returns the JSON variation of a feature flag.
7171
*
7272
* @param key The feature flag key.
7373
* @param defaultValue The value to return if the flag is not available.

packages/sdk/react/src/client/hooks/useVariationDetail.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import type { LDReactClientContextValue } from '../LDClient';
66
import useVariationCore from './useVariationCore';
77

88
/**
9-
* Returns the boolean variation and evaluation detail of a feature flag, re-rendering only when
10-
* that specific flag changes.
9+
* Returns the boolean variation and evaluation detail of a feature flag.
1110
*
1211
* @param key The feature flag key.
1312
* @param defaultValue The value to return if the flag is not available.
@@ -28,8 +27,7 @@ export function useBoolVariationDetail(
2827
}
2928

3029
/**
31-
* Returns the string variation and evaluation detail of a feature flag, re-rendering only when
32-
* that specific flag changes.
30+
* Returns the string variation and evaluation detail of a feature flag.
3331
*
3432
* @param key The feature flag key.
3533
* @param defaultValue The value to return if the flag is not available.
@@ -50,8 +48,7 @@ export function useStringVariationDetail(
5048
}
5149

5250
/**
53-
* Returns the numeric variation and evaluation detail of a feature flag, re-rendering only when
54-
* that specific flag changes.
51+
* Returns the numeric variation and evaluation detail of a feature flag.
5552
*
5653
* @param key The feature flag key.
5754
* @param defaultValue The value to return if the flag is not available.
@@ -72,8 +69,7 @@ export function useNumberVariationDetail(
7269
}
7370

7471
/**
75-
* Returns the JSON variation and evaluation detail of a feature flag, re-rendering only when
76-
* that specific flag changes.
72+
* Returns the JSON variation and evaluation detail of a feature flag.
7773
*
7874
* @param key The feature flag key.
7975
* @param defaultValue The value to return if the flag is not available.

packages/sdk/react/src/client/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export type * from '@launchdarkly/js-client-sdk';
22
export * from './LDClient';
33
export * from './LDOptions';
44

5-
export * from './provider/LDReactContext';
5+
export { LDReactContext, initLDReactContext } from './provider/LDReactContext';
66
export { createLDReactProvider, createLDReactProviderWithClient } from './provider/LDReactProvider';
77
export { createClient } from './LDReactClient';
88

packages/sdk/react/src/client/provider/LDReactContext.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ export function initLDReactContext(): LDReactClientContext {
1212
return createContext<LDReactClientContextValue>(null as any);
1313
}
1414

15+
/**
16+
* The LaunchDarkly React context.
17+
*/
1518
export const LDReactContext: LDReactClientContext = initLDReactContext();

0 commit comments

Comments
 (0)