Skip to main content

Javascript Client

Get your Featureflow account at featureflow.io Github: https://github.com/featureflow/featureflow-javascript-sdk

Examples

Codepen: https://codepen.io/featureflow/pen/BboreK

Installation

Using NPM

$ npm install --save featureflow-client

Using bower

$ bower install featureflow-client

Usage

Adding Featureflow

Webpack

If you are using webpack, you can require the code using

var Featureflow = require('featureflow-client');

or using es6 syntax

import Featureflow from 'featureflow-client';
Bower

Include the following script in HTML file. This will expose the global variable Featureflow

<script crossorigin="anonymous" src="bower_components/featureflow-client/dist/featureflow.min.js"></script>
note

Note: It is recommended to use build tools to manage your bower dependencies. Please see the bower website for more details.

CDN

Include the following script in HTML file. This will expose the global variable Featureflow

<script crossorigin="anonymous" src="https://cdn.featureflow.io/featureflow.js"></script>
Realtime events and EventSource

Featureflow uses EventSource for realtime streaming of feature updates. If you wish to target a browser that doesn't natively support EventSource, we recommend using a polyfill such as this one.

You can either require/include the polyfill in your application,

//for example
import 'event-source-polyfill';

or include it in your <head> of your html file before you load the Featureflow client.

<script src="https://cdnjs.cloudflare.com/ajax/libs/event-source-polyfill/0.0.9/eventsource.js"></script>

Quick start

Get your environment's Featureflow Javascript API key and initialise a new Featureflow client

var FF_JS_API_KEY = '<Your javascript api key goes here>';
//...
var featureflow = Featureflow.init(FF_JS_API_KEY);

This will load the value of each feature for the current environment specified by the api key. These values can be toggled on and off at https://<your-org-key>.featureflow.io

Note: You are responsible for passing the featureflow client instance around your application

In your code, you can test the value of your feature where the value of my-feature-key is equal to 'on'

  if (featureflow.evaluate('my-feature-key').is('on')){
// this feature code will be run because 'my-feature-key' is set to 'on'
}

Because the default variants for any feature are 'on' and 'off', we have provided two helper methods .isOn() and .isOff()


if(featureflow.evaluate('my-feature-key').isOn()){
// this feature code will be run because 'my-feature-key' is set to 'on'
}

if(featureflow.evaluate('my-feature-key').isOff()){
// this feature code won't be run because 'my-feature-key' is not set to 'off'
}

You can include user context information when you initialise featureflow, these attributes can be used in feature targeting rules:

var user = {
id: 'user123',
attributes:{
tier: 'gold',
country: 'australia',
roles: ['role1', 'role3']
}
};
var featureflow = Featureflow.init(FF_KEY, user);

Additional configuration can be set during init also. You can set offline mode for test environments or local development and provide a default set of feature values, for example:

var featureflow = Featureflow.init(FF_KEY, user, {
offline: true,
defaultFeatures: {
'feature-1': 'on',
'feature-2': 'red',
'test': 'off'
},
});

Further documentation can be found here

Anonymous User and Featureflow Server SDKs

In some instances you will want to split test a feature with anonymous users that spans both client and server code. The featureflow client generates a unique anonymous key for the user which can be shared with your server requests. There are a couple of ways you can do this.

Anytime the anonymous user is updated the featureflow client will set the ff-anonymous-id cookie. If request server is on the same [sub]domain and it doesn't have a user id you should use this cookie.

2. Pass the value into the request yourself

If you cannot use cookies (e.g. api on a separate [sub]domain), you can pass the anonymous id directly into the request. Here are some examples of how you can do this:

  1. Using HTTP Header: headers["X-Featureflow-Anonymous-Id"] = featureflow.getAnonymousId()
  2. Adding a query param: '?ff-anonymousid='+featureflow.getAnonymousId()

Update the user when a user logs in

Typically you would want to update the user information when a user logs in or out of your web site. You can do this with the 'featureflow.updateUser()' method

var u = myLoggedInUser; //on return from your login function
var user = {
id: u.id
attributes:{
tier: u.tier, //eg. 'gold'
country: u.country, //eg 'UK'
organisation: u.organisationId, //e.g '1234567'
language: 'en_GB'
}
};
featureflow.updateUser(user);

when the user logs out, clear the user, either call: featureflow.updateUser(); or you may wish to reset to an anonymous user with other values.

API and Configuration

Globals

Featureflow.init(apiKey, [user], [config])

Returns a featureflow instance, see below

ParamsTypeDefaultDescription
apiKey*stringRequiredThe Featureflow Javascript API key for the environment or project you are targeting
useruserSee the user object below
configconfigSee the config object below
returnfeatureflowSee Featureflow Instance below

####Featureflow Instance These properties are available on the return of Featureflow.init(...)

featureflow.evaluate(featureKey)

Returns an object that can be used to help evaluate feature values in an expressive way.

featureflow.evaluate(featureKey).is(value)

Evaluates the value of a feature for the given user.

ParamsTypeDefaultDescription
featureKey*stringRequiredThe feature key you are targeting
value*stringRequiredThe value you are testing against
returnbooleantrue if the feature's value is equal to the value provided, otherwise false
featureflow.evaluate(featureKey).isOn()

Evaluates the value of a feature for the given user is equal to 'on'.

ParamsTypeDefaultDescription
featureKey*stringRequiredThe feature key you are targeting
returnbooleantrue if the feature's value is equal to 'on' provided, otherwise false
featureflow.evaluate(featureKey).isOff()

Evaluates the value of a feature for the given user is equal to 'off'.

ParamsTypeDefaultDescription
featureKey*stringRequiredThe feature key you are targeting
returnbooleantrue if the feature's value is equal to 'off' provided, otherwise false
featureflow.evaluate(featureKey).value()

Returns the value of a feature for the given user.

ParamsTypeDefaultDescription
featureKey*stringRequiredThe feature key you are targeting
returnstringThe value of the feature, or the default feature value from config.defaultFeatures[featureKey] if present, or 'off'

featureflow.goal(goalKey)

Sends a goal event, along with the current evaluated features to featureflow.io. Use with experiments in the admin console.

ParamsTypeDefaultDescription
goalKey*stringThe key of the goal you want to target.

featureflow.updateUser(user, [callback])

Updates the current user of the instance and reevaluates all feature features using the new user.

ParamsTypeDefaultDescription
useruser...See the user object below

Fires a Featureflow.events.LOADED event when the features have been evaluated. Also Fires the callback if provided with the newly evaluated features.

featureflow.getFeatures()

Returns the current evaluated features as flat key-value map

ParamsTypeDefaultDescription
returnobjectThe current features object

featureflow.getUser()

Returns the current user

ParamsTypeDefaultDescription
returnuserThe current user

featureflow.on(event, callback, [bindContext])

Listen to events when the featureflow instance is updated

ParamsTypeDefaultDescription
event*stringRequiredThe name of the event to subscribe to. See Events section below for available events.
callback*functionRequiredThe function to call when the event is emitted.
bindContextanyundefinedThe context to bind the event callback to.

featureflow.off(event, [callback])

Listen to events when the featureflow instance is updated

ParamsTypeDefaultDescription
event*stringRequiredThe name of the event to unsubscribe from.
callbackfunctionRequiredThe callback used when binding the object

featureflow.getAnonymousId()

Returns the anonymous user id assigned for the user in localStorage.

ParamsTypeDefaultDescription
returnstringThe string of the anonymous user id in localStorage.

featureflow.hasReceivedInitialResponse()

Returns true if an initial response has been returned from the server, regardless of the status code.

ParamsTypeDefaultDescription
returnbooleanfalsetrue if the initial request to featureflow has completed

featureflow.resetAnonymousId()

Resets the anonymous user id for the user stored in localStorage. This will not re-evaluate the features, you must still call updateUser() to evaluate the latest features variants.

ParamsTypeDefaultDescription
returnstringThe string of the new anonymous user id.

Object Types

user

PropertyTypeDefaultDescription
idstring'anonymous:**********'Uniquely identifies the current user. Also used to calculate split variants. If not provided a random string prefixed with 'anonymous:' will be used. This will set a cookie that can be used to link the anonymous user with your server's Featureflow SDK.
attributesobjectundefinedFlat key-value object containing extra meta about the current user. Used to serve different features for specifically targeted attributes.

config

PropertyTypeDefaultDescription
streamingbooleanfalseSet to true when calling Featureflow.init(..., ..., config) to listen for realtime updates via SSE
useCookiesbooleantrueSet to false if you do not want to use cookies (you will have to pass the result of featureflow.getAnonymousId() to any future requests if you wish for the server to match the client anonymous key)
defaultFeaturesobjectundefinedA flat key-value object representing the default variants a feature should be set to if there is an interrupted connection and no cached value.

e.g. if you set config.defaultFeatures to {'my-feature': 'on'}, featureflow.evaluate('my-feature').isOn() will return true when there is an interrupted connection to Featureflow and no locally cached feature features.
offlinebooleanfalseSet to true to run in offline mode, this is for testing purposes. Featureflow will not attempt and calls and will use the defaultFeatures values only

Events

Featureflow.events.LOADED_FROM_CACHE

Fired when features have been loaded from localstorage. Triggered by both Featureflow.init(...) and featureflow.updateUser.

Callback is fired with one parameter with the value of all evaluated features.

Featureflow.events.INIT

Fired when features have been evaluated and loaded. Triggered by both Featureflow.init(...) and featureflow.updateUser.

Callback is fired with one parameter with the value of all evaluated features.

Featureflow.events.LOADED

Deprecated: Use Featureflow.events.INIT instead.

Featureflow.events.UPDATED_FEATURE

Only available when streaming is enabled. Fired when a feature has been changed.

Callback is fired with one parameter with the value of only the updated features returned by the stream. In the majority of cases, this object will only contain one property.

Featureflow.events.ERROR

Fired when an error has occurred evaluating the feature features for the given user.

Callback is fired with one parameter with the error message.

Roadmap

  • Write documentation
  • Release to npm
  • Release to bower
  • Automate release to bower on npm prepublish
  • Automate release script to cdn on npm prepublish

Publishing

./deploy_prod_npm.sh
./deploy_prod_s3.sh

License

Apache-2.0