JavaScript SDK
Learn to use the Harness FME JavaScript SDK for client-side feature management across various web frameworks and environments.
This guide provides detailed information about our JavaScript SDK. All of our SDKs are open source. Go to our JavaScript SDK GitHub repository to see the source code.
Before you begin
The JavaScript SDK supports all major browsers. While the library was built to support ES5 syntax, it depends on native support for ES6 Promise, Map, and Set objects, and therefore, you need to polyfill them if they are not available in your target browsers.
If you're looking for possible polyfill options, check es6-promise, es6-map and es6-set for Promise, Map and Set polyfills respectively.
Initialization
To set up Harness FME in your code base:
1. Import the SDK into your project
You can import the SDK into your project using either one of the methods below.
npm install --save @splitsoftware/splitio<script src="//cdn.split.io/sdk/split-11.9.0.min.js"></script>
2. Instantiate the SDK and create a new SDK factory client
UPDATING TO V10 FOR NPM VERSION
If you are using the CDN package or Bower, no changes are needed on your current code. We changed our module system to ES modules and now we are exposing an object with a SplitFactory property. That property points to the same factory function that we were returning in the previous versions. Refer to the snippet above to see the code.
Harness recommends instantiating the SDK factory once as a singleton and reusing it throughout your application.
Configure the SDK with the SDK key for the FME environment that you would like to access. In legacy Split (app.split.io) the SDK key is found on your Admin settings page, in the API keys section. Select a client-side SDK API key. This is a special type of API token with limited privileges for use in browsers or mobile clients. See API keys to learn more.
Use the SDK
Basic use
When the SDK is instantiated, it starts background tasks to update an in-memory cache with small amounts of data fetched from Harness servers. This process can take up to a few hundred milliseconds, depending on the size of data. If the SDK is asked to evaluate which treatment to show to a customer for a specific feature flag while it's in this intermediate state, it may not have the data necessary to run the evaluation. In this case, the SDK does not fail, rather, it returns the control treatment.
To make sure the SDK properly loads before asking it for a treatment, block until the SDK is ready, as shown below. We set the client to listen for the SDK_READY event triggered by the SDK before asking for an evaluation.
After the SDK_READY event fires, you can use the getTreatment method to return the proper treatment based on the feature flag name and the key you passed when instantiating the SDK. Then use an if-else-if block as shown below and insert the code for the different treatments that you defined in Harness FME. Remember the final else branch in your code to handle the client returning control.
Attribute syntax
To target based on custom attributes, the SDK's getTreatment method needs to be passed an attribute map at runtime.
In the example below, we are rolling out a feature to users. The provided attributes plan_type, registered_date, permissions, paying_customer, and deal_size are passed to the getTreatment call. These attributes are compared and evaluated against the attributes used in the rollout plan as defined in Harness FME to decide whether to show the on or off treatment to this account.
The getTreatment method has a number of variations that are described below. Each of these additionally has a variation that takes an attributes argument, which can defines attributes of the following types: strings, numbers, dates, booleans, and sets. The proper data type and syntax for each are:
Strings: Use type String.
Numbers: Use type Number.
Dates: Use type Date and express the value in
milliseconds since epoch. Note: Milliseconds since epoch is expressed in UTC. If your date or date-time combination is in a different timezone, first convert it to UTC, then transform it to milliseconds since epoch.Booleans: Use type Boolean.
Sets: Use type Array.
You can pass your attributes in exactly this way to the client.getTreatments method.
Binding attributes to the client
Attributes can optionally be bound to the client at any time during the SDK lifecycle. These attributes are stored in memory and used in every evaluation to avoid the need to keep the attribute set accessible through the whole app. When an evaluation is called, the attributes provided (if any) at evaluation time are combined with the ones that are already loaded into the SDK memory, with the ones provided at function execution time taking precedence. This enables those attributes to be overridden or hidden for specific evaluations.
An attribute is considered valid if it follows one of the types listed below:
String
Number
Boolean
Array
The SDK validates these before storing them and if there are invalid or missing values, possibly indicating an issue, the methods return the boolean false and do not update any value.
To use these methods, refer to the example below:
Multiple evaluations at once
In some instances, you may want to evaluate treatments for multiple feature flags at once. Use the different variations of getTreatments from the SDK factory client to do this.
getTreatments: Pass a list of the feature flag names you want treatments for.getTreatmentsByFlagSet: Evaluate all flags that are part of the provided set name and are cached on the SDK instance.getTreatmentsByFlagSets: Evaluate all flags that are part of the provided set names and are cached on the SDK instance.
Get treatments with configurations
To leverage dynamic configurations with your treatments, use the getTreatmentWithConfig method.
This method returns an object with the structure below:
As you can see from the object structure, the config is a stringified version of the configuration JSON defined in Harness FME. If there is no configuration defined for a treatment, the SDK returns null for the config parameter.
This method takes the exact same set of arguments as the standard getTreatment method. Refer to the examples below for proper usage:
If you need to get multiple evaluations at once, you can also use the getTreatmentsWithConfig methods. These methods take the exact same arguments as the getTreatments methods but return a mapping of feature flag names to TreatmentResults instead of strings. Example usage below:
If a flag cannot be evaluated, the SDK returns the fallback treatment value (default "control" unless overridden globally or per flag). For more information, see Fallback treatments.
Append properties to impressions
Impressions are generated by the SDK each time a getTreatment method is called. These impressions are periodically sent back to Harness servers for feature monitoring and experimentation.
You can append properties to an impression by passing an object of key-value pairs to the getTreatment method. These properties are then included in the impression sent by the SDK and can provide useful context to the impression data.
Three types of properties are supported: strings, numbers, and booleans.
Shutdown
Call the client.destroy() method before letting a process using the SDK exit, as this method gracefully shuts down the SDK by stopping all background threads, clearing caches, closing connections, and flushing the remaining unpublished impressions.
After destroy() is called and finishes, any subsequent invocations to getTreatment/getTreatments or manager methods result in control or empty list, respectively.
IMPORTANT!
A call to the destroy() method also destroys the factory object. When creating new client instance, first create a new factory instance.
Track
Use the track method to record any actions your customers perform. Each action is known as an event and corresponds to an event type. Calling track through one of our SDKs or via the API is the first step to getting experimentation data into Harness FME and allows you to measure the impact of your features on your users’ actions and metrics.
Learn more about tracking events.
In the examples below you can see that the .track() method can take up to four arguments. The proper data type and syntax for each are:
TRAFFIC_TYPE: The traffic type of the key in the track call. The expected data type is String. You can only pass values that match the names of traffic types that you have defined Harness FME.
EVENT_TYPE: The event type that this event should correspond to. The expected data type is String. Full requirements on this argument are:
Contains 63 characters or fewer.
Starts with a letter or number.
Contains only letters, numbers, hyphen, underscore, or period.
This is the regular expression we use to validate the value:
[a-zA-Z0-9][-_\.a-zA-Z0-9]{0,62}
VALUE: (Optional) The value to be used in creating the metric. This field can be sent in as null or 0 if you intend to purely use the count function when creating a metric. The expected data type is Integer or Float.
PROPERTIES: (Optional) An object of key value pairs that can be used to filter your metrics. Learn more about event property capture in the Events guide. FME currently supports three types of properties: strings, numbers, and booleans.
The track method returns a boolean value of true or false to indicate whether or not the SDK was able to successfully queue the event to be sent back to Harness servers on the next event post. The SDK will return false if the current queue size is equal to the config set by eventsQueueSize or if an incorrect input to the track method has been provided.
In the case that a bad input has been provided, you can read more about our SDK's expected behavior here.
Configuration
The SDK has a number of knobs for configuring performance. Each knob is tuned to a reasonable default. However, you can override the value while instantiating the SDK. The parameters available for configuration are shown below.
Configuration
Description
Default value
core.labelsEnabled
Enable impression labels from being sent to Harness servers. Labels may contain sensitive information.
true
startup.readyTimeout
Maximum amount of time in seconds to wait before firing the SDK_READY_TIMED_OUT event
10
startup.requestTimeoutBeforeReady
The SDK has two main endpoints it uses /splitChanges and /memberships that it hits to get ready. This config sets how long (in seconds) the SDK waits for each request it makes as part of getting ready.
5
startup.retriesOnFailureBeforeReady
How many retries on /splitChanges and /memberships we do while getting the SDK ready
1
startup.eventsFirstPushWindow
Use to set a specific timer (expressed in seconds) for the first push of events, starting on SDK initialization.
10
scheduler.featuresRefreshRate
The SDK polls Harness servers for changes to feature rollout plans. This parameter controls this polling period in seconds.
60
scheduler.segmentsRefreshRate
The SDK polls Harness servers for changes to segment definitions. This parameter controls this polling period in seconds.
60
scheduler.impressionsRefreshRate
The SDK sends information on who got what treatment at what time back to Harness servers to power analytics. This parameter controls how often this data is sent to Harness servers. The parameter should be in seconds.
300
scheduler.impressionsQueueSize
The max amount of impressions we queue. If the queue is full, the SDK flushes the impressions and resets the timer.
30000
scheduler.eventsPushRate
The SDK sends tracked events to Harness servers. This setting controls that flushing rate in seconds.
60
scheduler.eventsQueueSize
The max amount of events we queue. If the queue is full, the SDK flushes the events and resets the timer.
500
scheduler.telemetryRefreshRate
The SDK caches diagnostic data that it periodically sends to Harness servers. This configuration controls how frequently this data is sent back to Harness servers (in seconds).
3600 seconds (1 hour)
sync.splitFilters
Filter specific feature flags to be synced and evaluated by the SDK. This is formed by a type string property and a list of string values for the given criteria. Using the types 'bySet' (recommended, flag sets are available in all tiers) or 'byName', pass an array of strings defining the query. If empty or unset, all feature flags are downloaded by the SDK.
[]
sync.impressionsMode
This configuration defines how impressions (decisioning events) are queued on the SDK. Supported modes are OPTIMIZED, NONE, and DEBUG. In OPTIMIZED mode, only unique impressions are queued and posted to Harness; this is the recommended mode for experimentation use cases. In NONE mode, no impression is tracked in Harness FME and only minimum viable data to support usage stats is, so never use this mode if you are experimenting with that instance impressions. Use NONE when you want to optimize for feature flagging only use cases and reduce impressions network and storage load. In DEBUG mode, ALL impressions are queued and sent to Harness; this is useful for validations. This mode doesn't impact the impression listener which receives all generated impressions locally.
OPTIMIZED
sync.enabled
Controls the SDK continuous synchronization flags. When true, a running SDK processes rollout plan updates performed in Harness FME (default). When false, it fetches all data from the Harness FME servers only upon init, which ensures a consistent experience during a user session and optimizes resources when these updates are not consumed by the app.
true
sync.requestOptions.getHeaderOverrides
A callback function that can be used to override the Authentication header or append new headers to the SDK's HTTP(S) requests.
undefined
storage.type
Storage type to be used by the SDK. Possible values are MEMORY and LOCALSTORAGE.
MEMORY
storage.prefix
Only applies to the LOCALSTORAGE storage type. An optional prefix for your data to avoid collisions. This prefix is prepended to the existing "SPLITIO" localStorage prefix.
SPLITIO
storage.expirationDays
Only applies to the LOCALSTORAGE storage type. Number of days before cached data expires if it was not updated. If cache expires, it is cleared when the SDK is initialized.
10
storage.clearOnInit
Only applies to the LOCALSTORAGE storage type. When set to true, the SDK clears the cached data on initialization unless it was cleared within the last 24 hours. This 24-hour window is not configurable. If the cache is cleared (whether due to expiration or clearOnInit), both the 24-hour period and the expirationDays period are reset.
false
storage.wrapper
Only applies to the LOCALSTORAGE storage type. Storage wrapper used to persist the SDK cached data.
localStorage
debug
Either a boolean flag or log level string ('ERROR', 'WARN', 'INFO', or 'DEBUG'). See logging for details.
false
streamingEnabled
Boolean flag to enable the streaming service as default synchronization mechanism. In the event of an issue with streaming, the SDK falls back to the polling mechanism. If false, the SDK polls for changes as usual without attempting to use streaming.
true
userConsent
User consent status used to control the tracking of events and impressions. Possible values are GRANTED, DECLINED, and UNKNOWN. See User consent for details.
GRANTED
fallbackTreatments
Configure fallback treatments for the SDK.
undefined
To set each of the parameters defined above, use the following syntax:
Localhost mode
For testing, a developer can put code behind feature flags on their development machine without the SDK requiring network connectivity. To achieve this, the SDK can be started in localhost mode (aka off-the-grid or offline mode). In this mode, the SDK neither polls nor updates Harness servers. Instead, it uses an in-memory data structure to determine what treatments to show to the logged in customer for each of the features.
When instantiating the SDK in localhost mode, your authorizationKey is localhost. Define the feature flags you want to use in the features object map. All getTreatment calls for a feature flag now only return the one treatment (and config, if defined) that you have defined in the map.
Any feature that is not provided in the features map returns the control treatment if the SDK was asked to evaluate them.
You can use the additional configuration parameters below when instantiating the SDK in localhost mode.
Configuration
Description
Default value
scheduler.offlineRefreshRate
The refresh interval for the mocked features treatments.
15
features
A fixed mapping of which treatment to show for our mocked features.
{} By default we have no mocked features.
To use the SDK in localhost mode, replace the SDK key on authorizationKey property with 'localhost', as shown in the example below. Note that you can define in the features object a feature flag name and its treatment directly or use a map to define both a treatment and a dynamic configuration.
If you define just a string as the value for a feature flag name, any config returned by our SDKs are always null. If you use a map, we return the specified treatment and the specified config (which can also be null).
You can then change the feature flags as necessary for your testing, by mutating the properties of the features object you've provided. The SDK simulates polling for changes every offlineRefreshRate seconds, and will emit an SDK_UPDATE event if the mocked features have changed.
Localhost mode limitations and Allowlist workaround
JavaScript, React, Redux, and Browser SDKs use the features configuration parameter to set feature flags and treatment names when running in localhost mode. However, this mode does not support adding Allowlist keys within the features property, unlike the YAML file structure used in server-side SDKs.
To mimic the behavior of allowing specific keys to receive certain treatments, you can define multiple feature flag sets keyed by your user identifier and select the appropriate set dynamically. This approach lets you flip treatments based on the key, effectively simulating an Allowlist.
For example:
This approach provides a simple way to control feature flag treatments per user key while running your application locally.
Manager
Use the Split manager to get a list of features available to the SDK factory client. To instantiate a Manager in your code base, use the same factory that you used for your client.
The Manager then has the following methods available:
The SplitView object referenced above has the following structure:
Listener
FME SDKs send impression data back to Harness servers periodically and as a result of evaluating feature flags. To additionally send this information to a location of your choice, define and attach an impression listener. For that purpose, the SDK's configurations have a parameter called impressionListener where an implementation of ImpressionListener could be added. This implementation must define the logImpression method and it receives data in the following schema.
Name
Type
Description
impression
Object
Impression object that has the feature, key, treatment, label, etc.
attributes
Object
A map of attributes passed to getTreatment/getTreatments (if any).
sdkLanguageVersion
String
The version of the SDK. In this case the language is javascript plus the version currently running.
Implement custom impression listener
The following is an example of how to implement a custom impression listener:
An impression listener is called asynchronously from the corresponding evaluation, but is almost immediate.
Even though the SDK does not fail, if there is an exception in the listener, do not block the call stack.
Content Security Policy (CSP)
The Content Security Policy (CSP) can be enabled on a site that uses the JavaScript SDK. CSP is a security standard to prevent cross-site scripting (XSS) and other code injection attacks.
To allow the JavaScript SDK, you can use the nonce keyword to permit inline scripts securely:
Configure your server to send a response header like this (with your own random nonce value):
Content-Security-Policy: script-src 'self' cdn.split.io 'nonce-swfT4W3546RtDw4';.Add the matching nonce attribute to the script tag that uses the SDK:
Make sure the nonce value in the header and script tag match exactly. The nonce should be randomly generated per request for security.
Logging
To enable SDK logging in the browser, open your DevTools console and type the following:
Reload the browser to start seeing the logs.
Beginning with v9.2.0 of the SDK, you can also enable the logging via SDK settings and programmatically by calling the Logger API.
By default, the SDK uses the console.log method to output log messages for all log levels.
Since v11.7.0 of the SDK, you can provide a custom logger to handle SDK log messages by setting the logger configuration option or using the factory.Logger.setLogger method.
The logger object must implement the SplitIO.Logger interface, which is compatible with the console object and logging libraries such as winston, pino, and log4js. The interface is defined as follows:
The following example passes the console object as a logger, so that console.error, console.warn, console.info, and console.debug methods are called rather than the default console.log method.
Configure fallback treatments
Fallback treatments let you define a treatment value (and optional configuration) to be returned when a flag cannot be evaluated. By default, the SDK returns control, but you can override this globally or for individual flags at the SDK level.
This is useful when you want to:
Maintain a predictable user experience during outages or evaluation failures (avoid unexpected
controlin production)Protect critical user flows by returning a safe, stable treatment (for example, forcing
offduring an incident)Customize behavior per flag so each evaluation inherits appropriate safe defaults if something goes wrong
Global fallback treatment
Set a global fallback treatment when initializing the SDK factory. This value is returned whenever any flag cannot be evaluated.
Flag-level fallback treatment
You can also set a fallback treatment per flag when calling getTreatment or getTreatmentWithConfig. This flag-level fallback always takes precedence over the global fallback treatment, so if both are defined, the SDK will return the flag-level value when that flag cannot be evaluated.
For more information, see Fallback treatments.
Advanced use cases
This section describes advanced use cases and features provided by the SDK.
Instantiate multiple SDK clients
Each JavaScript SDK factory client is tied to one specific customer and traffic type at a time (for example, user, account, organization). This enhances performance and reduces data cached within the SDK.
FME supports the ability to release based on multiple traffic types. With traffic types, you can release to users in one feature flag and accounts in another. If you are unfamiliar with using multiple traffic types, refer to Traffic types for more information.
If you need to roll out features by different traffic types, instantiate multiple SDK clients, one for each traffic type. For example, you may want to roll out the feature user-poll by users and the feature account-permissioning by accounts. You can do this with the example below:
Subscribe to events
You can listen for four different events from the SDK.
SDK_READY_FROM_CACHE. This event fires when the SDK is ready to evaluate treatments. If the SDK is using theLOCALSTORAGEstorage type, it will attempt to use a locally cached version of your rollout plan from a previous session. By default, thelocalStorageAPI is used to cache the rollout plan (see Configuration for more information). If data is cached, this event fires almost immediately, since access to the cache is fast, but data might be stale. Otherwise, it fires together with theSDK_READYevent when the SDK downloads the rollout plan from Harness servers.SDK_READY. This event fires once the SDK is ready to evaluate treatments using the most up-to-date version of your rollout plan, downloaded from Harness servers.SDK_READY_TIMED_OUT. This event fires if the SDK could not download the data from Harness servers (SDK_READYevent), within the time specified by thestartup.readyTimeoutconfiguration parameter. This event does not indicate that the SDK initialization was interrupted. The SDK continues downloading the rollout plan and fires theSDK_READYevent when finished. This delayedSDK_READYevent may happen with slow connections or large rollout plans with many feature flags, segments, or dynamic configurations.SDK_UPDATE. This event fires whenever your rollout plan is changed. Listen for this event to refresh your app whenever a feature flag or segment is changed in Harness FME.
The syntax to listen for each event is shown below:
Include metadata
metadata provides additional context for events:
SDK_READY/SDK_READY_FROM_CACHE: IncludesinitialCacheLoad(true if no cached data from a previous session was available) andlastUpdateTimestamp(milliseconds since epoch when the cache was last updated).SDK_UPDATE: Includestype(FLAGS_UPDATEorSEGMENTS_UPDATE) andnames(list of impacted flags; empty for segment-only updates).SDK_READY_TIMED_OUT: No metadata is included.
For example:
Using readiness state and promises
The SDK_READY_FROM_CACHE, SDK_READY, and SDK_READY_TIMED_OUT events fire only once. Therefore, if an event listener is attached after the event has already fired, it will never be triggered.
For this reason, you can check the SDK readiness state using the client.getStatus() method to determine whether the SDK is ready to evaluate treatments, among other things:
As an alternative to event listeners, you can also use the client promise methods whenReady and whenReadyFromCache to wait for the SDK to become ready.
The
whenReadyFromCache()promise resolves once theSDK_READY_FROM_CACHEevent is emitted, or rejects if theSDK_READY_TIMED_OUTevent is emitted first.The
whenReady()promise resolves when theSDK_READYevent is emitted, or rejects if theSDK_READY_TIMED_OUTevent is emitted first. Subsequent calls toclient.whenReady()may return a new promise with a different settled state. For instance, a resolved promise if the SDK becomes ready after theSDK_READY_TIMED_OUTevent was triggered first.
User consent
The SDK allows you to disable the tracking of events and impressions until user consent is explicitly granted or declined.
The userConsent configuration parameter lets you set the initial consent status of the SDK instance, and the factory method UserConsent.setStatus(boolean) lets you grant (enable) or decline (disable) dynamic data tracking.
There are three possible initial states:
'GRANTED': The user grants consent for tracking events and impressions. The SDK sends them to Harness FME servers. This is the default value ifuserConsentparam is not defined.'DECLINED': The user declines consent for tracking events and impressions. The SDK does not send them to Harness FME servers.'UNKNOWN': The user neither grants nor declines consent for tracking events and impressions. The SDK tracks them in its internal storage, and eventually either sends them or not if the consent status is updated to'GRANTED'or'DECLINED'respectively.
The status can be updated at any time with the UserConsent.setStatus factory method.
Working with user consent is demonstrated below.
Example apps
The following example applications detail how to configure and instantiate the JavaScript SDK on commonly used platforms:
Troubleshooting
User IDs Being Double Bucketed (SDK_READY_TIMED_OUT Event Issue)
Using the JavaScript SDK, some percentage of User IDs are double bucketed: the same User ID is processed in the Control block, and at a later call in an actual treatment block.
One possible root cause is that the JavaScript SDK engine completes fetching treatments after the startup.requestTimeoutBeforeReady or startup.readyTimeout parameter expires, firing the browser event SDK_READY_TIMED_OUT.
This tends to happen for mobile users with slow internet connections.
If the JavaScript code does not properly handle this event, for example, if it only raises an error and exits:
There are two possible events:
If the
SDK_READYevent comes first, the promise resolves, and everything works as expected.If the
SDK_READY_TIMED_OUTevent comes first, the promise rejects and remains rejected, meaning that any.catch()attached will always be called, even if the SDK eventually becomes ready later.
If you add a .catch() that does not return or throw an error, the wrapper code might continue executing as if the SDK is ready, even when it is not. For example:
Here, the .catch() swallows the error without returning or throwing, causing the promise chain to appear "recovered." This can cause code to run prematurely against an SDK that isn’t ready.
Even if the SDK_READY_TIMED_OUT event fires, the SDK might become ready a few milliseconds later and emit the SDK_READY event. You should handle these events only when you actually want to respond to them.
Allow the SDK to retry fetching treatments a couple of times before giving up, increasing the chance the SDK becomes ready within the timeout:
Configure the SDK to store
SplitsandmySegmentsdata in the browser’sLOCALSTORAGE. This caches data between page loads and reduces fetch time on subsequent page visits, making the SDK ready faster:Use a custom prefix to prevent data collision across projects.
For more information, see the API reference documentation.
CORS Error in streaming call when running the SDK in a Service Worker
When running the JavaScript SDK inside a Service Worker, the SDK’s streaming HTTP call to streaming.split.io can be blocked by the browser’s CORS policy.
A Service Worker acts as a proxy between the browser and the network, intercepting requests and optionally redirecting them to a cache. While this enables offline access, it also means requests (such as the SDK’s Server-Sent Events (SSE) stream) must be explicitly handled in the Service Worker.
If SSE requests are not correctly handled (for example, when adding cache-control headers without accounting for SSE), the streaming connection between the SDK and Split’s backend can fail due to CORS restrictions.
To properly handle SSE streaming connections, add logic to your Service Worker’s fetch event listener that detects SSE requests and allows them through.
Alternatively, you can explicitly bypass certain requests in your fetch event listener:
"Shared Client not supported by the storage mechanism. Create isolated instances instead" error
When testing the JavaScript SDK browser mode using Jest, it fails with the following error:
When using Jest for testing applications, Jest runs in Node.js by default, and Node.js does not support shared clients, which is why it detects the storage does not have that function. It is not possible to overwrite that method from the outside.
You can instruct Jest to explicitly resolve to browser by setting the config in Jest options. For example, when using the package.json file, we can add the flag:
For more information, see the official Jest documentation.
Building JavaScript SDK using polymer-cli causes error: ENOENT: no such file or directory
Using the following environment:
@polymer/polymer: 3.1.0polymer-cli: 1.9.6
Steps to reproduce:
Install the SDK:
npm i @splitsoftware/splitio@10.6.0.Import via ES module:
Run
polymer build.
You encounter the following error:
Polymer's build process differs from bundlers like webpack. It attempts to load the Node.js path of the SDK, which requires the events module, a Node core module unavailable in browser environments.
The SDK package contains both Node and browser versions with:
While Node.js uses the main field (node.js), bundlers are instructed to use the browser-specific code (browser.js). Polymer’s build does not respect this configuration, leading to the error.
If you plan to implement the JavaScript SDK in both server and browser modes with Polymer, ensure your build configuration properly sets the browser and main fields to the corresponding JavaScript files to load the correct version.
Why does the JavaScript SDK return Not Ready status on slow networks?
When using the JavaScript SDK in a browser, the SDK status often remains as Not Ready when users are on a slow network connection (e.g., 3G).
The SDK takes longer to fetch feature flags and segment data from Harness FME servers over slow networks. This delay can cause the SDK to fall back to control treatments since it has not yet completed initialization.
Increase the startup.readyTimeout and startup.requestTimeoutBeforeReady values to ensure they cover the time needed to fetch FME definitions on slower networks.
Measure the fetch duration on a slow network (e.g., using Chrome DevTools to simulate 3G).
Enable SDK debug logging in the browser console:
Reload the page and look for the debug line:
Where
xxxxis the fetch duration in milliseconds.Set the
startup.requestTimeoutBeforeReadyandstartup.readyTimeoutin your SDK initialization to a value higher than the fetch duration, for example:To reduce network usage, enable local caching of the FME definition by specifying storage when initializing the SDK:
This configuration ensures the SDK does not have to fetch definitions on every page load, improving readiness on slow or unstable networks.
Why does the JavaScript URL return HTTP 404 error?
When using the JavaScript SDK, the following URL request generates a 404 error:
The URL is missing the required key ID (also known as customer ID). For example, if the key ID is 8879, the URL should be:
Ensure you specify the key or customer ID correctly in the SDK factory initialization and when fetching the client object, for example:
This correctly appends the key ID to the URL and prevents the 404 error.
Last updated
Was this helpful?