A library to integrate launch darkly with react redux 👏
Launch Darkly is a great tool for feature flagging and a/b testing. It has a fully capable client-side javascript sdk, so why this package?
If you use react redux and you want to store your feature flags as part of your redux state, this package will do that for you. It does the heavy lifting of:
- Fetching your flags from launch darkly.
- Storing it in your redux state.
- Camel casing your keys so you can use them in code with the dot operator. The keys by default are dash separated so you can't do this out of the box with the official sdk.
- Server Sent Event works as well so your app will respond live to feature flag changes without the users having to refresh the browser!
ld-redux v2 is NOT backwards compatible! It has been re-written so the api is cleaner and much easier to use:
- No more isLDReady (thank god)
- No more ldConnect (yayy!)
- One step initialisation
yarn add ld-redux
-
In your client bootstrap, initialise the launch darkly client by invoking the init method:
import createStore from '<your-project>/store'; import ldRedux from 'ld-redux'; // standard redux createStore const store = createStore(); const flags = { 'feature-flag-key': false }; // do this once ldRedux.init({ clientSideId: 'your-client-side-id', store, flags, }); render( <Provider store={store}> <Router routes={routes} history={browserHistory}/> </Provider>, document.getElementById('reactDiv') );
-
Include ldReducer as one of the reducers in your app:
import { combineReducers } from 'redux'; import ldRedux from 'ld-redux'; import reducers from '<your-project>/reducers'; export default combineReducers({ ...reducers, LD: ldRedux.reducer(), // Note: the LD key can be anything you want });
-
Use the flag:
import React, {Component} from 'react'; import {connect} from 'react-redux'; const mapStateToProps = (state) => { const {featureFlagKey} = state.LD; // Note: the key LD must be the same as step 2. return { featureFlagKey, }; }; @connect(mapStateToProps) export default class Home extends Component { render() { return ( <div> { /* look ma, feature flag! */ this.props.featureFlagKey ? <div> <p>Welcome to feature toggling!</p> </div> : 'nothing' } </div> ); } }
The init method accepts an object with the above properties. clientSideId
, store
and flags
are mandatory.
The user
property is optional. You can initialise the sdk with a custom user by specifying one. This must be an object containing
at least a "key" property. If you don't specify a user object, ldRedux will create a default one that looks like this:
const defaultUser = {
key: uuid.v4(), // random guid
ip: ip.address(),
custom: {
browser: userAgentParser.getResult().browser.name,
device
}
};
For more info on the user object, see here.
The options
property is optional. It can be used to pass in extra options such as Bootstrapping.
For example:
ldRedux.init({
clientSideId,
store,
flags,
options: {
bootstrap: 'localStorage',
}
});
This is ld-redux's reducer. You must include this reducer in your app as per step 2 above with any key of your choice. You then use this key to retrieve your flags from redux's state.
Internally the ldRedux.init method above initialises the js sdk and stores the resultant ldClient object in window.ldClient. You can use this object to access the official sdk methods directly. For example, you can do things like:
// track goals
window.ldClient.track('add to cart');
// change user context
window.ldClient.identify({key: 'someUserId'});
For more info on changing user context, see the official documentation.
Check the example for a fully working spa with react, redux and react-router.