Skip to content

Conversation

@joker23
Copy link
Contributor

@joker23 joker23 commented Dec 1, 2025

This PR will add a new browser SDK example that works with the new 4.x implementation.

I think this also addressed sdk-744


Note

Adds a new browser SDK example app with build/run tooling and includes it in workspaces.

  • Example app (packages/sdk/browser/example):
    • App code: Adds index.html, index.css, and src/app.ts demonstrating initialize, identify, variation, and change/error listeners with simple UI updates.
    • Build/run: Adds package.json scripts (start, build), tsconfig.json, and tsdown.config.ts that substitutes LD_CLIENT_SIDE_ID/LD_FLAG_KEY from .env.template into dist/app.js.
    • Docs: Adds README.md with setup instructions.
  • Monorepo:
    • Adds packages/sdk/browser/example to root package.json workspaces.

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

@joker23 joker23 requested a review from a team as a code owner December 1, 2025 19:50
@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2025

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

@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2025

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

@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2025

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

@joker23 joker23 force-pushed the skz/sdk-1649/create-javascript-example branch from cd49047 to 1048727 Compare December 1, 2025 19:58
@github-actions
Copy link
Contributor

github-actions bot commented Dec 1, 2025

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

@joker23 joker23 force-pushed the skz/sdk-1649/create-javascript-example branch 2 times, most recently from 126daf7 to d701b99 Compare December 1, 2025 23:24
@joker23 joker23 force-pushed the skz/sdk-1649/create-javascript-example branch from 10632da to 580a21a Compare December 2, 2025 15:18
@joker23 joker23 force-pushed the skz/sdk-1649/create-javascript-example branch from 580a21a to f4ad1e7 Compare December 2, 2025 16:04
@joker23
Copy link
Contributor Author

joker23 commented Dec 5, 2025

NOTE: this example will probably change after we merge #1028

import { initialize } from '@launchdarkly/js-client-sdk';

// Set clientSideID to your LaunchDarkly client-side ID
const clientSideID = '';
Copy link
Member

Choose a reason for hiding this comment

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

If we could set this up to work with a .env, or regular environment variable, then that would be good.

Generally speaking this approach results in accidental commits of tokens. Client-side IDs are not secret, so it isn't a big issue, but still nice to not have to worry about it.

If you do use a .env, then you can make sure it is in the git ignore.

Copy link
Member

Choose a reason for hiding this comment

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

(We can do the same thing with the flagKey, for convenience.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yea for this kind of example, I think we can inject those values during build time... I'll refactor this example, once we get the waitForInit PR in.

render();
});

ldclient.identify(context).catch(() => {
Copy link
Member

Choose a reason for hiding this comment

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

Now that we moved to a result returning method, we shouldn't need the catch, correct? Or we need to make sure we cannot throw from that method.

Copy link
Member

Choose a reason for hiding this comment

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

I think we can assume top-level await? Then just await the result?

@joker23 joker23 requested a review from kinyoklion December 8, 2025 16:44
render();
} else if (status === 'error') {
div.replaceChild(document.createTextNode('Error identifying client'), div.firstChild as Node);
}
Copy link

Choose a reason for hiding this comment

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

Bug: Missing handling for timeout and shed identify statuses

The identify method returns an LDIdentifyResult with four possible status values: completed, error, timeout, and shed. The code only handles completed and error, leaving timeout and shed unhandled. When these occur, the UI remains stuck on "Initializing..." with no user feedback. This is particularly relevant since the browser SDK sets sheddable: true by default, making shed status a realistic scenario.

Fix in Cursor Fix in Web

Copy link
Member

Choose a reason for hiding this comment

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

@joker23 Can we just always render, and when the status is an error additionally show the error box. This would be closer to what we expect.

Also, do we need the try catch?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yea I can get rid of the try catch now that we aren't throwing anything and I'll add a status box to track errors.

@joker23 joker23 force-pushed the skz/sdk-1649/create-javascript-example branch from d20bdad to 30d81c6 Compare December 8, 2025 16:48
Copy link
Member

Choose a reason for hiding this comment

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

nit: Newlines at the end of files.

}
const flagKey = LD_FLAG_KEY || 'sample-feature';
const content = fs.readFileSync(OUTPUT_FILE).toString();
fs.writeFileSync(OUTPUT_FILE, content.replaceAll(FLAG_KEY_PLACEHOLDER, flagKey));
Copy link

Choose a reason for hiding this comment

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

Bug: Inconsistent fallback behavior for build-time configuration variables

The build configuration has inconsistent handling of environment variables. LD_FLAG_KEY gets a sensible default ('sample-feature') when not provided, but LD_CLIENT_SIDE_ID has no default and leaves the literal placeholder string 'LD_CLIENT_SIDE_ID' in the built output. This causes the SDK to silently fail initialization with an invalid client-side ID if the user forgets to configure it.

Fix in Cursor Fix in Web

@joker23 joker23 force-pushed the skz/sdk-1649/create-javascript-example branch from c87a4d5 to 4ba5b0b Compare December 9, 2025 17:36
@joker23 joker23 merged commit 0486ac8 into main Dec 9, 2025
36 checks passed
@joker23 joker23 deleted the skz/sdk-1649/create-javascript-example branch December 9, 2025 17:44
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.

3 participants