Remote config
A value your app reads by name and you change from the dashboard, without a release: a feature flag, a price, a headline. One call to read it, and nothing to set up beyond the SDK you already have.
Make a variable
In the dashboard, open Remote config and add a variable. Give it a key your code will use — new_checkout — choose what kind of value it is (on/off, text, a number or JSON) and its default. Add rules if some people should get something else: a platform, an app version, a share of everybody. Nothing reaches an app until you press Publish.
Read it
getConfig takes the key and a fallback, and answers a value of the same kind as the fallback.
import treebars from '@treebars/web-sdk';
if (treebars.getConfig('new_checkout', false)) showNewCheckout();
const headline = treebars.getConfig('home_headline', 'Welcome');
const limit = treebars.getConfig('upload_limit_mb', 25);
const layout = treebars.getConfig('home_layout', { columns: 2 });if Treebars.getConfig("new_checkout", fallback: false) { showNewCheckout() }
let headline = Treebars.getConfig("home_headline", fallback: "Welcome")
let limit = Treebars.getConfig("upload_limit_mb", fallback: 25)if (Treebars.getConfig("new_checkout", false)) showNewCheckout()
val headline = Treebars.getConfig("home_headline", "Welcome")
val limit = Treebars.getConfig("upload_limit_mb", 25)import treebars from '@treebars/react-native-sdk';
await treebars.init({ write_key: 'pk_live_…' }); // read after init has resolved
if (treebars.getConfig('new_checkout', false)) showNewCheckout();
const headline = treebars.getConfig('home_headline', 'Welcome');A read never waits and never fails. It answers from what the device already holds, so it is safe while a screen is being drawn, on the main thread, offline.
The fallback
The fallback is what the read answers until the device holds a value for the key — a first launch, no connection yet, somebody who opted out. Pass the value your app behaves with today, and adding the read changes nothing by itself.
It also says which kind of value you expect. The kind is read from the fallback and never from what was published: if somebody sets a flag to the text "false" by mistake, your getConfig('new_checkout', false) still answers false, not a piece of text that reads as on. An empty fallback is fine — '', 0 and false are each still a kind.
When you have no fallback
Sometimes there is no sensible default — a banner that should only appear once its text exists. Name the kind instead, and the read answers nothing until a value is held.
const banner = treebars.getConfigString('promo_banner'); // string, or null
if (banner) showBanner(banner);if let banner = Treebars.getConfigString("promo_banner") { showBanner(banner) }Treebars.getConfigString("promo_banner")?.let { showBanner(it) }| Kind | Read | Answers |
|---|---|---|
| On / off | getConfigBoolean(key) | true, false, or nothing |
| Text | getConfigString(key) | the text, or nothing |
| Number | getConfigNumber(key) | the number, or nothing |
| JSON | getConfigJson(key) | the value, or nothing |
- Kind
- On / off
- Read
getConfigBoolean(key)- Answers
- true, false, or nothing
- Kind
- Text
- Read
getConfigString(key)- Answers
- the text, or nothing
- Kind
- Number
- Read
getConfigNumber(key)- Answers
- the number, or nothing
- Kind
- JSON
- Read
getConfigJson(key)- Answers
- the value, or nothing
Each also takes a fallback, and is then exactly what getConfig calls. On iOS and Android a JSON value is read this way — getConfigJson answers JSON text for you to decode with your own types — and a number read with a whole-number fallback answers a whole number.
When values arrive
There is no fetch to call. The SDK asks for the values by itself when a newer config has been published and when who is asking changes, and keeps them on the device — so a launch starts on the values the last one held.
A first launch has none yet, and starts on your fallbacks; its values arrive a moment after the app opens. To start a first screen on the published values instead, wait for them. It gives up after two seconds and carries on with your fallbacks.
await treebars.configReady(); // or configReady(500) for half a second at most
render();await Treebars.configReady()
render()Treebars.configReady() // a suspend function
render()A key keeps its answer for the session
The first read of a key fixes its answer until the session ends. A newer config published while somebody is half-way through a checkout does not change that checkout under them; it applies from their next session. A key that has not been read yet takes the newest values straight away.
To apply new values sooner, call activateConfig() at a moment you can redraw — it answers whether any read would now answer differently. onConfigChange tells you when that may be so, and returns the function that stops it.
const stop = treebars.onConfigChange(() => {
if (treebars.activateConfig()) redrawHome();
});What a rule can read
A rule in the dashboard can already read the platform, the app version, the language, the country and whether somebody is signed in — nothing to send. For anything else your app knows, say it once. It is the whole set each time: a key you leave out is no longer set.
treebars.setConfigAttributes({ plan: 'pro', seats: 5 });Treebars.setConfigAttributes(["plan": "pro", "seats": 5])Treebars.setConfigAttributes(mapOf("plan" to "pro", "seats" to 5))await treebars.setConfigAttributes({ plan: 'pro', seats: 5 });Signing in or out asks for the values again, since the answer may differ. A sign-out forgets the account's values at once, before the next ones arrive, so the next person on the device is never shown the last one's.
Experiments
A variable can serve an experiment: two to five values, each to a share of people. Your code does not change — it is the same read. When a read answers an experiment's value, the SDK records experiment_exposed with the variant, at most once a day for each person, so who saw which variant is counted from what your app actually showed and not from what it was sent.
That is what lets the dashboard compare the variants afterwards: Insights has an Experiment view that reads the whole page once for each variant, and a user flow can be divided at a step by the variable.
While you build
An override answers a key on this device whatever was published — for trying a variant without changing the dashboard. It is never stored and never sent: the next launch or reload forgets it, and it records no exposure.
treebars.setConfigOverride('new_checkout', true);
treebars.setConfigOverride('new_checkout', undefined); // take it backTreebars.setConfigOverride("new_checkout", value: true)Treebars.setConfigOverride("new_checkout", true)await treebars.setConfigOverride('new_checkout', true);allConfig() lists every value the device holds, for a debug screen. fetchConfig() asks for the values now and answers whether they arrived; it is seldom needed, since the SDK asks by itself.
Somebody who opted out
After optOut() the SDK asks for nothing about that person, and every read answers its fallback. Your app keeps working on the values it ships with.