Skip to content

コンテンツカードからバナーへの移行

このガイドは、バナースタイルのメッセージング ユースケースのコンテンツカードからバナーへの移行に役立ちます。バナーは、インライン、永続的なインアプリおよびウェブメッセージ用のアイデアl です。これらは、アプリライケーションの特定の場所でイヤーをアプリします。

なぜバナーに移行するのか?

  • 開発チームがカスタムコンテンツカードを作成または管理している場合、バナーに移行すると、その継続的な投資を削減できます。バナーは、マーケター s にUI を直接コントロールさせ、他の作業のために開発者s を解放します。
  • 新しいホームページメッセージ、オンボーディングの流れ、または永続的なアナウンスを起動する場合は、コンテンツカードではなく、バナーで開始します。リアルタイムパーソナライゼーション、30 日間の有効期限なし、サイズ制限なし、1 日目からのネイティブ優先順位付けのメリットを得ることができます。
  • 30 日間の有効期限の制限を回避したり、複雑な再適格ロジックを管理したり、古いパーソナライゼーションにイライラしたりする場合、バナーはこれらの問題をネイティブに解決します。

バナースタイルのメッセージングのために、バナーはコンテンツカードよりもいくつかのタグを提供しています:

生産加速

  • 必要な継続開発の短縮:マーケターは、ドラッグアンドドロップエディターとカスタムHTMLを使用してカスタムメッセージを作成できます。カスタマイズのために開発者な支援は必要ありません
  • 柔軟なカスタマイズオプション:エディタで直接デザインするか、HTMLを使用するか、既存のデータモデルをカスタムプロパティで活用します

ベターUX

  • 動的内容更新s:リフレッシュごとにリキッドロジックと適格性をリフレッシュし、ユーザーが最も適切な内容を常に確認できるようにします
  • ネイティブ配置サポート:メッセージは、フィードではなく、特定の文脈でアプリし、より良い文脈に応じた or 状況に即した関連性を提供します
  • ネイティブ優先度:カスタムロジックなしで表示順序を制御し、メッセージ階層の管理を容易にする

永続性

  • 有効期限なし:バナーキャンペーンsには、コンテンツカードのような30日間の有効期限がなく、メッセージの真の持続性を可能にします

移行時期

コンテンツカードを使用している場合は、バナーへの移行を検討してください。

  • ホームページヒーロー、商品ページプロモーション、チェックアウトオファー
  • 永続的なナビゲーションのアナウンスまたはサイドバーメッセージ
  • 30 日以上実行されている常時オンメッセージ
  • リアルタイムのパーソナライゼーションと適格性が必要なメール

コンテンツカードをいつ保持するか

必要に応じて、コンテンツカードの使用を続行します。

  • 飼料体験:複数のスクロール可能なメッセージ、またはカードベースの”Inbox”を含むユースケース。
  • 特長:バナーがネイティブにサポートしていないため、接続コンテンツまたはプロモーションコードを必要とするメッセージ。
  • トリガー配信:API-トリガー ed またはアクション ベースの配信を厳密に必要とするユースケース。Banner はAPI-トリガー ed またはアクション ベースの配信をサポートしていませんが、リアルタイム適格性評価とは、ユーザー s が更新ごとにSegmentメンバーシップに基づいて即座に適格または不適格になることを意味します。

移行ガイド

前提条件

移行する前に、Braze SDKが最低限必要なバージョンを満たしていることを確認してください。

更新を購読する

コンテンツカードアプリへの侵入

1
2
3
4
5
6
7
8
import * as braze from "@braze/web-sdk";

braze.subscribeToContentCardsUpdates((cards) => {
  // Handle array of cards
  cards.forEach(card => {
    console.log("Card:", card.id);
  });
});
1
2
3
4
5
6
Braze.getInstance(context).subscribeToContentCardsUpdates { cards ->
  // Handle array of cards
  cards.forEach { card ->
    Log.d(TAG, "Card: ${card.id}")
  }
}
1
2
3
4
5
6
braze.contentCards.subscribeToUpdates { cards in
  // Handle array of cards
  for card in cards {
    print("Card: \(card.id)")
  }
}
1
2
3
4
5
6
7
Braze.addListener(Braze.Events.CONTENT_CARDS_UPDATED, (update) => {
  const cards = update.cards;
  // Handle array of cards
  cards.forEach(card => {
    console.log("Card:", card.id);
  });
});
1
2
3
4
5
6
StreamSubscription contentCardsStreamSubscription = braze.subscribeToContentCards((List<BrazeContentCard> contentCards) {
  // Handle array of cards
  for (final card in contentCards) {
    print("Card: ${card.id}");
  }
});

バナーズ・アプリ・ローチ

1
2
3
4
5
6
7
8
9
import * as braze from "@braze/web-sdk";

braze.subscribeToBannersUpdates((banners) => {
  // Get banner for specific placement
  const globalBanner = braze.getBanner("global_banner");
  if (globalBanner) {
    console.log("Banner received for placement:", globalBanner.placementId);
  }
});
1
2
3
4
5
6
7
Braze.getInstance(context).subscribeToBannersUpdates { update ->
  // Get banner for specific placement
  val globalBanner = Braze.getInstance(context).getBanner("global_banner")
  if (globalBanner != null) {
    Log.d(TAG, "Banner received for placement: ${globalBanner.placementId}")
  }
}
1
2
3
4
5
6
7
8
braze.banners.subscribeToUpdates { banners in
  // Get banner for specific placement
  braze.banners.getBanner(for: "global_banner") { banner in
    if let banner = banner {
      print("Banner received for placement: \(banner.placementId)")
    }
  }
}
1
2
3
4
5
6
7
8
9
Braze.addListener(Braze.Events.BANNER_CARDS_UPDATED, (data) => {
  const banners = data.banners;
  // Get banner for specific placement
  Braze.getBanner("global_banner").then(banner => {
    if (banner) {
      console.log("Banner received for placement:", banner.placementId);
    }
  });
});
1
2
3
4
5
6
7
8
StreamSubscription bannerStreamSubscription = braze.subscribeToBanners((List<BrazeBanner> banners) {
  // Get banner for specific placement
  braze.getBanner("global_banner").then((banner) {
    if (banner != null) {
      print("Banner received for placement: ${banner.placementId}");
    }
  });
});

表示内容

コンテンツカードアプリへの侵入

1
2
3
4
5
6
7
8
9
10
11
// Show default feed UI
braze.showContentCards(document.getElementById("feed"));

// Or manually render cards
const cards = braze.getCachedContentCards();
cards.forEach(card => {
  // Custom rendering logic
  if (card instanceof braze.ClassicCard) {
    // Render classic card
  }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Using default fragment
val fragment = ContentCardsFragment()
supportFragmentManager.beginTransaction()
  .replace(R.id.content_cards_container, fragment)
  .commit()

// Or manually render cards
val cards = Braze.getInstance(context).getCachedContentCards()
cards.forEach { card ->
  when (card) {
    is ClassicCard -> {
      // Render classic card
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Using default view controller
let contentCardsController = BrazeContentCardUI.ViewController(braze: braze)
navigationController?.pushViewController(contentCardsController, animated: true)

// Or manually render cards
let cards = braze.contentCards.cards
for card in cards {
  switch card {
  case let card as Braze.ContentCard.Classic:
    // Render classic card
  default:
    break
  }
}
1
2
3
4
5
6
7
8
9
10
// Launch default feed
Braze.launchContentCards();

// Or manually render cards
const cards = await Braze.getContentCards();
cards.forEach(card => {
  if (card.type === 'CLASSIC') {
    // Render classic card
  }
});
1
2
3
4
5
6
7
8
9
10
// Launch default feed
braze.launchContentCards();

// Or manually render cards
final cards = await braze.getContentCards();
for (final card in cards) {
  if (card.type == 'CLASSIC') {
    // Render classic card
  }
}

バナーズ・アプリ・ローチ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
braze.subscribeToBannersUpdates((banners) => {
  const globalBanner = braze.getBanner("global_banner");
  if (!globalBanner) {
    return;
  }

  const container = document.getElementById("global-banner-container");
  braze.insertBanner(globalBanner, container);

  if (globalBanner.isControl) {
    container.style.display = "none";
  }
});

braze.requestBannersRefresh(["global_banner"]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Using BannerView in XML
// <com.braze.ui.banners.BannerView
//     android:id="@+id/banner_view"
//     android:layout_width="match_parent"
//     android:layout_height="wrap_content"
//     app:placementId="global_banner" />

// Or programmatically
val bannerView = BannerView(context).apply {
  placementId = "global_banner"
}
container.addView(bannerView)

Braze.getInstance(context).requestBannersRefresh(listOf("global_banner"))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Using BannerUIView
let bannerView = BrazeBannerUI.BannerUIView(
  placementId: "global_banner",
  braze: braze,
  processContentUpdates: { result in
    switch result {
    case .success(let updates):
      if let height = updates.height {
        // Update height constraint
      }
    case .failure:
      break
    }
  }
)
view.addSubview(bannerView)

braze.banners.requestBannersRefresh(placementIds: ["global_banner"])
1
2
3
4
5
6
7
8
9
10
11
12
// Using BrazeBannerView component
<Braze.BrazeBannerView
  placementID='global_banner'
/>

// Or get banner data
const banner = await Braze.getBanner("global_banner");
if (banner) {
  // Render custom banner UI
}

Braze.requestBannersRefresh(["global_banner"]);
1
2
3
4
5
6
7
8
9
10
11
12
// Using BrazeBannerView widget
BrazeBannerView(
  placementId: "global_banner",
)

// Or get banner data
final banner = await braze.getBanner("global_banner");
if (banner != null) {
  // Render custom banner UI
}

braze.requestBannersRefresh(["global_banner"]);

ログ分析(カスタムインプリメンテーション)

コンテンツカードアプリへの侵入

1
2
3
4
5
6
7
// Manual impression logging required for custom implementations
cards.forEach(card => {
    braze.logContentCardImpressions([card]);
});

// Manual click logging required for custom implementations
card.logClick();
1
2
3
4
5
6
7
// Manual impression logging required for custom implementations
cards.forEach { card ->
    card.logImpression()
}

// Manual click logging required for custom implementations
card.logClick()
1
2
3
4
5
6
7
// Manual impression logging required for custom implementations
for card in cards {
    card.context?.logImpression()
}

// Manual click logging required for custom implementations
card.context?.logClick()
1
2
3
4
5
6
7
// Manual impression logging required for custom implementations
cards.forEach(card => {
    Braze.logContentCardImpression(card.id);
});

// Manual click logging required for custom implementations
Braze.logContentCardClicked(card.id);
1
2
3
4
5
6
7
// Manual impression logging required for custom implementations
for (final card in cards) {
    braze.logContentCardImpression(card);
}

// Manual click logging required for custom implementations
braze.logContentCardClicked(card);

バナーズ・アプリ・ローチ

1
2
3
4
5
6
7
8
9
// Analytics are automatically tracked when using insertBanner()
// Manual logging should not be used when using insertBanner()

// For custom implementations, use manual logging methods:
// Log impression
braze.logBannerImpressions([globalBanner]);

// Log click (with optional buttonId)
braze.logBannerClick("global_banner", buttonId);
1
2
3
4
5
6
7
8
9
// Analytics are automatically tracked when using BannerView
// Manual logging should not be used for default BannerView

// For custom implementations, use manual logging methods:
// Log impression
Braze.getInstance(context).logBannerImpression("global_banner");

// Log click (with optional buttonId)
Braze.getInstance(context).logBannerClick("global_banner", buttonId);
1
2
3
4
5
6
7
8
9
10
11
// Analytics are automatically tracked when using BannerUIView
// Manual logging should not be used for default BannerUIView

// For custom implementations, use manual logging methods:
// Log impression
braze.banners.logImpression(placementId: "global_banner")

// Log click (with optional buttonId)
braze.banners.logClick(placementId: "global_banner", buttonId: buttonId)

// Control groups are automatically handled by BannerUIView
1
2
3
4
5
// Analytics are automatically tracked when using BrazeBannerView
// No manual logging required

// Note: Manual logging methods for Banners are not yet supported in React Native
// Control groups are automatically handled by BrazeBannerView
1
2
3
4
5
// Analytics are automatically tracked when using BrazeBannerView
// No manual logging required

// Note: Manual logging methods for Banners are not yet supported in Flutter
// Control groups are automatically handled by BrazeBannerView

コントロールグループの処理

コンテンツカードアプリへの侵入

1
2
3
4
5
6
7
cards.forEach(card => {
  if (card.isControl) {
    // Logic for control cards ie. don't display but log analytics
  } else {
    // Logic for cards ie. render card
  }
});
1
2
3
4
5
6
7
cards.forEach { card ->
  if (card.isControl) {
    // Logic for control cards ie. don't display but log analytics
  } else {
    // Logic for cards ie. render card
  }
}
1
2
3
4
5
6
7
for card in cards {
  if card.isControl {
    // Logic for control cards ie. don't display but log analytics
  } else {
    // Logic for cards ie. render card
  }
}
1
2
3
4
5
6
7
cards.forEach(card => {
  if (card.isControl) {
    // Logic for control cards ie. don't display but log analytics
  } else {
    // Logic for cards ie. render card
  }
});
1
2
3
4
5
6
7
for (final card in cards) {
  if (card.isControl) {
    // Logic for control cards ie. don't display but log analytics
  } else {
    // Logic for cards ie. render card
  }
}

バナーズ・アプリ・ローチ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
braze.subscribeToBannersUpdates((banners) => {
  const globalBanner = braze.getBanner("global_banner");
  if (!globalBanner) {
    return;
  }

  const container = document.getElementById("global-banner-container");
  
  // Always call insertBanner to track impression (including control)
  braze.insertBanner(globalBanner, container);
  
  // Hide if control group
  if (globalBanner.isControl) {
    container.style.display = "none";
  }
});
1
2
3
4
5
// BannerView automatically handles control groups
// No additional code needed
val bannerView = BannerView(context).apply {
  placementId = "global_banner"
}
1
2
3
4
5
6
// BannerUIView automatically handles control groups
// No additional code needed
let bannerView = BrazeBannerUI.BannerUIView(
  placementId: "global_banner",
  braze: braze
)
1
2
3
4
5
// BrazeBannerView automatically handles control groups
// No additional code needed
<Braze.BrazeBannerView
  placementID='global_banner'
/>
1
2
3
4
5
// BrazeBannerView automatically handles control groups
// No additional code needed
BrazeBannerView(
  placementId: "global_banner",
)

制限事項

コンテンツカードからバナーに移行する場合は、次の制限事項に注意してください。

トリガーメッセージの移行

バナーはスケジュールされた配信キャンペーンs のみに対応しています。以前にAPI-トリガーされたメッセージまたはアクションベースのメッセージを移行するには、それをSegmentベースのターゲットに変換します。

  • 例:&quot をトリガーする代わりに、プロファイル” API を使用してカードを完了し、過去7 日間にサインアップしたがプロファイルを完了していないユーザーのSegmentを作成します。
  • リアルタイム資格:ユーザは、Segmentメンバーシップに基づいて、リフレッシュごとに即座にバナーの資格を取得するか、または資格を喪失します。

機能の違い

製品の制限事項

  • 配置ごとに最大25 のアクティブメッセージ。
  • リフレッシュ要求ごとに最大 10 個の配置 ID。これを超える要求は切り捨てられます。

SDK制限

  • 現在、バナーは。NET MAUI (Xamarin)、Cordova、Unity、ベガ、またはTV プラットフォームではサポートされていません。
  • 前提条件に記載されている最低限のSDKを使用していることを確認します。

関連記事

New Stuff!