Skip to main content

DevCycle JavaScript Client SDK

The DevCycle JS SDK, like all client SDKs, will retrieve a configuration for the provided User upon initialization. The configuration which is retrieved contains all of the Features and Variables, meaning no further outbound network calls will be made to retrieve Feature information unless explicitly specified.

The JS SDK is available on NPM as an open-source package that can be viewed on the DevCycle GitHub.

Npm package version GitHub

Installation​

1. NPM Module​

The recommended way to include the JS SDK is by bundling it with the rest of your application code using our NPM Module.

The JS SDK library can be found on NPM. To get started, install the JS SDK using NPM:

npm install --save @devcycle/devcycle-js-sdk

To use the JS SDK in your project, import the initialize function:

import { initialize } from "@devcycle/devcycle-js-sdk";

2. Using the CDN​

If you want to load the JS SDK on your webpage separately from your main application bundle, you can use a script tag to do so.

Place the following code snippet as high as possible in your head tag.

<script
src="https://js.devcycle.com/devcycle.min.js"
type="text/javascript"
></script>

Getting Started​

  • If the JS SDK is installed using NPM, callΒ initialize with your client key, a user object, and an optional options object.
  • Otherwise, If you’re using the CDN to install the JS SDK, call DevCycle.initialize with your client key, a user object, and an optional options object.

The user object needs either a user_id, or isAnonymous set to true for an anonymous user. The options object is optional, but can passed a logWriter for a custom logging solution and a logLevel, which must be one of info, debug, warn or error. The default options are to set the logWriter to be the console and the logLevel to error.

const user = { user_id: "my_user" };
const dvcOptions = { logLevel: "debug" };
const dvcClient = initialize("YOUR_CLIENT_KEY", user, dvcOptions); // replace initialize with DevCycle.initialize if using the CDN

DVC User Object​

DVCUser Typescript Schema

PropertyTypeDescription
isAnonymousbooleanBoolean to indicate if the user is anonymous
user_idstringUnique user ID
emailstringUser's email
namestringUser's name
languagestringUser's language
countrystringUser's country
appVersionstringApp version
appBuildnumberApp build
customDataDVCJSONKey/value map of properties to be used for targeting
privateCustomDataDVCJSONKey/value map of properties to be used for targeting. Private properties will not be included in event logging.

Initialization Options​

The SDK exposes various initialization options which can be set on the initialization() method:

DVCOptions Typescript Schema

DVC OptionTypeDescription
eventFlushIntervalMSnumberControls the interval between flushing events to the DevCycle servers in milliseconds, defaults to 10 seconds.
enableEdgeDBbooleanEnables the usage of EdgeDB for DevCycle that syncs User Data to DevCycle.
loggerDVCLoggerLogger override to replace default logger
logLevelDVCDefaultLogLevelSet log level of the default logger. Options are: debug, info, warn, error. Defaults to info.
apiProxyURLstringAllows the SDK to communicate with a proxy of DVC bucketing API / client SDK API.

Waiting for Features​

You can wait on the features to be loaded from our servers by using .onClientInitialized() function. It returns a promise that you can use to wait until features are ready to be used:

dvcClient.onClientInitialized().then(() => {
const featureToggle = dvcClient.variable('YOUR_VARIABLE_KEY', false)
if (featureToggle.value) {
...
} else {
...
}
})

You can also pass in a callback which will get called after the features are loaded:

dvcClient.onClientInitialized((err) => {
if (err) {
// error state
}

const featureToggle = dvcClient.variable('YOUR_VARIABLE_KEY', false)
if (featureToggle.value) {
...
} else {
...
}
})

Getting Variable Values​

To get values from your Features, .variable is used to fetch variable values using the identifier key coupled with a default value. The default value can be of type string, boolean, number, or object.

const variable = dvcClient.variable("YOUR_VARIABLE_KEY", "default value");

To grab the value, there is a property on the object returned to grab the value:

const value = variable.value;

If the value is not ready, it will return the default value passed in the creation of the variable.

The onUpdate accepts a handler function that will be called whenever a variable value has changed. This can occur as a result of a project configuration change or calls to identifyUser or resetUser. To learn more, visit our Realtime Updates page.

There can only be one onUpdate function registered at a time. Subsequent calls to this method will overwrite the previous handler:

variable.onUpdate((value) => {
// value returned when the value of the variable changes
});

The DVCVariable type interface can be found here.

Identifying User​

To identify a different user, or the same user passed into the initialize with more attributes, pass in the entire user attribute object into identifyUser:

const user = {
user_id: "user1",
name: "user 1 name",
customData: {
customKey: "customValue",
},
};
dvcClient.identifyUser(user);

To wait on Variables that will be returned from the identify call, you can pass in a callback or use the Promise returned if no callback is passed in:

const variableSet = await dvcClient.identifyUser(user);

// OR

dvcClient.identifyUser(user, (err, variables) => {
// variables is the variable set for the identified user
});

Reset User​

To reset the user into an anonymous user, resetUser will reset to the anonymous user created before or will create one with an anonymous user_id.

dvcClient.resetUser();

To wait on the Features of the anonymous user, you can pass in a callback or use the Promise returned if no callback is passed in:

const variableSet = await client.resetUser();

// OR

dvcClient.resetUser((err, variables) => {
// variables is the variable set for the anonymous user
});

Get All Features​

To retrieve all the Features returned in the config:

const features = dvcClient.allFeatures()

If the SDK has not finished initializing, these methods will return an empty object. Read Waiting for Features to mitigate this.

See getFeatures in the Bucketing API for detailed response formats.

Get All Variables​

To grab all the Features returned in the config:

const variables = dvcClient.allVariables()

If the SDK has not finished initializing, these methods will return an empty object. Read Waiting for Features to mitigate this.

See getVariables in the Bucketing API for detailed response formats.

Tracking Events​

To track events, pass in an object with at least a type key:

const event = {
type: "my_event_type", // this is required
date: new Date(),
target: "my_target",
value: 5,
metaData: {
key: "value",
},
};
dvcClient.track(event);

The SDK will flush events every 10s or flushEventsMS specified in the options. To manually flush events, call:

await dvcClient.flushEvents();

// or

dvcClient.flushEvents(() => {
// called back after flushed events
});

Subscribing to SDK Events​

The SDK can emit certain events when specific actions occur which can be listened on by subscribing to them:

dvcClient.subscribe(
"variableUpdated:*",
(key: string, variable: DVCVariable) => {
// key is the variable that has been updated
// The new value can be accessed from the variable object passed in: variable.value
console.log(`New variable value for variable ${key}: ${variable.value}`);
}
);

The first argument is the name of the event that you can subscribe to. The subscribe method will throw an error if you try to subscribe to an event that doesn't exist. These are the events you can subscribe to:

EventKeyHandler ParamsDescription
Initializedinitialized(initialized: boolean)An initialized event is emitted once the SDK has received its first config from DevCycle. This event will only be emitted once.
Errorerror(error: Error)If any error occurs in the SDK, this event emits that error.
Variable UpdatedvariableUpdated:*(key: string, variable: DVCVariable)This event gets triggered when a variable value changes for a user. You can subscribe to all variable updates using the * identifier, or you can pass in the key of the variable you want to subscribe to, e.g. variableUpdated:my_variable_key.
Feature UpdatedfeatureUpdated:*(key: string, feature: DVCFeature)This event gets triggered when a feature's variation changes for a user. You can subscribe to all feature updates using the * identifier, or you can pass in the key of the feature you want to subscribe to, e.g. featureUpdated:my_feature_key.

EdgeDB​

EdgeDB allows you to save user data to our EdgeDB storage so that you don't have to pass in all the user data every time you identify a user.

To get started, contact us at [email protected] to enable EdgeDB for your project.

Once you have EdgeDB enabled in your project, pass in the enableEdgeDB option to turn on EdgeDB mode for the SDK:

const user = {
user_id: "my_user",
customData: {
amountSpent: 50,
},
};
const options = {
enableEdgeDB: true,
};
const dvcClient = initialize("YOUR_CLIENT_KEY", user, options);

This will send a request to our EdgeDB API to save the custom data under the user my_user.

In the example, amountSpent is associated to the user my_user. In your next identify call for the same user_id, you may omit any of the data you've sent already as it will be pulled from the EdgeDB storage when segmenting to experiments and features:

dvcClient.identifyUser({ user_id: 'my_user' }) // no need to pass in "amountSpent" any more!