fune/toolkit/components/nimbus/docs/integration.md

2.4 KiB
Raw Blame History

Nimbus Integration and Migration Guide for Desktop Front-End Experiments

This guide will help you integrate ExperimentAPI.jsm in your Desktop front-end code to run Nimbus experiments, while still being able to use preferences for default values and local development.

In order to use ExperimentAPI.jsm your code must be able to import jsms in the parent process or a privileged child process.

Register a new feature

A feature is just some area of code instrumented for experiments it can be as small as a single function or as complex as a whole about: page. You need to choose an identifier for your feature (e.g. "aboutnewtab").

// In ExperimentAPI.jsm

const MANIFEST = {
  // Our feature name
  aboutwelcome: {
    description: "The about:welcome page",
    // Control if the feature is on or off
    enabledFallbackPref: "browser.aboutwelcome.enabled",
    variables: {
      // Additional (optional) values that we can control
      // The name of these variables is up to you
      skipFocus: {
        type: "boolean",
        fallbackPref: "browser.aboutwelcome.skipFocus",
      },
    },
  },
};

// In firefox.js
pref("browser.aboutwelcome.enable", true);
pref("skipFocus", false);

By setting fallback preferences for Nimbus features, you will be able to still run Normandy roll-outs and experiments while you are partially migrated. We do not recommend running Nimbus and Normandy experiments on the same feature/preference simultaneously.

How to use an Experiment Feature

Import ExperimentFeature from ExperimentAPI.jsm and instantiate an instance

XPCOMUtils.defineLazyGetter(this, "feature", () => {
  const { ExperimentFeature } = ChromeUtils.import(
    "resource://nimbus/ExperimentAPI.jsm"
  );
  // Here we use the same name we defined in the MANIFEST
  return new ExperimentFeature("aboutwelcome");
});

Access feature values:

if (feature.isEnabled() {
  // Do something!
  // This is controllbed by the `enabledFallbackPref` defined in the MANIFEST
}

// props: { skipFocus: boolean }
const props = feature.getValue();
renderSomeUI(props);

Defaults values inline:

feature.isEnabled({ defaultValue: true });

// Default values work here too
const { skipFocus } = feature.getValue({ defaultValue: { skipFocus: false } });

Listen to changes:

// Listen to changes, including to fallback prefs.
feature.on(() => {
  updateUI(feature.getValue());
});