All notable changes to the LaunchDarkly client-side JavaScript SDKs will be documented in this file. This project adheres to Semantic Versioning.
- If there are pending analytics events when the page is being closed, the SDK normally attempts to deliver them by making a synchronous HTTP request. Chrome, as of version 73, does not allow this and logs an error. An upcoming release will change how events are sent, but as a temporary measure to avoid these errors, the SDK will now simply discard any pending events when the page is being closed if the browser is Chrome version 73 or higher. In other browsers, there is no change. Note that this means that in Chrome 73, some events may be lost; that was already the case. The purpose of this patch is simply to avoid triggering errors. (#178)
This release was an error and has been removed.
- In React, when using the
bootstrap
property to preload the SDK client with flag values, the client will now become ready immediately and make the flags available to other components as soon as it is initialized; previously this did not happen until aftercomponentDidMount
. - The user attribute
secondary
was not included in the TypeScript declarations and therefore could not be used from TypeScript code.
- Running inside an iframe on Chrome with third-party cookies disabled-- which also disables HTML5 local storage-- would cause a security exception (due to the SDK attempting to check whether
window.localStorage
exists). This was a long-standing problem, but became worse in the 2.9.0 release since the SDK now checks for browser capabilities like this regardless of whether you've attempted to use them yet. It should now simply log a warning if you try to usebootstrap: "localstorage"
when local storage is disabled. (#138) - If the SDK received streaming updates out of order (rare, but possible) such that it received "flag X was deleted" prior to "flag X was created", an uncaught exception would be logged in the browser console (but would not otherwise affect anything).
- A supported user property,
privateAttributeNames
, was not usable from TypeScript because it was omitted from the TypeScript declarations. - Several TypeScript declarations had been changed from
interface
totype
. They all now useinterface
, except forLDFlagValue
which is a type alias. This should not affect regular usage of the SDK in TypeScript, but it is easier to extend aninterface
than atype
if desired. - Removed a window message listener that was previously used for integration with the LaunchDarkly dashboard, but is no longer used.
- The React SDK was pulling in the entire
lodash
package. This has been improved to only require the much smallercamelcase
tool fromlodash
. - The React SDK now lists React itself as a peer dependency rather than a regular dependency, so it will not included twice in an application that already requires React.
- Corrected the TypeScript declaration for the
identify
method to indicate that its asynchronous result type isLDFlagSet
, notvoid
. (Thanks, impressiver!) - Corrected and expanded many documentation comments in the TypeScript declarations.
(The 2.9.2 release was broken and has been removed.)
- The previous release of
ldclient-react
was broken: the package did not contain the actual files. The packaging script has been fixed. There are no other changes.
- The new
ldclient-react
package provides a convenient mechanism for using the LaunchDarkly SDK within the React framework. - The new
getUser()
method returns the current user object. - The client options can now have a
logger
property that defines a custom logging mechanism. The default is still to useconsole.warn
andconsole.error
; you could override this to send log messages to another destination or to suppress them. SeeLDLogger
andcreateConsoleLogger
in the TypeScript definitions.
- The SDK now uses an additional package,
ldclient-js-common
, consisting of code that is also used by other LaunchDarkly SDKs. This is automatically loaded as a dependency ofldclient-js
so you should notice any difference. However, the source code has been reorganized so that this project is now a monorepo containing multiple packages.
- The use of a streaming connection to LaunchDarkly for receiving live updates can now be controlled with the new
client.setStreaming()
method, or the equivalent booleanstreaming
property in the client configuration. If you set this tofalse
, the client will not open a streaming connection even if you subscribe to change events (you might want to do this if, for instance, you just want to be notified when the client gets new flag values due to having switched users). If you set it totrue
, the client will open a streaming connection regardless of whether you subscribe to change events or not (the flag values will simply be updated in the background). If you don't set it either way then the default behavior still applies, i.e. the client opens a streaming connection if and only if you subscribe to change events.
- If the client opened a streaming connection because you called
on('change', ...)
one or more times, it will not close the connection until you calloff()
for all of your event listeners. Previously, it was closing the connection wheneveroff('change')
was called, even if you still had a listener for'change:specific-flag-key'
. - The client's logic for signaling a
change
event was using a regular Javascript===
comparison, so it could incorrectly decide that a flag had changed if its value was a JSON object or an array. This has been fixed to use deep equality checking for object and array values.
- When using the
event-source-polyfill
package to allow streaming mode in browsers with no native EventSource support, the polyfill was using a default read timeout of 45 seconds, so if no updates arrived within 45 seconds it would log an error and reconnect the stream. The SDK now sets its own timeout (5 minutes) which will be used if this particular polyfill is active. LaunchDarkly normally sends a heartbeat every 3 minutes, so you should not see a timeout happen unless the connection has been lost. - The SDK's use of the "Base64" package caused problems for build tools that strictly enforce the lowercase package name rule. It now uses the "base64-js" package instead. (#124)
(This version was skipped due to a release problem.)
- The TypeScript definitions were incorrectly restricting the possible values for event types in
on()
andoff()
. Also, added documentation for event types which were not documented before. (#122)
- Disconnecting from the stream does not close the browser tab anymore. (Thanks, Sawtaytoes.)
- The configuration property
evaluationReasons
was misnamed asevaluationExplanations
in the TypeScript definitions.
- Event posts did not include the HTTP header that specifies the SDK version. They now do again. Note that the
sendLDHeaders
option does not affect this; if the header is turned off for flag requests, it should still be sent in events, since events always require a CORS preflight check anyway (and are delivered asynchronously, so the OPTIONS request does not slow down page loads).
- New client method
waitForInitialization
returns a Promise, likewaitUntilReady
; but whilewaitUntilReady
will be resolved as soon as client initialization either succeeds or fails,waitForInitialization
will be resolved only if initialization succeeds, and will be rejected (with an error object) if it fails. - New config option
fetchGoals
(default: true) allows you to control whether the client will request A/B testing parameters from LaunchDarkly. If you do not use A/B testing, you may wish to disable this to reduce the number of HTTP requests. - New config option
sendLDHeaders
(default: true) allows you to control whether the client will add a custom HTTP header to LaunchDarkly flag requests (to indicate the SDK version). You may wish to disable this behavior if you have performance concerns, as it causes browsers to make an additional CORS preflight check (since it is no longer a simple request).
- The new configuration option
evaluationReasons
causes LaunchDarkly to report information about how each feature flag value was determined; you can access this information with the new client methodvariationDetail
. The new method returns an object that contains both the flag value and a "reason" object which will tell you, for instance, if the user was individually targeted for the flag or was matched by one of the flag's rules, or if the flag returned the default value due to an error.
- In streaming mode, the client will attempt to reconnect if it receives an HTTP error status from LaunchDarkly. Previously, it would only retry if the connection was lost.
- Starting in version 2.0.0, there was a problem where analytics events would not be generated correctly if you initialized the client with bootstrap data, because the bootstrap data did not include some flag metadata that the front end uses for events. The client now supports an extended format for bootstrap data that fixes this problem; this is generated by calling a new method that has been added to the server-side SDKs,
allFlagsState
/all_flags_state
(previouslyallFlags
/all_flags
). Therefore, if you want analytics event data and you are using bootstrap data from the back end, you should upgrade both your JavaScript SDK and your server-side SDK, and useallFlagsState
on the back end. This does not require any changes in your JavaScript code. If you use bootstrap data in the old format, the SDK will still be usable but events will not work correctly. - When posting events to LaunchDarkly, if a request fails, it will be retried once.
- The TypeScript mappings for the SDK were omitted from the distribution in the previous release. They are now in the distribution again, in the root folder instead of in
src
, and have been renamed fromindex.d.ts
totypings.d.ts
.
- The result value of
identify()
(provided by either a promise or a callback, once the flag values for the new user have been retrieved) used to be a simple map of flag keys to values, until it was accidentally changed to an internal data structure in version 2.0.0. It is now a map of flag keys to values again, consistent with what is returned byallFlags()
. - Added TypeScript definitions for the result values of
identify()
. (Thanks, 1999!) - Documented all optional compatibility polyfills in
README.md
.
- Named exports for the
initialize
method andversion
number exports.
- Default exports, use named exports instead.
- Updated
package.json
to only export minified files.
- If a polling request has failed due to an invalid environment key, calling
variation
now returns the default value; previously, it sometimes caused a null reference error.
- The client will now stop trying to send analytics events if it receives almost any HTTP 4xx error from LaunchDarkly; such errors indicate either a configuration problem (invalid SDK key) or a bug, which is not likely to resolve without a restart or an upgrade. This does not apply if the error is 400, 408, or 429.
- New event
goalsReady
(and new methodwaitUntilGoalsReady
, which returns a Promise based on that event) indicates when the client has loaded goals-- i.e. when it is possible for pageview events and click events to be triggered.
- Fixed a bug where calling
variation
would throw an error if the client was bootstrapped from local storage and there were no flags in local storage yet, and the initial HTTP request for flags from LaunchDarkly had not yet completed. (thanks, mpcowan!)
- Fix the TypeScript definitions to properly support the ES default export.
- Removed two function calls that are not supported in Internet Explorer:
string.startsWith()
andObject.assign()
.
- The client now sends the current SDK version to LaunchDarkly in an HTTP header. This information will be visible in a future version of the LaunchDarkly UI.
- Fixed a bug that caused summary events to combine the counts for flag evaluations that produced the flag's first variation (variation index 0) with the counts for flag evaluations that fell through to the default value.
- To reduce the network bandwidth used for analytics events, feature request events are now sent as counters rather than individual events, and user details are now sent only at intervals rather than in each event. These behaviors can be modified through the LaunchDarkly UI and with the new configuration option
inlineUsersInEvents
. For more details, see Analytics Data Stream Reference. - In every function that takes an optional callback parameter, if you provide a callback, the function will not return a promise; a promise will be returned only if you omit the callback. Previously, it would always return a promise which would be resolved/rejected at the same time that the callback (if any) was called; this caused problems if you had not registered an error handler for the promise.
- When sending analytics events, if there is a connection error or an HTTP 5xx response, the client will try to send the events again one more time after a one-second delay.
- Analytics are now sent with an HTTP
POST
request if the browser supports CORS, or via image loading if it does not. Previously, they were always sent via image loading.
- The new configuration option
sendEventsOnlyForVariation
, if set totrue
, causes analytics events for feature flags to be sent only when you callvariation
. Otherwise, the default behavior is to also send events when you callallFlags
, and whenever a changed flag value is detected in streaming mode. - The new configuration option
allowFrequentDuplicateEvents
, if set totrue
, turns off throttling for feature flag events. Otherwise, the default behavior is to block the sending of an analytics event if another event with the same flag key, flag value, and user key was generated within the last five minutes.
- If
identify
is called with a null user, or a user with no key, the function no longer tries to do an HTTP request to the server (which would always fail); instead, it just returns an error.
- The configuration options
all_attributes_private
andprivate_attribute_names
are deprecated. UseallAttributesPrivate
andprivateAttributeNames
instead.
- Fixed a bug that caused events not to be sent if
options.sendEvents
was explicitly set totrue
. - HTTP requests will no longer fail if there is a
charset
specified in the response'sContent-Type
header. (#87)
- The client no longer creates an empty
XMLHttpRequest
at startup time (which could interfere with unit tests).
This release was broken and should not be used.
This release was broken and should not be used.
- The build now uses Rollup, Babel and Jest.
- Fixed a bug that caused a syntax error when running in Internet Explorer 11.
- Fixed an IE 11 incompatibility in the example page index.html.
- Fixed a bug that caused the SDK to send events on beforeunload even if it should not send events.
LDClient.track
properly sets the user for custom events.
- The SDK now polls the URL for changes if (and only if) there are page view goals,to ensure it is accurately reporting page views.
- Added support for a future update to LaunchDarkly that will deliver individual feature flag changes over the streaming connection as they occur, rather than requiring the client to re-request all flags for each change.
- The new flush method on the client object tells the client to deliver any stored analytics events as soon as possible, rather than waiting for the regularly scheduled event-flushing interval.
- Fixed a bug that could prevent events from being generated for page view goals.
- Removed usage of the
const
keyword, to maintain IE10 compatibility. (Thanks, turnerniles!)
- The
options
object now supports asamplingInterval
property. If greater than zero, this causes a fraction of analytics events to be sent to LaunchDarkly: one per that number of events (pseudo-randomly). For instance, setting it to 5 would cause 20% of events to be sent on average.
- The SDK now supports multiple environments. Calling
initialize
returns a new client each time. - The
waitUntilReady
Promise
will now resolve even after theready
event was emitted — thanks @rmanalan!
- Methods that expose a
Promise
interface now properly return the resolution or rejection value to the caller.
- Support for private user attributes.
- New
sendEvents
option to control whether the SDK should send events back to LaunchDarkly or not. Defaults totrue
. - It is now possible to wait for SDK readiness using
waitUntilReady
which returns aPromise
.identify
also returns aPromise
(while still supporting the callback argument), which should make it easier to integrate into code that relies heavily onPromise
's for asynchronous code. - The SDK now respects the user's do-not-track setting
- Added
useReport
initialization option to useREPORT
instead ofGET
when communicating with LaunchDarkly. - Authentication errors will now be logged — the root cause for these errors is usually an invalid client-side ID.
- Emit an
error
event — separately from theready
event — in case fetching initial data fails. This allows consumers to respond accordingly.
- Improve error handling
- Add typescript definitions
- Add a warning when tracking unknown custom goal events
- Changed default stream url
- Cached
localStorage
copy is not overwritten anymore when connection to LD fails
onDone
argument toidentify
method is now optional
- Removed dependency on Sizzle and direct to polyfill for older browser support
- Fix bug in
Emitter.off()
- Fix bug caused by accessing
undefined
flags
- Fix bug caused by accessing
undefined
settings
- Ensure callbacks only ever get called once
- Fix flag setting request cancellation logic
- Add a new
allFlags
method that returns a map of all feature flag keys and their values for a user
- Added 'undefined' check on VERSION otherwise unbundled usage from npm fails
- Expose SDK version at
LDClient.version
- Added check for EventSource before trying to connect Stream.
- Fixed an error that occurred on
hashchage
/popstate
if the account had no goals.
- Added window check for server side rendering compatibility before loading Sizzle.