コンテンツにスキップ

フィーチャーフラグ

フィーチャーフラグを使用すると、特定のユーザーまたはランダムに選択したユーザーの機能をリモートで有効または無効にすることができます。重要なのは、追加のコードデプロイやアプリストアの更新なしに、本番環境で機能のオンオフを切り替えられることです。これにより、新しい機能を安全かつ確信を持ってロールアウトできます。

前提条件

フィーチャーフラグの使用を開始するために必要な最小SDKバージョンは以下のとおりです。

ユースケース

段階的なロールアウト

フィーチャーフラグを使用して、サンプル集団に対して機能を段階的に有効にできます。たとえば、VIPユーザーに対して最初に新機能をソフトローンチできます。この戦略は、すべてのユーザーに一度に新機能をリリースすることに伴うリスクを軽減し、バグを早期に発見するのに役立ちます。

ロールアウトトラフィックスライダーが0%から100%に移動するアニメーション。

たとえば、より迅速なカスタマーサービスのために、アプリに新しい「ライブチャットサポート」リンクを追加することを決定したとします。この機能をすべての顧客に一度にリリースすることもできますが、広範なリリースには次のようなリスクが伴います。

  • サポートチームはまだトレーニング中であり、リリース後に顧客がサポートチケットを開始する可能性があります。サポートチームにもう少し時間が必要な場合に余裕がありません。
  • 実際に発生する新しいサポートケースの量が不明であるため、適切な人員配置ができていない可能性があります。
  • サポートチームが対応しきれなくなった場合、この機能をすぐにオフにする手段がありません。
  • チャットウィジェットにバグが含まれている可能性があり、顧客にネガティブな体験をさせたくありません。

Brazeのフィーチャーフラグを使用すれば、機能を段階的にロールアウトし、これらのリスクすべてを軽減できます。

  • サポートチームの準備が整ったと言われた時点で「ライブチャットサポート」機能を有効にします。
  • 適切な人員配置ができているかを判断するために、まず10%のユーザーのみにこの新機能を有効にします。
  • バグがある場合は、新しいリリースを急いで出す代わりに、すぐに機能を無効にできます。

この機能を段階的にロールアウトするために、「Live Chat Widget」という名前のフィーチャーフラグを作成します。

Live Chat Widgetというサンプルのフィーチャーフラグの詳細。IDはenable_live_chat。このフィーチャーフラグの説明には、ライブチャットウィジェットがサポートページに表示されると記載されています。

アプリのコードでは、Brazeのフィーチャーフラグが有効な場合にのみStart Live Chatボタンを表示します。

import {useState} from "react";
import * as braze from "@braze/web-sdk";

// Get the initial value from the Braze SDK
const featureFlag = braze.getFeatureFlag("enable_live_chat");
const [liveChatEnabled, setLiveChatEnabled] = useState(featureFlag.enabled);

// - Available in version 7.0.0+
// Listen for events from the Braze SDK
braze.subscribeToFeatureFlagsEvents((event) => {
  switch (event.type) {
    case braze.ChannelEventType.CACHE_REPLAY:
    case braze.ChannelEventType.CACHE_LOAD:
    case braze.ChannelEventType.DATA_UPDATED: {
      const flag = event.cacheSnapshot.featureFlags.find((f) => f.id === "enable_live_chat");
      setLiveChatEnabled(flag ? flag.enabled : false);
      break;
    }
    case braze.ChannelEventType.ERROR:
      if (event.reason === braze.ChannelErrorReason.FEATURE_DISABLED) {
        setLiveChatEnabled(false);
      }
      break;
  }
});

// Listen for updates from the Braze SDK
braze.subscribeToFeatureFlagsUpdates(() => {
    const newValue = braze.getFeatureFlag("enable_live_chat").enabled;
    setLiveChatEnabled(newValue);
});

// Only show the Live Chat if the Braze SDK determines it is enabled
return (<>
  Need help? <button>Email Our Team</button>
  {liveChatEnabled && <button>Start Live Chat</button>}
</>)

Web SDK 7.0.0以降ではsubscribeToFeatureFlagsEventsを使用してください。subscribeToFeatureFlagsUpdatesは以前のパターンであり、7.0.0で非推奨になりました。

受信できるイベントの完全なリストについては、フィーチャーフラグの作成を参照してください。

// Get the initial value from the Braze SDK
FeatureFlag featureFlag = braze.getFeatureFlag("enable_live_chat");
Boolean liveChatEnabled = featureFlag != null && featureFlag.getEnabled();

// - Available in version 44.0.0+
// Listen for events from the Braze SDK
braze.subscribeToFeatureFlagsEvents(event -> {
  if (event instanceof FeatureFlagsEvent.CacheReplay || event instanceof FeatureFlagsEvent.CacheLoad || event instanceof FeatureFlagsEvent.DataUpdated) {
    FeatureFlag newFeatureFlag = braze.getFeatureFlag("enable_live_chat");
    Boolean newValue = newFeatureFlag != null && newFeatureFlag.getEnabled();
    liveChatEnabled = newValue;
  } else if (event instanceof FeatureFlagsEvent.ErrorEvent) {
    FeatureFlagsEvent.ErrorEvent errorEvent = (FeatureFlagsEvent.ErrorEvent) event;
    if (errorEvent.getReason() instanceof ChannelErrorReason.FeatureDisabled) {
      liveChatEnabled = false;
    }
  }
});

// Listen for updates from the Braze SDK
braze.subscribeToFeatureFlagsUpdates(event -> {
  FeatureFlag newFeatureFlag = braze.getFeatureFlag("enable_live_chat");
  Boolean newValue = newFeatureFlag != null && newFeatureFlag.getEnabled();
  liveChatEnabled = newValue;
});

// Only show the Live Chat view if the Braze SDK determines it is enabled
if (liveChatEnabled) {
  liveChatView.setVisibility(View.VISIBLE);
} else {
  liveChatView.setVisibility(View.GONE);
}

Android SDK 44.0.0以降ではsubscribeToFeatureFlagsEventsを使用してください。subscribeToFeatureFlagsUpdatesは以前のパターンであり、44.0.0で非推奨になりました。

// Get the initial value from the Braze SDK
val featureFlag = braze.getFeatureFlag("enable_live_chat")
var liveChatEnabled = featureFlag?.enabled

// - Available in version 44.0.0+
// Listen for events from the Braze SDK
braze.subscribeToFeatureFlagsEvents { event ->
  when (event) {
    is FeatureFlagsEvent.CacheReplay, is FeatureFlagsEvent.CacheLoad, is FeatureFlagsEvent.DataUpdated -> {
      val newValue = braze.getFeatureFlag("enable_live_chat")?.enabled
      liveChatEnabled = newValue
    }
    is FeatureFlagsEvent.ErrorEvent -> {
      if (event.reason is ChannelErrorReason.FeatureDisabled) {
        liveChatEnabled = false
      }
    }
    else -> {}
  }
}

// Listen for updates from the Braze SDK
braze.subscribeToFeatureFlagsUpdates {
  val newValue = braze.getFeatureFlag("enable_live_chat")?.enabled
  liveChatEnabled = newValue
}

// Only show the Live Chat view if the Braze SDK determines it is enabled
if (liveChatEnabled) {
  liveChatView.visibility = View.VISIBLE
} else {
  liveChatView.visibility = View.GONE
}

Android SDK 44.0.0以降ではsubscribeToFeatureFlagsEventsを使用してください。subscribeToFeatureFlagsUpdatesは以前のパターンであり、44.0.0で非推奨になりました。

// Get the initial value from the Braze SDK
let featureFlag = braze.featureFlags.featureFlag(id: "enable_live_chat")
var liveChatEnabled = featureFlag?.enabled ?? false

// - Available in version 19.0.0+
// Listen for events from the Braze SDK
let cancellable = braze.featureFlags.subscribeToEvents { event in
  switch event {
  case .cacheReplay, .cacheLoad, .dataUpdated:
    let newValue = braze.featureFlags.featureFlag(id: "enable_live_chat")?.enabled ?? false
    liveChatEnabled = newValue
  default:
    break
  }
}

// Listen for updates from the Braze SDK
let cancellable = braze.featureFlags.subscribeToUpdates { _ in
  let newValue = braze.featureFlags.featureFlag(id: "enable_live_chat")?.enabled ?? false
  liveChatEnabled = newValue
}

// Only show the Live Chat view if the Braze SDK determines it is enabled
liveChatView.isHidden = !liveChatEnabled

Swift SDK 19.0.0以降ではsubscribeToEvents(_:)を使用してください。subscribeToUpdates(_:)は以前のパターンであり、19.0.0で非推奨になりました。

各イベントがいつ発火するか、また各更新理由、リトライ状態、分析アクション、エラー理由の意味については、イベントサブスクリプションを参照してください。

アプリ変数のリモート制御

フィーチャーフラグを使用して、本番環境でアプリの機能を変更できます。これは、アプリストアの承認プロセスにより、すべてのユーザーに迅速に変更をロールアウトできないモバイルアプリにとって特に重要です。

たとえば、マーケティングチームがアプリのナビゲーションに現在のセールやプロモーションを掲載したいとします。通常、エンジニアは変更に1週間のリードタイムを必要とし、アプリストアのレビューに3日かかります。しかし、感謝祭、ブラックフライデー、サイバーマンデー、ハヌカー、クリスマス、元旦がすべて2か月以内にある場合、これらの厳しい締め切りに間に合わせることはできません。

フィーチャーフラグを使用すれば、アプリのナビゲーションリンクのコンテンツをBrazeに任せることができ、マーケティングマネージャーは数日ではなく数分で変更を行えます。

この機能をリモートで設定するために、navigation_promo_linkという名前の新しいフィーチャーフラグを作成し、以下の初期プロパティを定義します。

一般的なセールページへのリンクとテキストのプロパティを持つフィーチャーフラグ。

アプリでは、Brazeのゲッターメソッドを使用してこのフィーチャーフラグのプロパティを取得し、それらの値に基づいてナビゲーションリンクを構築します。

import * as braze from "@braze/web-sdk";
import {useState} from "react";

const featureFlag = braze.getFeatureFlag("navigation_promo_link");
// Check if the feature flag is enabled
const [promoEnabled, setPromoEnabled] = useState(featureFlag.enabled);
// Read the "link" property
const [promoLink, setPromoLink] = useState(featureFlag.getStringProperty("link"));
// Read the "text" property
const [promoText, setPromoText] = useState(featureFlag.getStringProperty("text"));

return (<>
  <div>
    <a href="/">Home</a>
    { promoEnabled && <a href={promoLink}>{promoText}</a> }
    <a href="/products">Products</a>
    <a href="/categories">Categories
  </div>
</>)
// liveChatView is the View container for the Live Chat UI
FeatureFlag featureFlag = braze.getFeatureFlag("navigation_promo_link");
if (featureFlag != null && featureFlag.getEnabled()) {
  liveChatView.setVisibility(View.VISIBLE);
} else {
  liveChatView.setVisibility(View.GONE);
}
liveChatView.setPromoLink(featureFlag.getStringProperty("link"));
liveChatView.setPromoText(featureFlag.getStringProperty("text"));

// liveChatView is the View container for the Live Chat UI
val featureFlag = braze.getFeatureFlag("navigation_promo_link")
if (featureFlag?.enabled == true) {
  liveChatView.visibility = View.VISIBLE
} else {
  liveChatView.visibility = View.GONE
}
liveChatView.promoLink = featureFlag?.getStringProperty("link")
liveChatView.promoText = featureFlag?.getStringProperty("text")
let featureFlag = braze.featureFlags.featureFlag(id: "navigation_promo_link")
if let featureFlag {
  liveChatView.isHidden = !featureFlag.enabled
} else {
  liveChatView.isHidden = true
}
liveChatView.promoLink = featureFlag?.stringProperty("link")
liveChatView.promoText = featureFlag?.stringProperty("text")

感謝祭の前日に、Brazeダッシュボードでこれらのプロパティ値を変更するだけで済みます。

感謝祭セールページへのリンクとテキストのプロパティを持つフィーチャーフラグ。

その結果、次にアプリを読み込んだユーザーには、新しい感謝祭のお得な情報が表示されます。

メッセージの連携

フィーチャーフラグを使用して、機能のロールアウトとメッセージングを同期し、プロダクトチームとマーケティングチームの連携を強化できます。フィーチャーフラグを通じて機能リリースとメッセージングを調整することで、両チームは戦略を合わせ、一貫したユーザー体験を生み出すことができます。

たとえば、ユーザー向けに新しいロイヤルティ報酬プログラムをローンチするとします。マーケティングチームとプロダクトチームが、プロモーションメッセージのタイミングと機能のロールアウトを完璧に調整するのは難しい場合があります。しかし、キャンバスでフィーチャーフラグを使用すれば、プロダクトチームは特定のオーディエンスに対して機能を有効にする高度なロジックを適用でき、マーケティングチームは同じユーザーに関連するメッセージングを制御できます。

機能のロールアウトとメッセージングを効果的に連携させるために、show_loyalty_programという名前の新しいフィーチャーフラグを作成します。最初の段階的リリースでは、フィーチャーフラグの有効化のタイミングと対象をキャンバスに制御させます。現時点では、ロールアウト率を0%のままにし、ターゲットセグメントも選択しません。

Loyalty Rewards Programという名前のフィーチャーフラグ。IDはshow_loyalty_programで、説明にはホーム画面とプロフィールページに新しいロイヤルティ報酬プログラムを表示すると記載されています。

次に、キャンバスで「High Value Customers」セグメントに対してshow_loyalty_programフィーチャーフラグを有効にするフィーチャーフラグステップを作成します。

高価値顧客セグメントがshow_loyalty_programフィーチャーフラグを有効にするオーディエンス分割ステップを含むキャンバスの例。

これで、このセグメントのユーザーに新しいロイヤルティプログラムが表示されるようになり、有効化後にメールと調査が自動的に送信され、チームがフィードバックを収集できるようになります。

機能の実験

フィーチャーフラグを使用して、新機能に関する仮説を実験し、検証できます。トラフィックを2つ以上のグループに分割することで、グループ間でフィーチャーフラグの影響を比較し、結果に基づいて最適な行動方針を決定できます。

フィーチャーフラグ実験では、合計最大9つのグループを設定できます。1つのコントロールグループと最大8つのバリアントです。

A/Bテストは、変数の複数のバージョンに対するユーザーの反応を比較する強力なツールです。

この例では、eコマースアプリの新しいチェックアウトフローを構築しました。ユーザー体験が向上すると確信していますが、アプリの収益に与える影響を測定するためにA/Bテストを実施したいと考えています。

まず、enable_checkout_v2という名前の新しいフィーチャーフラグを作成します。オーディエンスやロールアウト率は追加しません。代わりに、フィーチャーフラグ実験を使用してトラフィックを分割し、機能を有効にし、結果を測定します。

アプリでは、フィーチャーフラグが有効かどうかを確認し、レスポンスに基づいてチェックアウトフローを切り替えます。

import * as braze from "@braze/web-sdk";

const featureFlag = braze.getFeatureFlag("enable_checkout_v2");
braze.logFeatureFlagImpression("enable_checkout_v2");
if (featureFlag?.enabled) {
  return <NewCheckoutFlow />
} else {
  return <OldCheckoutFlow />
}
FeatureFlag featureFlag = braze.getFeatureFlag("enable_checkout_v2");
braze.logFeatureFlagImpression("enable_checkout_v2");
if (featureFlag != null && featureFlag.getEnabled()) {
  return new NewCheckoutFlow();
} else {
  return new OldCheckoutFlow();
}
val featureFlag = braze.getFeatureFlag("enable_checkout_v2")
braze.logFeatureFlagImpression("enable_checkout_v2")
if (featureFlag?.enabled == true) {
  return NewCheckoutFlow()
} else {
  return OldCheckoutFlow()
}
let featureFlag = braze.featureFlags.featureFlag(id: "enable_checkout_v2")
braze.featureFlags.logFeatureFlagImpression(id: "enable_checkout_v2")
if let featureFlag, featureFlag.enabled {
  return NewCheckoutFlow()
} else {
  return OldCheckoutFlow()
}

A/Bテストはフィーチャーフラグ実験で設定します。

これで、50%のユーザーには従来の体験が表示され、残りの50%には新しい体験が表示されます。2つのバリアントを分析して、どちらのチェックアウトフローがより高いコンバージョン率をもたらしたかを判断できます。

コンバージョン率は、メッセージの全受信者と比較して、定義されたイベントが発生した回数の割合です。この定義されたイベントは、キャンペーンを作成するときに決定します。

トラフィックを50%ずつの2つのグループに分割するフィーチャーフラグ実験。

勝者を決定したら、このキャンペーンを停止し、フィーチャーフラグのロールアウト率をすべてのユーザーに対して100%に引き上げ、その間にエンジニアリングチームが次のアプリリリースにハードコードします。

セグメンテーション

フィーチャーフラグフィルターを使用して、フィーチャーフラグが有効かどうかに基づいてセグメントを作成したり、ユーザーにメッセージをターゲティングしたりできます。たとえば、アプリのプレミアムコンテンツを制御するフィーチャーフラグがあるとします。フィーチャーフラグが有効になっていないユーザーでフィルタリングするセグメントを作成し、そのセグメントに対してプレミアムコンテンツを表示するためにアカウントのアップグレードを促すメッセージを送信できます。

  1. セグメントまたはメッセージオーディエンスを開きます。
  2. フィーチャーフラグフィルターを追加します。
  3. フィーチャーフラグを選択します。
  4. フィーチャーフラグが有効なユーザーを含めるには比較子をisに設定し、有効でないユーザーを含めるにはis notに設定します。 フィーチャーフラグの有効値フィルターを使用したBrazeセグメントビルダー。

セグメントのフィルタリングの詳細については、セグメントの作成を参照してください。

プランの制限事項

以下はフィーチャーフラグの無料プランおよび有料プランにおける制限事項です。

機能 無料版 有料版
アクティブなフィーチャーフラグ ワークスペースあたり10 ワークスペースあたり110
アクティブなキャンペーン実験 ワークスペースあたり1 ワークスペースあたり100
フィーチャーフラグキャンバスステップ 無制限 無制限

以下のいずれかに該当する場合、フィーチャーフラグはアクティブとみなされ、制限数にカウントされます。

  • ロールアウトが0%を超えている
  • アクティブなキャンバスで使用されている
  • アクティブな実験で使用されている

同じフィーチャーフラグが複数の条件に一致する場合(例:キャンバスで使用されており、かつロールアウトが50%の場合)でも、制限数に対して1つのアクティブなフィーチャーフラグとしてのみカウントされます。

New Stuff!