Embedding Banner Cards
Learn how to embed banner cards using the Braze SDK, so you can engage users with an experience that feels natural. For more general information, see About Banner Cards.
important:
Banner Cards are currently in early access. Contact your Braze account manager if you’re interested in participating in this early access.
Prerequisites
These are the minimum SDK versions needed to start using Banner Cards:
Embedding a Banner Card
Step 1: Create placements
If you haven’t already, you’ll need to create Banner Card placements in Braze that are used to define the locations in your app or site can display Banner Cards. To create a placement, go to Settings > Banner Cards Placements, then select Create Placement.

Give your placement a name and assign a Placement ID. Be sure you consult other teams before assigning an ID, as it’ll be used throughout the card’s lifecycle and shouldn’t be changed later. For more information, see Placement IDs.

Step 2: Refresh placements in your app
Placements can be requested each session and will be cached automatically when a user’s session expires or when you change identified users using the changeUser
method.
tip:
Refresh placements as soon as possible to avoid delays in downloading or displaying banners.
1
2
3
| import * as braze from "@braze/web-sdk";
braze.requestBannersRefresh(["global_banner", "navigation_square_banner"])
|
1
| AppDelegate.braze?.banners.requestRefresh(placementIds: ["global_banner", "navigation_square_banner"])
|
1
2
3
4
| ArrayList<String> listOfBanners = new ArrayList<>();
listOfBanners.add("global_banner");
listOfBanners.add("navigation_square_banner");
Braze.getInstance(context).requestBannersRefresh(listOfBanners);
|
1
| Braze.getInstance(context).requestBannersRefresh(listOf("global_banner", "navigation_square_banner"))
|
1
| Braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
|
1
| This feature is not currently supported on Unity.
|
1
| This feature is not currently supported on Cordova.
|
1
| braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
|
1
| This feature is not currently supported on Roku.
|
Step 3: Listen for updates
tip:
If you insert banners using the SDK methods in this guide, all analytics events will be handled automatically. If you want to manually render the HTML, let us know.
1
2
3
4
5
6
7
8
| import * as braze from "@braze/web-sdk";
braze.subscribeToBannersUpdates((banners) => {
console.log(`Banners were updated`);
})
// always refresh after your subscriber function has been registered
braze.requestBannersRefresh(["global_banner", "navigation_square_banner"])
|
1
2
3
4
5
| let cancellable = brazeClient.braze()?.banners.subscribeToUpdates { banners in
banners.forEach { placementId, banner in
print("Received banner: \(banner) with placement ID: \(placementId)")
}
}
|
1
2
3
4
5
| Braze.getInstance(context).subscribeToBannersUpdates(banners -> {
for (Banner banner : banners.getBanners()) {
Log.d(TAG, "Received banner: " + banner.getPlacementId());
}
});
|
1
2
3
4
5
| Braze.getInstance(context).subscribeToBannersUpdates { update ->
for (banner in update.banners) {
Log.d(TAG, "Received banner: " + banner.placementId)
}
}
|
1
2
3
4
5
6
7
8
9
10
| const bannerCardsSubscription = Braze.addListener(
Braze.Events.BANNER_CARDS_UPDATED,
data => {
const banners = data.banners;
console.log(
`Received ${banners.length} Banner Cards with placement IDs:`,
banners.map(banner => banner.placementId),
);
},
);
|
1
| This feature is not currently supported on Unity.
|
1
| This feature is not currently supported on Cordova.
|
1
2
3
4
5
| StreamSubscription bannerStreamSubscription = braze.subscribeToBanners((List<BrazeBanner> banners) {
for (final banner in banners) {
print("Received banner: " + banner.toString());
}
});
|
1
| This feature is not currently supported on Roku.
|
Step 4: Embed using the placement ID
Create a container element for the banner. Be sure to set its width and height.
1
| <div id="global-banner-container" style="width: 100%; height: 450px;"></div>
|
Next, use the insertBanner
method to replace the inner HTML of the container element.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| import * as braze from "@braze/web-sdk";
braze.initialize("sdk-api-key", {
baseUrl: "sdk-base-url",
allowUserSuppliedJavascript: true, // banners require you to opt-in to user-supplied javascript
});
braze.subscribeToBannersUpdates((banners) => {
// get this placement's banner. If it's `null` the user did not qualify for one.
const globalBanner = braze.getBanner("global_banner");
if (!globalBanner) {
return;
}
// choose where in the DOM you want to insert the banner HTML
const container = document.getElementById("global-banner-container");
// Insert the banner which replacees the innerHTML of that container
braze.insertBanner(globalBanner, container);
// Special handling if the user is part of a Control Variant
if (globalBanner.isControl) {
// hide or collapse the container
container.style.display = 'none';
}
});
braze.requestBannersRefresh(["global_banner", "navigation_square_banner"])
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| // To get access to the Banner model object:
let globalBanner: Braze.Banner?
AppDelegate.braze?.banners.getBanner(for: "global_banner", { banner in
self.globalBanner = banner
})
// If you simply want the Banner view, you may initialize a `UIView` with the placement ID:
if let braze = AppDelegate.braze {
let bannerUIView = BrazeBannerUI.BannerUIView(
placementId: "global_banner",
braze: braze,
// iOS does not perform automatic resizing or visibility changes.
// Use the `processContentUpdates` parameter to adjust the size and visibility of your Banner Card according to your use case.
processContentUpdates: { result in
switch result {
case .success(let updates):
if let height = updates.height {
// Adjust the visibility and/or height.
}
case .failure(let error):
// Handle the error.
}
}
)
}
// Similarly, if you want a Banner view in SwiftUI, use the corresponding `BannerView` initializer:
if let braze = AppDelegate.braze {
let bannerView = BrazeBannerUI.BannerView(
placementId: "global_banner",
braze: braze,
// iOS does not perform automatic resizing or visibility changes.
// Use the `processContentUpdates` parameter to adjust the size and visibility of your Banner Card according to your use case.
processContentUpdates: { result in
switch result {
case .success(let updates):
if let height = updates.height {
// Adjust the visibility and/or height according to your parent controller.
}
case .failure(let error):
// Handle the error.
}
}
)
}
|
To get the Banner in Java code, use:
1
| Banner globalBanner = Braze.getInstance(context).getBanner("global_banner");
|
You can create Banner Cards in your Android views layout by including this XML:
1
2
3
4
5
| <com.braze.ui.banners.BannerView
android:id="@+id/global_banner_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:placementId="global_banner" />
|
To get the Banner in Kotlin, use:
1
| val banner = Braze.getInstance(context).getBanner("global_banner")
|
If you’re using Android Views, use this XML:
1
2
3
4
5
| <com.braze.ui.banners.BannerView
android:id="@+id/global_banner_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:placementId="global_banner" />
|
If you’re using Jetpack Compose, you can use this:
1
| Banner(placementId = "global_banner")
|
If you’re using React Native’s New Architecture, you need to register BrazeBannerView
as a Fabric component in your AppDelegate.mm
.
1
2
3
4
5
6
7
8
| #ifdef RCT_NEW_ARCH_ENABLED
/// Register the `BrazeBannerView` for use as a Fabric component.
- (NSDictionary<NSString *,Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents {
NSMutableDictionary * dictionary = [super thirdPartyFabricComponents].mutableCopy;
dictionary[@"BrazeBannerView"] = [BrazeBannerView class];
return dictionary;
}
#endif
|
To get the Banner Card’s data model in React Native, use:
1
| const banner = await Braze.getBanner("global_banner");
|
You may use the getBanner
method to check for the presence of that placement in your user’s cache. However, for the simplest integration, add the following JavaScript XML (JSX) snippet into your view hierarchy, providing just the placement ID.
1
2
3
| <Braze.BrazeBannerView
placementID='global_banner'
/>
|
1
| This feature is not currently supported on Unity.
|
1
| This feature is not currently supported on Cordova.
|
To get the Banner Card’s data model in Flutter, use:
1
2
3
4
5
6
7
| braze.getBanner("global_banner").then((banner) {
if (banner == null) {
// Handle null cases.
} else {
print(banner.toString());
}
});
|
You may use the getBanner
method to check for the presence of that placement in your user’s cache. However, for the simplest integration, add the following widget into your view hierarchy, providing just the placement ID.
1
2
3
| BrazeBannerView(
placementId: "global_banner",
),
|
1
| This feature is not currently supported on Roku.
|
Step 5: Send a test card (optional)
Before you launch a Banner Card campaign, you can send a test Banner Card to verify the integration. Test cards will be stored in a separate in-memory cache and won’t persist across app restarts. While no extra setup is needed, your test device must be capable of receiving foreground push notifications so it can display the test card.
note:
Test Banner Cards are like any other banners, except they’re removed at the next app session.
Logging analytics
Braze automatically logs impressions when you use SDK methods to insert a Banner Card—so no need to track impressions manually. If you need to parse and render the HTML in a custom view, contact us at [email protected].
Dimensions and sizing
Here’s some things to know about Banner Card dimensions and sizing:
- While the composer let’s you preview banners in different dimensions, that information is not saved or sent to the SDK.
- The HTML will take up the full width of the container it’s rendered in.
- We recommend making a fixed dimension element and testing those dimensions in composer.