Administrar ubicaciones de Banner
Aprende a crear y administrar ubicaciones de Banner en el SDK de Braze, incluido el acceso a sus propiedades únicas y el registro de impresiones. Para obtener información más general, consulta Acerca de los Banners.
Acerca de las solicitudes de ubicación
Cuando creas ubicaciones en tu aplicación o sitio web, tu aplicación envía una solicitud a Braze para obtener mensajes de banner para cada ubicación.
- Puedes solicitar hasta 10 ubicaciones por cada solicitud de actualización.
- Para cada ubicación, Braze devuelve el banner con mayor prioridad para el que el usuario es elegible.
- Si se solicitan más de 10 ubicaciones en una actualización, solo se devuelven las primeras 10; el resto se descartan.
Por ejemplo, una aplicación podría solicitar tres ubicaciones en una solicitud de actualización: homepage_promo, cart_abandonment y seasonal_offer. Cada solicitud devuelve el banner más relevante para esa ubicación.
Límite de velocidad para las solicitudes de actualización
Si utilizas versiones anteriores del SDK (anteriores a Swift 13.1.0, Android 38.0.0, Web 6.1.0, React Native 17.0.0 y Flutter 15.0.0), solo se permite una solicitud de actualización por sesión de usuario.
Si utilizas versiones mínimas más recientes del SDK (Swift 13.1.0+, Android 38.0.0+, Web 6.1.0+, React Native 17.0.0+ y Flutter 15.0.0+), las solicitudes de actualización se controlan mediante un algoritmo de token bucket para evitar un sondeo excesivo:
- Cada sesión de usuario comienza con cinco tokens de actualización.
- Los tokens se recargan a una tasa de un token cada 180 segundos (3 minutos).
Cada llamada explícita a requestBannersRefresh consume un token. La actualización automática que ocurre al inicio de una nueva sesión o cuando se llama a changeUser no consume un token, ya que esta actualización es una publicación del último banner almacenado en caché para ese usuario. Si intentas actualizar cuando no hay tokens disponibles, el SDK no realiza la solicitud y registra un error hasta que se repone un token. Esto es importante para las actualizaciones a mitad de sesión y las desencadenadas por eventos. Para implementar actualizaciones dinámicas (por ejemplo, después de que un usuario complete una acción en la misma página), llama al método de actualización después de que se registre el evento personalizado, pero ten en cuenta el retraso necesario para que Braze ingiera y procese el evento antes de que el usuario reúna los requisitos para una Campaign de banner diferente.
Crear una ubicación
Requisitos previos
Estas son las versiones mínimas del SDK necesarias para crear ubicaciones de Banner:
Paso 1: Crear ubicaciones en Braze
Si aún no lo has hecho, tendrás que crear ubicaciones para Banners en Braze, que se utilizan para definir los lugares en tu aplicación o sitio que pueden mostrar Banners. Para crear una ubicación, ve a Configuración > Ubicaciones de Banners y, a continuación, selecciona Crear ubicación.

Dale un nombre a tu ubicación y asígnale un ID de ubicación. Asegúrate de consultar a otros equipos antes de asignar un ID, ya que se utilizará durante todo el ciclo de vida de la tarjeta y no debería cambiarse posteriormente. Para más información, consulta ID de ubicación.


Para las ubicaciones web, puedes configurar opcionalmente Web Targeting en la ubicación para que el SDK de Braze para Web inserte automáticamente los Banners en un lugar concreto de la página, en lugar de llamar tú mismo a insertBanner(). Consulta Web Targeting: inserción automática de Banners.
Paso 2: Actualiza las ubicaciones en tu aplicación
Para actualizar las ubicaciones, llama a requestBannersRefresh() en tu SDK.
requestBannersRefresh() se fusiona con la caché de Banners existente. Solo se añaden, actualizan o eliminan los ID de ubicación que pases:
- Si el servidor devuelve un Banner para una ubicación solicitada, se reemplaza el Banner almacenado en caché para esa ubicación.
- Si el servidor no devuelve ningún Banner para una ubicación solicitada, esa ubicación se elimina de la caché.
- Los Banners almacenados en caché para ubicaciones que no solicitaste permanecen en la caché hasta que caducan.
Para saber cuántas ubicaciones puedes solicitar en cada actualización, consulta Acerca de las solicitudes de ubicación. Puedes actualizar distintos conjuntos de ubicaciones a lo largo del tiempo (por ejemplo, las ubicaciones de la pantalla actual) y mantener en la caché los Banners de otras ubicaciones.
El comportamiento de actualización de los Banners sigue dos caminos:
- Actualización explícita: Puedes llamar al método de actualización en cualquier momento durante una sesión activa.
- Actualización automática en una nueva sesión: Después de que hagas al menos una solicitud de actualización explícita, el SDK puede volver a solicitar los ID de ubicación solicitados más recientemente cuando se inicia una nueva sesión de Braze (por ejemplo, después de
changeUser()o tras el tiempo de espera de una sesión).
El papel de la suscripción a los eventos de Banner varía según la plataforma:
- iOS y Android:
subscribeToBannersEvents()en Android (osubscribeToEvents()en Swift) registra un controlador de eventos. La actualización automática al inicio de la sesión no depende de que la suscripción esté activa. - Web: La actualización automática al inicio de la sesión está vinculada al registro de
subscribeToBannersEvents()(o del obsoletosubscribeToBannersUpdates()). Sin una suscripción activa, el SDK no repite automáticamente la actualización en una nueva sesión.
En todos los casos, debes hacer al menos una solicitud de actualización explícita por ciclo de vida de la aplicación para que el SDK sepa qué ID de ubicación debe mantener actualizados. Los Banners no se obtienen automáticamente en el primer inicio sin esa llamada inicial, y los ID de ubicación rastreados se restablecen cuando se reinicia la aplicación.
Las actualizaciones automáticas al inicio de la sesión no consumen un token de límite de velocidad.

Actualiza las ubicaciones lo antes posible para evitar retrasos en la descarga o visualización de los Banners.
import * as braze from "@braze/web-sdk";
braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
AppDelegate.braze?.banners.requestBannersRefresh(placementIds: ["global_banner", "navigation_square_banner"])
ArrayList<String> placementIds = new ArrayList<>();
placementIds.add("global_banner");
placementIds.add("navigation_square_banner");
Braze.getInstance(context).requestBannersRefresh(placementIds);
Braze.getInstance(context).requestBannersRefresh(listOf("global_banner", "navigation_square_banner"))
Braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
This feature is not currently supported on Unity.
This feature is not currently supported on Cordova.
braze.requestBannersRefresh(["global_banner", "navigation_square_banner"]);
This feature is not currently supported on Roku.
Paso 3: Escucha las actualizaciones

Si insertas Banners con los métodos del SDK de esta guía, todos los eventos de análisis (como impresiones y clics) se gestionan automáticamente, y las impresiones solo se registran cuando el Banner está a la vista.
Usa subscribeToBannersEvents para escuchar los eventos de Banner y, a continuación, llama a requestBannersRefresh para obtener las ubicaciones. El SDK llama a tu controlador con un objeto de evento. Usa un switch sobre event.type para gestionar cada tipo de evento. Para más información sobre los valores de los eventos, consulta Suscripciones a eventos.
Si utilizas JavaScript vanilla con el SDK de Braze para Web, registra tu controlador antes de llamar a requestBannersRefresh.
import * as braze from "@braze/web-sdk";
const placementIds = ["global_banner", "navigation_square_banner"];
// - Available in version 7.0.0+
const subscriptionId = braze.subscribeToBannersEvents((event) => {
switch (event.type) {
case braze.ChannelEventType.CACHE_REPLAY:
// Sent once, right away, with the Banners that are already cached.
// Render them now instead of waiting for the network.
console.log("Cached Banners:", Object.keys(event.cacheSnapshot.banners));
break;
case braze.ChannelEventType.CACHE_LOAD:
// The cache changed without a refresh, such as after changeUser().
// The snapshot can be empty, so clear Banners from the previous user.
console.log("Cache reloaded:", Object.keys(event.cacheSnapshot.banners));
break;
case braze.ChannelEventType.DATA_UPDATED:
// A refresh finished, even if nothing changed, or a Banner was dismissed.
console.log("Banners were updated:", event.reason);
break;
case braze.ChannelEventType.ERROR:
switch (event.retryState) {
case braze.RetryState.SDK_WILL_RETRY:
// The SDK is retrying. Keep the current Banners and wait.
break;
case braze.RetryState.INTEGRATOR_MAY_RETRY: {
// The SDK stopped retrying. Try again later, and limit how often you retry.
const delayMs = event.rateLimitedUntil
? Math.max(event.rateLimitedUntil.getTime() - Date.now(), 0)
: 30000;
setTimeout(() => braze.requestBannersRefresh(placementIds), delayMs);
break;
}
case braze.RetryState.DO_NOT_RETRY:
// The failure is final. For example, Banners are disabled for this workspace.
if (event.reason === braze.ChannelErrorReason.FEATURE_DISABLED) {
// Hide the Banner containers.
}
break;
}
break;
}
});
const deprecatedSubscriptionId = braze.subscribeToBannersUpdates((banners) => {
console.log("Banners were updated");
});
// Always refresh after your subscriber function has been registered
braze.requestBannersRefresh(placementIds);
// Remove the subscription when you no longer need it
// braze.removeSubscription(subscriptionId);
Si utilizas React con el SDK de Braze para Web, configura subscribeToBannersEvents dentro de un hook useEffect y llama a requestBannersRefresh después de registrar tu oyente.
import * as braze from "@braze/web-sdk";
useEffect(() => {
const placementIds = ["global_banner", "navigation_square_banner"];
// - Available in version 7.0.0+
const subscriptionId = braze.subscribeToBannersEvents((event) => {
switch (event.type) {
case braze.ChannelEventType.CACHE_REPLAY:
case braze.ChannelEventType.CACHE_LOAD:
// Cached Banners, sent right away on subscribe or after the cache reloads
console.log("Cached Banners:", Object.keys(event.cacheSnapshot.banners));
break;
case braze.ChannelEventType.DATA_UPDATED:
// A refresh finished, even if nothing changed, or a Banner was dismissed
console.log("Banners were updated:", event.reason);
break;
case braze.ChannelEventType.ERROR:
if (event.retryState === braze.RetryState.INTEGRATOR_MAY_RETRY) {
// The SDK stopped retrying. Try again later, and limit how often you retry.
const delayMs = event.rateLimitedUntil
? Math.max(event.rateLimitedUntil.getTime() - Date.now(), 0)
: 30000;
setTimeout(() => braze.requestBannersRefresh(placementIds), delayMs);
}
break;
}
});
const deprecatedSubscriptionId = braze.subscribeToBannersUpdates((banners) => {
console.log("Banners were updated");
});
// Always refresh after your subscriber function has been registered
braze.requestBannersRefresh(placementIds);
// Cleanup listeners
return () => {
braze.removeSubscription(subscriptionId);
braze.removeSubscription(deprecatedSubscriptionId);
};
}, []);
Para saber cuándo se dispara cada evento y qué significa cada motivo de actualización, estado de reintento, acción de análisis y motivo de error, consulta Suscripciones a eventos.
event.cacheSnapshot.banners es un objeto que asigna cada ID de ubicación a su Banner. Puede incluir ubicaciones de actualizaciones anteriores, no solo los ID de ubicación de tu llamada más reciente a requestBannersRefresh. Si solo te interesan determinadas ubicaciones, lee esos ID de ubicación de la instantánea y omite el resto.
Usa subscribeToBannersEvents en el SDK para Web 7.0.0 y posteriores. subscribeToBannersUpdates es el patrón anterior, obsoleto desde la versión 7.0.0. El patrón anterior solo entrega los Banners actuales, por lo que no puede indicarte por qué cambiaron los Banners ni cuándo falló una actualización.

Tu oyente de actualizaciones de Banner refleja el estado de los Banners en la memoria del SDK. Una sola actualización puede incluir ubicaciones que ya estaban en caché (por ejemplo, de una actualización anterior, de otra pantalla o de un trabajo automático del SDK), no solo los ID de ubicación de tu llamada más reciente a requestBannersRefresh. Si solo te interesan determinadas ubicaciones, comprueba el ID de ubicación de cada Banner en tu oyente y omite el resto. Cuando hayas registrado tu oyente, llama a requestBannersRefresh para las ubicaciones que quieras sincronizar desde Braze.
// - Available in version 19.0.0+
let placementIds = ["global_banner", "navigation_square_banner"]
let cancellable = brazeClient.braze()?.banners.subscribeToEvents { event in
switch event {
case .cacheReplay(let cacheSnapshot), .cacheLoad(let cacheSnapshot):
cacheSnapshot.banners.forEach { placementId, banner in
print("Received banner: \(banner) with placement ID: \(placementId)")
}
case .dataUpdated(let cacheSnapshot, let reason):
cacheSnapshot.banners.forEach { placementId, banner in
print("Received banner: \(banner) with placement ID: \(placementId)")
}
default:
break
}
}
// Always refresh after your subscriber is registered
brazeClient.braze()?.banners.requestBannersRefresh(placementIds: placementIds)
let placementIds = ["global_banner", "navigation_square_banner"]
let cancellable = brazeClient.braze()?.banners.subscribeToUpdates { banners in
banners.forEach { placementId, banner in
print("Received banner: \(banner) with placement ID: \(placementId)")
}
}
// Always refresh after your subscriber is registered
brazeClient.braze()?.banners.requestBannersRefresh(placementIds: placementIds)
Usa subscribeToEvents(_:) en el SDK para Swift 19.0.0 y posteriores. subscribeToUpdates(_:) es el patrón anterior, obsoleto desde la versión 19.0.0.
Para saber cuándo se dispara cada evento y qué significa cada motivo de actualización, estado de reintento, acción de análisis y motivo de error, consulta Suscripciones a eventos.
Estos pasos requieren el SDK para Android 44.0.0 o posterior. Úsalos para renderizar Banners sin reaccionar a los datos en caché.

Tu controlador de eventos de Banner refleja el estado de los Banners en la memoria del SDK. Un solo evento puede incluir ubicaciones que ya estaban en caché (por ejemplo, de una actualización anterior, de otra pantalla o de un trabajo automático del SDK), no solo los ID de ubicación de tu llamada más reciente a requestBannersRefresh. Si solo te interesan determinadas ubicaciones, comprueba el ID de ubicación de cada Banner en tu controlador y omite el resto. Cuando hayas registrado tu suscriptor, llama a requestBannersRefresh para las ubicaciones que quieras sincronizar desde Braze.
-
Suscríbete a los eventos de Banner con
subscribeToBannersEvents. Gestiona cada tipo de evento por separado. | Evento | Cuándo se dispara | |—|—| |CacheReplay| Justo después de suscribirte. Contiene los Banners en caché, que pueden no coincidir con tu última solicitud. | |CacheLoad| Cuando el SDK carga la caché de Banners desde el disco, por ejemplo, al inicio de una sesión. | |DataUpdated| Cuando cambia la caché, incluida cada vez que se completa una actualización. |val bannerSubscriber = IEventSubscriber<BannersEvent> { event -> when (event) { is BannersEvent.CacheReplay -> { // Cached Banners. Don't show fallback content based on this event. } is BannersEvent.DataUpdated -> { val cachedPlacementIds = event.cacheSnapshot.banners.values.map { it.placementId } Log.d(TAG, "Banner cache updated: $cachedPlacementIds") // Update any Banners that are already on screen. } else -> Unit } } Braze.getInstance(context).subscribeToBannersEvents(bannerSubscriber)
-
Llama a
requestBannersRefreshcon los ID de ubicación de la pantalla actual. Pasa una devolución de llamada de finalización para saber cuándo termina la actualización.val requestedPlacementIds = listOf("global_banner", "navigation_square_banner") Braze.getInstance(context).requestBannersRefresh( requestedPlacementIds, object : IValueCallback<BannersUpdatedEvent> { override fun onSuccess(value: BannersUpdatedEvent) { // The refresh finished. Check each requested placement. } } )
-
En la devolución de llamada, llama a
getBannerpara cada ID de ubicación que hayas solicitado. SigetBannerdevuelvenull, la ubicación no tiene contenido de Banner para el usuario actual. Muestra tu contenido alternativo para esa ubicación.requestedPlacementIds.forEach { placementId -> val banner = Braze.getInstance(context).getBanner(placementId) if (banner == null) { Log.d(TAG, "No Banner content for $placementId") } else { Log.d(TAG, "Banner available for ${banner.placementId}") } }
-
Cuando ya no necesites el suscriptor, elimínalo.
Braze.getInstance(context).removeSingleSubscription(bannerSubscriber, BannersEvent::class.java)
Ten en cuenta lo siguiente:
- Los Banners en caché para ubicaciones que no solicitaste permanecen en la caché, por lo que los eventos
DataUpdatedpueden incluir ubicaciones de otras pantallas. Filtra por los ID de ubicación de tu pantalla actual. - Una ubicación solicitada sin contenido de Banner no aparece en el evento
DataUpdated. UsagetBanneren la devolución de llamada de finalización en lugar de esperar a que llegue un Banner coincidente en un evento. - Una actualización completada envía un evento
DataUpdatedaunque el contenido del Banner no haya cambiado.
Los eventos llegan en un subproceso en segundo plano. Cambia al subproceso principal antes de actualizar las vistas.
Usa subscribeToBannersEvents en el SDK para Android 44.0.0 y posteriores. subscribeToBannersUpdates es el patrón anterior, obsoleto desde la versión 44.0.0.
Para saber cuándo se dispara cada evento y qué significa cada motivo de actualización, estado de reintento, acción de análisis y motivo de error, consulta Suscripciones a eventos.
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)
);
}
);
This feature is not currently supported on Unity.
This feature is not currently supported on Cordova.
StreamSubscription bannerStreamSubscription = braze.subscribeToBanners((List<BrazeBanner> banners) {
for (final banner in banners) {
print("Received banner: " + banner.toString());
}
});
This feature is not currently supported on Roku.
Paso 4: Inserta usando el ID de ubicación

Crea un elemento contenedor para el Banner. Asegúrate de establecer su anchura y altura.
<div id="global-banner-container" style="width: 100%; height: 450px;"></div>
Si utilizas JavaScript vanilla con el SDK de Braze para Web, llama al método insertBanner para reemplazar el HTML interno del elemento contenedor.
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
});
// - Available in version 7.0.0+
braze.subscribeToBannersEvents((event) => {
const container = document.getElementById("global-banner-container");
switch (event.type) {
case braze.ChannelEventType.CACHE_REPLAY:
case braze.ChannelEventType.CACHE_LOAD:
case braze.ChannelEventType.DATA_UPDATED: {
// get this placement's banner. If it's missing the user did not qualify for one.
const globalBanner = event.cacheSnapshot.banners["global_banner"];
if (!globalBanner) {
container.style.display = "none";
return;
}
// Insert the banner which replaces the innerHTML of that container
braze.insertBanner(globalBanner, container);
// Special handling if the user is part of a Control Variant
container.style.display = globalBanner.isControl ? "none" : "";
break;
}
case braze.ChannelEventType.ERROR:
if (event.reason === braze.ChannelErrorReason.FEATURE_DISABLED) {
// Banners are disabled, so hide the container
container.style.display = "none";
}
break;
}
});
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;
}
const container = document.getElementById("global-banner-container");
// Insert the banner which replaces 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"]);
Usa subscribeToBannersEvents en el SDK para Web 7.0.0 y posteriores. subscribeToBannersUpdates es el patrón anterior, obsoleto desde la versión 7.0.0.
Si utilizas React con el SDK de Braze para Web, llama al método insertBanner con un ref para reemplazar el HTML interno del elemento contenedor.
import { useRef } from 'react';
import * as braze from "@braze/web-sdk";
export default function App() {
const bannerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const globalBanner = braze.getBanner("global_banner");
if (!globalBanner || globalBanner.isControl) {
// hide the container
} else {
// insert the banner to the container node
braze.insertBanner(globalBanner, bannerRef.current);
}
}, []);
return <div ref={bannerRef}></div>
}

Para hacer un seguimiento de las impresiones, asegúrate de llamar a insertBanner para isControl. Después, puedes ocultar o contraer tu contenedor.
Después de una actualización, el SDK actualiza un BannerUIView o BannerView solo cuando cambia el contenido en caché de esa ubicación (se añade, se elimina o se actualiza). Los Banners mostrados que no cambian se quedan como están. Llamar a changeUser() actualiza todas las vistas de Banner registradas.
// To get access to the Banner model object:
let globalBanner: Braze.Banner?
AppDelegate.braze?.banners.getBanner(for: "global_banner", { banner in
self.globalBanner = banner
})
// UIKit implementation:
// If you simply want the Banner view, 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 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.
}
}
)
}
// SwiftUI implementation:
// 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 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.
}
}
)
}
Después de una actualización, el SDK actualiza un BannerView solo cuando cambia el contenido en caché de esa ubicación (se añade, se elimina o se actualiza). Los Banners mostrados que no cambian se quedan como están. Llamar a changeUser() sigue actualizando todos los BannerView registrados.
Para obtener el Banner en código Java, usa:
Banner globalBanner = Braze.getInstance(context).getBanner("global_banner");
Puedes crear Banners en el diseño de tus vistas de Android incluyendo este XML:
<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" />
Si utilizas vistas de Android, usa este XML:
<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" />
Para usar Jetpack Compose, añade el artefacto com.braze:android-sdk-jetpack-compose al módulo de tu aplicación. Usa la misma versión que tus otras dependencias del SDK de Braze para Android. Este módulo es independiente de android-sdk-ui e incluye el composable Banner en com.braze.jetpackcompose.banners.

Algunas bibliotecas de interfaz de usuario de Compose definen su propio composable Banner. Importa com.braze.jetpackcompose.banners.Banner explícitamente para llamar a la API de Braze.
import com.braze.jetpackcompose.banners.Banner
@Composable
fun myBannerSlot() {
Banner(placementId = "global_banner")
}
Opcionalmente, pasa heightCallback para recibir la altura renderizada en dp cuando cambie el tamaño del Banner. Como referencia, consulta el KDoc de Banner.
Si no añades el módulo de Jetpack Compose, envuelve BannerView en AndroidView:
import android.view.ViewGroup
import androidx.compose.runtime.Composable
import androidx.compose.ui.viewinterop.AndroidView
import com.braze.ui.banners.BannerView
@Composable
fun myBannerSlot() {
AndroidView(
factory = { context ->
BannerView(context, "global_banner").apply {
layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
},
update = { it.placementId = "global_banner" }
)
}
Para obtener el Banner en Kotlin, usa:
val banner = Braze.getInstance(context).getBanner("global_banner")
Si utilizas la Nueva Arquitectura de React Native, tienes que registrar BrazeBannerView como componente Fabric en tu AppDelegate.mm.
#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
Para la integración más sencilla, añade el siguiente fragmento de código JavaScript XML (JSX) a tu jerarquía de vistas, proporcionando solo el ID de ubicación.
<Braze.BrazeBannerView
placementId='global_banner'
/>
Para obtener el modelo de datos del Banner en React Native, o para comprobar si esa ubicación está presente en la caché de tu usuario, usa:
const banner = await Braze.getBanner("global_banner");
This feature is not currently supported on Unity.
This feature is not currently supported on Cordova.
Para la integración más sencilla, añade el siguiente widget a tu jerarquía de vistas, proporcionando solo el ID de ubicación.
BrazeBannerView(
placementId: "global_banner",
),
To get the Banner's data model in Flutter, use:
Puedes usar el método getBanner para comprobar si esa ubicación está presente en la caché de tu usuario.
braze.getBanner("global_banner").then((banner) {
if (banner == null) {
// Handle null cases.
} else {
print(banner.toString());
}
});
This feature is not currently supported on Roku.
Paso 5: Envía un Banner de prueba (opcional)
Antes de lanzar una campaña de Banner, puedes enviar un Banner de prueba para verificar tu integración. Los Banners de prueba se almacenan en una caché en memoria independiente y no persisten tras reiniciar la aplicación. Aunque no se necesita ninguna configuración adicional, tu dispositivo de prueba debe poder recibir notificaciones push en primer plano para poder mostrar la prueba.

Los Banners de prueba son como cualquier otro Banner, salvo que se eliminan en la siguiente sesión de la aplicación.
Registrar impresiones
Braze registra automáticamente las impresiones de los banners que están a la vista cuando utilizas métodos del SDK para insertar un banner—así que no necesitas hacer un seguimiento manual de las impresiones.
Registro de clics
El método para registrar los clics en un Banner depende de cómo se renderiza el Banner y de dónde se encuentra tu controlador de clics.
Contenido estándar del Banner (automático)
Si usas los métodos predeterminados integrados del SDK para insertar Banners y tu Banner usa componentes estándar del editor (imágenes, botones, texto), los clics se registran automáticamente. El SDK añade detectores de clics a estos elementos y no necesitas código adicional.
Bloques de código personalizado
Si tu Banner usa el bloque de editor Código personalizado en el panel de Braze, debes usar brazeBridge.logClick() para registrar los clics desde ese HTML personalizado. Esto se aplica incluso cuando usas los métodos del SDK para renderizar el Banner, porque el SDK no puede añadir automáticamente detectores a los elementos dentro de tu código personalizado.
<button onclick="brazeBridge.logClick()">
Click me
</button>
Para ver la referencia completa, consulta Código personalizado y puente JavaScript para Banners. El brazeBridge proporciona una capa de comunicación entre el HTML interno del Banner y el SDK de Braze principal.
Implementaciones de interfaz de usuario personalizadas (headless)
Si estás creando una interfaz de usuario totalmente personalizada con las propiedades personalizadas del Banner en lugar de renderizar el HTML del Banner, debes registrar manualmente los clics y las impresiones desde el código de tu aplicación. Como el SDK no renderiza el Banner, no tiene forma de hacer un seguimiento automático de las interacciones con los elementos de tu interfaz personalizada.
Para ver las firmas de los métodos y todos los detalles, consulta la documentación de referencia del SDK de Braze.
Registro de impresiones
Llama al método de impresión de Banner de la plataforma cuando tu interfaz personalizada considere que el Banner se ha “visto”. Crea una lógica sólida para determinar qué cuenta como impresión y así evitar eventos duplicados; por ejemplo, registra la impresión solo cuando el Banner entre en la ventana gráfica (o equivalente), y no vuelvas a registrarla cuando el mismo Banner vuelva a aparecer al desplazarse o cuando tu componente se vuelva a renderizar sin un nuevo evento de visualización.
import * as braze from "@braze/web-sdk";
// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
const banner = braze.getBanner("placement_id_homepage_top");
if (banner) {
braze.logBannerImpressions([banner]);
}
// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
Braze.getInstance(context).logBannerImpression("placement_id_homepage_top")
// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
Braze.getInstance(context).logBannerImpression("placement_id_homepage_top");
// Retrieve a banner and log an impression on it (for example, once when it enters viewport)
braze.banners.getBanner(for: "placement_id_homepage_top") { banner in
banner?.context.logImpression()
}
// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
Braze.logBannerImpression("placement_id_homepage_top");
Consulta el repositorio del SDK para React Native para ver las firmas de métodos más recientes.
// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
braze.logBannerImpression("placement_id_homepage_top");
Registro de clics
Llama al método de clic de Banner de la plataforma cuando el usuario toque tu Banner personalizado (o un botón específico). Pasa el parámetro opcional buttonId cuando el clic se produzca en un botón específico para que los análisis puedan atribuir el clic correctamente.
import * as braze from "@braze/web-sdk";
// Log click
braze.logBannerClick("placement_id_homepage_top", buttonId); // buttonID is optional
// Log click
Braze.getInstance(context).logBannerClick("placement_id_homepage_top", buttonId) // buttonID parameter can be null
// Log click
Braze.getInstance(context).logBannerClick("placement_id_homepage_top", buttonId); // buttonID parameter can be null
// Retrieve a banner and log a click on it
braze.banners.getBanner(for: "placement_id_homepage_top") { banner in
banner?.context.logClick(buttonId: buttonId) // buttonID is optional
}
// Log click
Braze.logBannerClick("placement_id_homepage_top", buttonId); // buttonID is optional
Consulta el repositorio del SDK para React Native para ver las firmas de métodos más recientes.
// Log click
braze.logBannerClicked("placement_id_homepage_top", buttonId); // buttonID parameter can be null
Registrar descartes
Los descartes de Banner eliminan de forma programática un Banner de una ubicación cuando un usuario lo descarta activamente. Al descartarlo, el Banner se suprime para ese usuario. La próxima vez que se actualice la lista de ubicaciones, se devolverá un nuevo banner si el usuario es elegible para uno.
Requisitos previos
Estas son las versiones mínimas del SDK necesarias para registrar descartes de Banner:
Integraciones
Integraciones estándar de Banner (editor de arrastrar y soltar)
Si tu Banner usa el editor de arrastrar y soltar e incluye un componente de botón de descarte, no necesitas código adicional. Cuando un usuario hace clic en el botón de descarte, el mensaje se oculta, desencadena un descarte y, a continuación, registra un evento de descarte para los análisis.
Bloques de código personalizado
Si tu Banner usa el bloque de editor Código personalizado, puedes desencadenar un descarte directamente desde el HTML del Banner con brazeBridge.closeMessage().
<button onclick="brazeBridge.closeMessage()">
Dismiss
</button>
Descartar un banner de forma programática
Si usas el BrazeBannerView estándar con el botón de descarte creado en el editor de arrastrar y soltar, no necesitas código adicional; el descarte se gestiona automáticamente.
Para integraciones de interfaz de usuario personalizadas, puedes llamar al método de descarte directamente en tu instancia de Braze para descartar un banner de forma programática y registrar un evento de descarte. Es seguro llamar al método de descarte varias veces: el SDK ignora las llamadas duplicadas para el mismo banner.
Estas son las versiones mínimas del SDK necesarias para descartar un banner de forma programática:
Pasa el objeto Banner a braze.dismissBanner(). Puedes obtener el objeto Banner de braze.getAllBanners() o del objeto cacheSnapshot.banners de un evento subscribeToBannersEvents.
import * as braze from "@braze/web-sdk";
const banners = braze.getAllBanners();
const banner = banners["global_banner"];
if (banner) {
braze.dismissBanner(banner);
}
import * as braze from "@braze/web-sdk";
const banners = braze.getAllBanners();
const banner = banners["global_banner"];
if (banner) {
braze.dismissBanner(banner);
}
Braze.getInstance(context).dismissBanner("your-placement-id");
Braze.getInstance(context).dismissBanner("your-placement-id")
dismissBanner() elimina el Banner de la caché y publica BannersEvent.DataUpdated con ChannelUpdateReason.CLIENT_ACTION para que las interfaces de usuario personalizadas puedan volver a renderizarse. Los widgets BannerView se ocultan cuando reciben BannerDismissedEvent. BannersEvent.DismissEvent es el ciclo de vida de análisis de ese descarte, no una señal para ocultar la vista.
Usa dismiss() en el contexto del banner cuando esté disponible. Este método es idempotente y activa automáticamente la devolución de llamada onDismiss. Si el contexto no está disponible, llama a dismiss(using:) directamente en el banner. Ambos métodos deben llamarse desde el hilo principal.
// Preferred: dismiss via context.
banner.context?.dismiss()
// Fallback: if context is unavailable.
banner.dismiss(using: braze)
En Objective-C, están disponibles como [banner.context dismiss] y [banner dismissUsing:braze].
Braze.dismissBanner("your-placement-id");
braze.dismissBanner("your-placement-id");
Registrar análisis personalizados al descartar un banner
Para ejecutar una lógica personalizada cuando se descarta un banner, como registrar análisis, usa la devolución de llamada de descarte de tu SDK. La devolución de llamada recibe un objeto de evento con placementId, stableKey y trackingId del banner.
Usa Banner.subscribeToDismissedEvent() para ejecutar una lógica personalizada cuando se descarte un banner concreto. Suscríbete al evento antes de mostrar el banner.

Banner.subscribeToDismissedEvent() requiere la versión 6.9.0 o posterior del SDK Web. En versiones anteriores, usa braze.subscribeToBannersUpdates() y detecta el descarte comprobando si el banner ya no está presente en el mapa de banners actualizado. En la versión 7.0.0 o posterior del SDK Web, también puedes escuchar el evento DISMISS de braze.subscribeToBannersEvents().
import * as braze from "@braze/web-sdk";
// - Available in version 7.0.0+
braze.subscribeToBannersEvents((event) => {
if (
event.type !== braze.ChannelEventType.CACHE_REPLAY &&
event.type !== braze.ChannelEventType.CACHE_LOAD &&
event.type !== braze.ChannelEventType.DATA_UPDATED
) {
return;
}
const banner = event.cacheSnapshot.banners["global_banner"];
if (banner) {
banner.subscribeToDismissedEvent(() => {
// Run any custom logic here, such as logging custom analytics
console.log("Banner was dismissed");
});
}
});
braze.subscribeToBannersUpdates((banners) => {
const banner = banners["global_banner"];
if (banner) {
banner.subscribeToDismissedEvent(() => {
// Run any custom logic here, such as logging custom analytics
console.log("Banner was dismissed");
});
}
});
braze.requestBannersRefresh(["global_banner"]);
Usa subscribeToBannersEvents en la versión 7.0.0 y posteriores del SDK Web. subscribeToBannersUpdates es el patrón anterior, obsoleto desde la versión 7.0.0.
import { useEffect } from "react";
import * as braze from "@braze/web-sdk";
useEffect(() => {
// - Available in version 7.0.0+
const subscriptionId = braze.subscribeToBannersEvents((event) => {
if (
event.type !== braze.ChannelEventType.CACHE_REPLAY &&
event.type !== braze.ChannelEventType.CACHE_LOAD &&
event.type !== braze.ChannelEventType.DATA_UPDATED
) {
return;
}
const banner = event.cacheSnapshot.banners["global_banner"];
if (banner) {
banner.subscribeToDismissedEvent(() => {
// Run any custom logic here, such as logging custom analytics
console.log("Banner was dismissed");
});
}
});
const deprecatedSubscriptionId = braze.subscribeToBannersUpdates((banners) => {
const banner = banners["global_banner"];
if (banner) {
banner.subscribeToDismissedEvent(() => {
// Run any custom logic here, such as logging custom analytics
console.log("Banner was dismissed");
});
}
});
braze.requestBannersRefresh(["global_banner"]);
return () => {
braze.removeSubscription(subscriptionId);
braze.removeSubscription(deprecatedSubscriptionId);
};
}, []);
Usa subscribeToBannersEvents en la versión 7.0.0 y posteriores del SDK Web. subscribeToBannersUpdates es el patrón anterior, obsoleto desde la versión 7.0.0.
Establece la propiedad opcional onDismissCallback en BannerView.
import android.util.Log;
import com.braze.ui.banners.BannerView;
import kotlin.Unit;
// After obtaining your BannerView instance (for example from XML via findViewById, or `new BannerView(context, "global_banner")`)
bannerView.setOnDismissCallback((snapshot) -> {
Log.d(TAG, "placementId: " + snapshot.getPlacementId()
+ ", stableKey: " + snapshot.getStableKey()
+ ", trackingId: " + snapshot.getTrackingId());
// Run any custom logic here, such as logging custom analytics
return Unit.INSTANCE;
});
import android.util.Log
import com.braze.ui.banners.BannerView
// After obtaining your BannerView instance (for example via findViewById or `BannerView(context, "global_banner")`)
bannerView.onDismissCallback = { snapshot ->
Log.d(TAG, "placementId: ${snapshot.placementId}, stableKey: ${snapshot.stableKey}, trackingId: ${snapshot.trackingId}")
// Run any custom logic here, such as logging custom analytics
}
// After initializing your banner view instance using UIKit or SwiftUI
bannerView.onDismiss = { event in
print("Banner dismissed — placementId: \(event.placementId ?? "unknown")")
print(" stableKey: \(event.stableKey ?? "unknown")")
print(" trackingId: \(event.trackingId ?? "unknown")")
// Run any custom logic here, such as logging custom analytics
}
Establece la prop onDismiss en Braze.BrazeBannerView para ejecutar una lógica personalizada cuando se descarte un banner.
import Braze from "@braze/react-native-sdk";
<Braze.BrazeBannerView
placementId="global_banner"
onDismiss={(event) => {
console.log("placementId:", event.placementId, "stableKey:", event.stableKey, "trackingId:", event.trackingId);
// Run any custom logic here, such as logging custom analytics
}}
/>
Establece el parámetro onDismiss en BrazeBannerView para ejecutar una lógica personalizada cuando se descarte un banner.
BrazeBannerView(
placementId: 'global_banner',
onDismiss: (BrazeBannerDismissEvent event) {
print('placementId: ${event.placementId}, stableKey: ${event.stableKey}, trackingId: ${event.trackingId}');
// Run any custom logic here, such as logging custom analytics
},
)
Límite de almacenamiento de descartes pendientes
Los eventos de descarte se almacenan localmente como entradas pendientes hasta que se pueden sincronizar con el servidor de Braze en la siguiente llamada a requestBannersRefresh.

En casos poco frecuentes en los que se acumula un gran número de descartes sin una sincronización correcta, es posible que se eliminen los descartes pendientes más antiguos. Si esto ocurre, los Banners descartados anteriormente pueden volver a aparecer hasta que se complete la siguiente sincronización correcta. Para minimizar este riesgo, llama a requestBannersRefresh cada vez que tu aplicación recupere la conectividad de red.
Dimensiones y tamaño
Esto es lo que necesitas saber sobre las dimensiones y el tamaño de los banners:
- Aunque el creador te permite obtener una vista previa de los banners en diferentes dimensiones, esa información no se guarda ni se envía al SDK.
- El HTML ocupará todo el ancho del contenedor en el que se renderice.
- Te recomendamos crear un elemento de dimensiones fijas y probar esas dimensiones en el creador.
Propiedades personalizadas
Puedes utilizar propiedades personalizadas de tu campaña de banners para recuperar datos clave-valor a través del SDK y modificar el comportamiento o la apariencia de tu aplicación. Por ejemplo, podrías:
- Envía metadatos para tus análisis o integraciones de terceros.
- Usa metadatos como un
timestampu objeto JSON para desencadenar lógica condicional. - Controla el comportamiento de un Banner basándote en metadatos incluidos como
ratiooformat.
Requisitos previos
Debes añadir propiedades personalizadas a tu campaña de banners. Además, estas son las versiones mínimas del SDK necesarias para acceder a las propiedades personalizadas:
Acceder a las propiedades personalizadas
Para acceder a las propiedades personalizadas de un banner, utiliza uno de los siguientes métodos según el tipo de propiedad definido en el panel. Si la clave no coincide con una propiedad de ese tipo o no existe, el método devuelve null.
// Returns the Banner instance
const banner = braze.getBanner("placement_id_homepage_top");
// banner may be undefined or null
if (banner) {
// Returns the string property
const stringProperty = banner.getStringProperty("color");
// Returns the boolean property
const booleanProperty = banner.getBooleanProperty("expanded");
// Returns the number property
const numberProperty = banner.getNumberProperty("height");
// Returns the timestamp property (as a number)
const timestampProperty = banner.getTimestampProperty("account_start");
// Returns the image URL property as a string of the URL
const imageProperty = banner.getImageProperty("homepage_icon");
// Returns the JSON object property
const jsonObjectProperty = banner.getJsonProperty("footer_settings");
}
// Passes the specified banner to the completion handler
AppDelegate.braze?.banners.getBanner(for: "placement_id_homepage_top") { banner in
// Returns the string property
let stringProperty: String? = banner.stringProperty(key: "color")
// Returns the boolean property
let booleanProperty: Bool? = banner.boolProperty(key: "expanded")
// Returns the number property as a double
let numberProperty: Double? = banner.numberProperty(key: "height")
// Returns the Unix UTC millisecond timestamp property as an integer
let timestampProperty: Int? = banner.timestampProperty(key: "account_start")
// Returns the image property as a String of the image URL
let imageProperty: String? = banner.imageProperty(key: "homepage_icon")
// Returns the JSON object property as a [String: Any] dictionary
let jsonObjectProperty: [String: Any]? = banner.jsonObjectProperty(key: "footer_settings")
}
// Returns the Banner instance
Banner banner = Braze.getInstance(context).getBanner("placement_id_homepage_top");
// banner may be undefined or null
if (banner != null) {
// Returns the string property
String stringProperty = banner.getStringProperty("color");
// Returns the boolean property
Boolean booleanProperty = banner.getBooleanProperty("expanded");
// Returns the number property
Number numberProperty = banner.getNumberProperty("height");
// Returns the timestamp property (as a Long)
Long timestampProperty = banner.getTimestampProperty("account_start");
// Returns the image URL property as a String of the URL
String imageProperty = banner.getImageProperty("homepage_icon");
// Returns the JSON object property as a JSONObject
JSONObject jsonObjectProperty = banner.getJSONProperty("footer_settings");
}
// Returns the Banner instance
val banner: Banner = Braze.getInstance(context).getBanner("placement_id_homepage_top") ?: return
// Returns the string property
val stringProperty: String? = banner.getStringProperty("color")
// Returns the boolean property
val booleanProperty: Boolean? = banner.getBooleanProperty("expanded")
// Returns the number property
val numberProperty: Number? = banner.getNumberProperty("height")
// Returns the timestamp property (as a Long)
val timestampProperty: Long? = banner.getTimestampProperty("account_start")
// Returns the image URL property as a String of the URL
val imageProperty: String? = banner.getImageProperty("homepage_icon")
// Returns the JSON object property as a JSONObject
val jsonObjectProperty: JSONObject? = banner.getJSONProperty("footer_settings")
// Get the Banner instance
const banner = await Braze.getBanner('placement_id_homepage_top');
if (!banner) return;
// Get the string property
const stringProperty = banner.getStringProperty('color');
// Get the boolean property
const booleanProperty = banner.getBooleanProperty('expanded');
// Get the number property
const numberProperty = banner.getNumberProperty('height');
// Get the timestamp property (as a number)
const timestampProperty = banner.getTimestampProperty('account_start');
// Get the image URL property as a string
const imageProperty = banner.getImageProperty('homepage_icon');
// Get the JSON object property
const jsonObjectProperty = banner.getJSONProperty('footer_settings');
// Fetch the banner asynchronously
_braze.getBanner(placementId).then(('placement_id_homepage_top') {
// Get the string property
final String? stringProperty = banner?.getStringProperty('color');
// Get the boolean property
final bool? booleanProperty = banner?.getBooleanProperty('expanded');
// Get the number property
final num? numberProperty = banner?.getNumberProperty('height');
// Get the timestamp property
final int? timestampProperty = banner?.getTimestampProperty('account_start');
// Get the image URL property
final String? imageProperty = banner?.getImageProperty('homepage_icon');
// Get the JSON object property
final Map<String, dynamic>? jsonObjectProperty = banner?.getJSONProperty('footer_settings');
// Use these properties as needed in your UI or logic
});