Ir para o conteúdo

Gerenciar posicionamentos de Banner

Aprenda como criar e gerenciar posicionamentos de Banner no SDK da Braze, incluindo o acesso às suas propriedades exclusivas e o registro de impressões. Para mais informações gerais, veja Sobre Banners.

Sobre solicitações de posicionamento

Quando você cria posicionamentos no seu app ou site, seu app envia uma solicitação para a Braze buscar mensagens de Banner para cada posicionamento.

  • Você pode solicitar até 10 posicionamentos por solicitação de atualização.
  • Para cada posicionamento, a Braze retorna o Banner de maior prioridade que o usuário é elegível para receber.
  • Se mais de 10 posicionamentos forem solicitados em uma atualização, apenas os primeiros 10 são retornados; os demais são descartados.

Por exemplo, um app pode solicitar três posicionamentos em uma solicitação de atualização: homepage_promo, cart_abandonment e seasonal_offer. Cada solicitação retorna o Banner mais relevante para aquele posicionamento.

Limite de frequência para solicitações de atualização

Se você estiver em versões mais antigas do SDK (antes do Swift 13.1.0, Android 38.0.0, Web 6.1.0, React Native 17.0.0 e Flutter 15.0.0), apenas uma solicitação de atualização é permitida por sessão de usuário.

Se você estiver em versões mínimas mais novas do SDK (Swift 13.1.0+, Android 38.0.0+, Web 6.1.0+, React Native 17.0.0+ e Flutter 15.0.0+), as solicitações de atualização são controladas por um algoritmo de token bucket para evitar polling excessivo:

  • Cada sessão de usuário começa com cinco tokens de atualização.
  • Os tokens são reabastecidos a uma taxa de um token a cada 180 segundos (3 minutos).

Cada chamada explícita para requestBannersRefresh consome um token. A atualização automática que ocorre no início de uma nova sessão ou quando changeUser é chamado não consome um token, pois essa atualização é uma publicação do último Banner em cache para aquele usuário. Se você tentar uma atualização quando não houver tokens disponíveis, o SDK não faz a solicitação e registra um erro até que um token seja reabastecido. Isso é importante para atualizações durante a sessão e atualizações disparadas por eventos. Para implementar atualizações dinâmicas (por exemplo, após um usuário completar uma ação na mesma página), chame o método de atualização após o evento personalizado ser registrado, mas observe um delay necessário para a Braze ingerir e processar o evento antes que o usuário se qualifique para uma Campaign de Banner diferente.

Criar um posicionamento

Pré-requisitos

Estas são as versões mínimas do SDK necessárias para criar posicionamentos de Banner:

Etapa 1: Criar posicionamentos na Braze

Se ainda não o fez, você precisará criar posicionamentos de Banner na Braze, que são usados para definir os locais em seu app ou site que podem exibir Banners. Para criar um posicionamento, acesse Configurações > Posicionamentos de Banners e selecione Criar posicionamento.

Seção de posicionamentos de Banner para criar IDs de posicionamento.

Dê um nome ao seu posicionamento e atribua um ID de posicionamento. Consulte outras equipes antes de atribuir um ID, pois ele será usado durante todo o ciclo de vida do cartão e não deve ser alterado posteriormente. Para saber mais, consulte IDs de posicionamento.

Detalhes de posicionamento que indicam que um Banner será exibido na barra lateral esquerda para campanhas de promoção de vendas de primavera.

Etapa 2: Atualizar posicionamentos no seu app

Para atualizar posicionamentos, chame requestBannersRefresh() no seu SDK.

requestBannersRefresh() faz a mesclagem com o cache de Banner existente. Somente os IDs de posicionamento que você informar são adicionados, atualizados ou removidos:

  • Se o servidor retornar um Banner para um posicionamento solicitado, o Banner em cache para aquele posicionamento é substituído.
  • Se o servidor não retornar nenhum Banner para um posicionamento solicitado, aquele posicionamento é removido do cache.
  • Banners em cache para posicionamentos que você não solicitou permanecem no cache até a expiração.

Para saber quantos posicionamentos você pode solicitar por atualização, consulte Sobre solicitações de posicionamento. Você pode atualizar conjuntos diferentes de posicionamentos ao longo do tempo (por exemplo, posicionamentos na tela atual) e manter Banners de outros posicionamentos no cache.

O comportamento de atualização de Banner tem dois caminhos:

  1. Atualização explícita: Você pode chamar o método de atualização a qualquer momento durante uma sessão ativa.
  2. Atualização automática em nova sessão: Depois que você fizer pelo menos uma solicitação de atualização explícita, o SDK pode re-solicitar os IDs de posicionamento mais recentes quando uma nova sessão da Braze iniciar (por exemplo, após changeUser() ou após um tempo limite de sessão).

O papel da inscrição em eventos de Banner varia por plataforma:

  • iOS e Android: subscribeToBannersEvents() no Android (ou subscribeToEvents() no Swift) registra um manipulador de eventos. A atualização automática no início de sessão não depende de a inscrição estar ativa.
  • Web: A atualização automática no início de sessão está vinculada a subscribeToBannersEvents() (ou a função descontinuada subscribeToBannersUpdates()) estar registrada. Sem uma inscrição ativa, o SDK não repete automaticamente a atualização em uma nova sessão.

Em todos os casos, você deve fazer pelo menos uma solicitação de atualização explícita por ciclo de vida do app para que o SDK saiba quais IDs de posicionamento manter atualizados. Banners não são buscados automaticamente no primeiro lançamento sem essa chamada inicial, e os IDs de posicionamento rastreados são redefinidos após a reinicialização do app.

Atualizações automáticas no início de sessão não consomem um token de limite de frequência.

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.

Etapa 3: Escutar atualizações

Use subscribeToBannersEvents para escutar eventos de Banner e depois chame requestBannersRefresh para buscar posicionamentos. O SDK chama seu manipulador com um objeto de evento. Use event.type em um switch para tratar cada tipo de evento. Para saber mais sobre os valores dos eventos, consulte Inscrições em eventos.

Se você está usando JavaScript puro com o SDK Web da Braze, registre seu manipulador antes de chamar 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);

Se você está usando React com o SDK Web da Braze, configure subscribeToBannersEvents dentro de um hook useEffect e chame requestBannersRefresh após registrar seu listener.

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 quando cada evento é disparado e o que significa cada motivo de atualização, estado de nova tentativa, ação de análise de dados e motivo de erro, consulte Inscrições em eventos.

event.cacheSnapshot.banners é um objeto que mapeia cada ID de posicionamento para seu Banner. Ele pode incluir posicionamentos de atualizações anteriores, não apenas os IDs de posicionamento da sua chamada requestBannersRefresh mais recente. Se você se interessa apenas por determinados posicionamentos, leia esses IDs de posicionamento do snapshot e ignore o restante.

Use subscribeToBannersEvents no Web SDK 7.0.0 e versões posteriores. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 7.0.0. O padrão anterior entrega apenas os Banners atuais, então não é possível saber por que os Banners mudaram ou quando uma atualização falhou.

// - 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)

Use subscribeToEvents(_:) no Swift SDK 19.0.0 e versões posteriores. subscribeToUpdates(_:) é o padrão anterior, descontinuado a partir da versão 19.0.0.

Para saber quando cada evento é disparado e o que significa cada motivo de atualização, estado de nova tentativa, ação de análise de dados e motivo de erro, consulte Inscrições em eventos.

ArrayList<String> placementIds = new ArrayList<>();
placementIds.add("global_banner");
placementIds.add("navigation_square_banner");

// - Available in version 44.0.0+
Braze.getInstance(context).subscribeToBannersEvents(event -> {
  if (event instanceof BannersEvent.CacheReplay) {
    logBanners(((BannersEvent.CacheReplay) event).getCacheSnapshot());
  } else if (event instanceof BannersEvent.CacheLoad) {
    logBanners(((BannersEvent.CacheLoad) event).getCacheSnapshot());
  } else if (event instanceof BannersEvent.DataUpdated) {
    logBanners(((BannersEvent.DataUpdated) event).getCacheSnapshot());
  }
});
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds);

Braze.getInstance(context).subscribeToBannersUpdates(event -> {
  for (Banner banner : event.getBanners()) {
    Log.d(TAG, "Received banner: " + banner.getPlacementId());
  }
});
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds);

private void logBanners(BannersCacheSnapshot cacheSnapshot) {
  for (Banner banner : cacheSnapshot.getBanners().values()) {
    Log.d(TAG, "Received banner: " + banner.getPlacementId());
  }
}
val placementIds = listOf("global_banner", "navigation_square_banner")

// - Available in version 44.0.0+
Braze.getInstance(context).subscribeToBannersEvents { event ->
  when (event) {
    is BannersEvent.CacheReplay -> logBanners(event.cacheSnapshot)
    is BannersEvent.CacheLoad -> logBanners(event.cacheSnapshot)
    is BannersEvent.DataUpdated -> logBanners(event.cacheSnapshot)
    else -> {}
  }
}
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds)

Braze.getInstance(context).subscribeToBannersUpdates { event ->
  event.banners.forEach { banner ->
    Log.d(TAG, "Received banner: ${banner.placementId}")
  }
}
// Always refresh after your subscriber is registered
Braze.getInstance(context).requestBannersRefresh(placementIds)

private fun logBanners(cacheSnapshot: BannersCacheSnapshot) {
  cacheSnapshot.banners.values.forEach { banner ->
    Log.d(TAG, "Received banner: ${banner.placementId}")
  }
}

Os eventos chegam em uma thread de segundo plano. Mude para a thread principal antes de atualizar as views.

Use subscribeToBannersEvents no Android SDK 44.0.0 e versões posteriores. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 44.0.0.

Para saber quando cada evento é disparado e o que significa cada motivo de atualização, estado de nova tentativa, ação de análise de dados e motivo de erro, consulte Inscrições em 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.

Etapa 4: Inserir usando o ID de posicionamento

Crie um elemento container para o Banner. Defina sua largura e altura.

<div id="global-banner-container" style="width: 100%; height: 450px;"></div>

Se você está usando JavaScript puro com o SDK Web da Braze, chame o método insertBanner para substituir o HTML interno do elemento container.

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"]);

Use subscribeToBannersEvents no Web SDK 7.0.0 e versões posteriores. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 7.0.0.

Se você está usando React com o SDK Web da Braze, chame o método insertBanner com um ref para substituir o HTML interno do elemento container.

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>
}

Após uma atualização, o SDK atualiza uma BannerUIView ou BannerView somente quando o conteúdo em cache daquele posicionamento muda (adicionado, removido ou atualizado). Banners exibidos sem alteração permanecem como estão. Chamar changeUser() atualiza todas as views 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.
      }
    }
  )
}

Após uma atualização, o SDK atualiza uma BannerView somente quando o conteúdo em cache daquele posicionamento muda (adicionado, removido ou atualizado). Banners exibidos sem alteração permanecem como estão. Chamar changeUser() ainda atualiza todas as BannerView registradas.

Para obter o Banner no código Java, use:

Banner globalBanner = Braze.getInstance(context).getBanner("global_banner");

Você pode criar Banners no layout de views do Android incluindo 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" />

Se você está usando Android Views, use 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 o Jetpack Compose, adicione o artefato com.braze:android-sdk-jetpack-compose ao módulo do seu app. Use a mesma versão das outras dependências do SDK Android da Braze. Esse módulo é separado do android-sdk-ui e inclui o composable Banner no pacote com.braze.jetpackcompose.banners.

import com.braze.jetpackcompose.banners.Banner

@Composable
fun myBannerSlot() {
    Banner(placementId = "global_banner")
}

Opcionalmente, passe heightCallback para receber a altura renderizada em dp quando o tamanho do banner mudar. Para referência, consulte a KDoc do Banner.

Se você não adicionar o módulo Jetpack Compose, encapsule BannerView em 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 obter o Banner no Kotlin, use:

val banner = Braze.getInstance(context).getBanner("global_banner")

Se você está usando a Nova Arquitetura do React Native, é necessário registrar o BrazeBannerView como um componente Fabric no seu 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 a integração mais simples, adicione o seguinte snippet JavaScript XML (JSX) na hierarquia de views, informando apenas o ID de posicionamento.

<Braze.BrazeBannerView
  placementId='global_banner'
/>

Para obter o modelo de dados do Banner no React Native, ou para verificar a presença daquele posicionamento no cache do usuário, use:

const banner = await Braze.getBanner("global_banner");
This feature is not currently supported on Unity.
This feature is not currently supported on Cordova.

Para a integração mais simples, adicione o seguinte widget na hierarquia de views, informando apenas o ID de posicionamento.

BrazeBannerView(
  placementId: "global_banner",
),
To get the Banner's data model in Flutter, use:

Você pode usar o método getBanner para verificar a presença daquele posicionamento no cache do usuário.

braze.getBanner("global_banner").then((banner) {
  if (banner == null) {
    // Handle null cases.
  } else {
    print(banner.toString());
  }
});
This feature is not currently supported on Roku.

Etapa 5: Enviar um Banner de teste (opcional)

Antes de lançar uma Campaign de Banner, você pode enviar um Banner de teste para verificar sua integração. Banners de teste são armazenados em um cache em memória separado e não persistem entre reinicializações do app. Nenhuma configuração extra é necessária, mas seu dispositivo de teste precisa ser capaz de receber notificações por push em primeiro plano para exibir o teste.

Registrar impressões

A Braze registra impressões automaticamente para Banners que estão visíveis quando você usa métodos do SDK para inserir um Banner — então não é necessário rastrear impressões manualmente.

Registro de cliques

O método usado para registrar cliques em Banners depende de como o seu Banner é renderizado e de onde o seu manipulador de cliques está localizado.

Conteúdo padrão do Banner (automático)

Se você está usando os métodos padrão e prontos do SDK para inserir Banners, e o seu Banner utiliza componentes padrão do editor (imagens, botões, texto), os cliques são rastreados automaticamente. O SDK anexa ouvintes de clique a esses elementos, e nenhum código adicional é necessário.

Blocos de código personalizado

Se o seu Banner usa o bloco de editor Custom Code no dashboard da Braze, você deve usar brazeBridge.logClick() para registrar cliques de dentro desse HTML personalizado. Isso se aplica mesmo quando você usa métodos do SDK para renderizar o Banner, porque o SDK não consegue anexar ouvintes automaticamente a elementos dentro do seu código personalizado.

<button onclick="brazeBridge.logClick()">
  Click me
</button>

Para a referência completa, consulte Código personalizado e ponte JavaScript para Banners. O brazeBridge fornece uma camada de comunicação entre o HTML interno do Banner e o SDK da Braze pai.

Implementações de UI personalizada (headless)

Se você está construindo uma UI totalmente personalizada usando as propriedades personalizadas do Banner em vez de renderizar o HTML do Banner, é necessário registrar manualmente os cliques e as impressões a partir do código da sua aplicação. Como o SDK não está renderizando o Banner, ele não tem como rastrear automaticamente as interações com os elementos da sua UI personalizada.

Para assinaturas de métodos e detalhes completos, consulte a documentação de referência do SDK da Braze.

Registro de impressões

Chame o método de impressão de Banner da plataforma quando a sua UI personalizada considerar o Banner como “visualizado”. Construa uma lógica robusta para definir o que conta como uma impressão, evitando eventos duplicados — por exemplo, registre apenas quando o Banner entrar na viewport (ou equivalente) e não registre novamente quando o mesmo Banner voltar à visualização ao rolar a página ou quando o componente for re-renderizado sem um novo evento de visualização.

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]);
}

Referência do SDK Web

// 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");

Referência do SDK Android

// 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()
}

Referência do SDK Swift

// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
Braze.logBannerImpression("placement_id_homepage_top");

Consulte o repositório do SDK React Native para as assinaturas de métodos mais recentes.

// Log impression when your custom UI considers the banner viewed (for example, once when it enters viewport)
braze.logBannerImpression("placement_id_homepage_top");

Referência do SDK Flutter

Registro de cliques

Chame o método de clique de Banner da plataforma quando o usuário tocar no seu Banner personalizado (ou em um botão específico). Passe o buttonId opcional quando o clique for em um botão específico, para que a análise de dados possa atribuir o clique corretamente.

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

// Log click
braze.logBannerClick("placement_id_homepage_top", buttonId);  // buttonID is optional

Referência do SDK Web

// 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

Referência do SDK Android

// 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
}

Referência do SDK Swift

// Log click
Braze.logBannerClick("placement_id_homepage_top", buttonId);  // buttonID is optional

Consulte o repositório do SDK React Native para as assinaturas de métodos mais recentes.

// Log click
braze.logBannerClicked("placement_id_homepage_top", buttonId);  // buttonID parameter can be null

Referência do SDK Flutter

Registrar dispensas

As dispensas de banner removem programaticamente um banner de um posicionamento quando um usuário o dispensa ativamente. Quando dispensado, o banner é suprimido para aquele usuário. Na próxima vez que a lista de posicionamentos for atualizada, um novo banner será retornado se o usuário for elegível para um.

Pré-requisitos

Estas são as versões mínimas do SDK necessárias para registrar dispensas de banner:

Integrações

Integrações de banner padrão (editor de arrastar e soltar)

Se o seu banner usa o editor de arrastar e soltar e inclui um componente de botão de dispensa, nenhum código adicional é necessário. Quando um usuário clica no botão de dispensa, a mensagem é ocultada, aciona uma dispensa e registra um evento de dispensa para análise de dados.

Blocos de código personalizado

Se o seu banner usa o bloco do editor de Custom Code, você pode acionar uma dispensa diretamente de dentro do HTML do banner usando brazeBridge.closeMessage().

<button onclick="brazeBridge.closeMessage()">
  Dismiss
</button>

Dispensar um banner programaticamente

Se você está usando o BrazeBannerView padrão com o botão de dispensa criado no editor de arrastar e soltar, nenhum código adicional é necessário; a dispensa é tratada automaticamente.

Para integrações de UI personalizadas, você pode chamar o método de dispensa diretamente na sua instância da Braze para dispensar programaticamente um banner e registrar um evento de dispensa. O método de dispensa pode ser chamado várias vezes com segurança — o SDK ignora chamadas duplicadas para o mesmo banner.

Estas são as versões mínimas do SDK necessárias para dispensar um banner programaticamente:

Passe o objeto Banner para braze.dismissBanner(). Você pode obter o objeto Banner a partir de braze.getAllBanners() ou do objeto cacheSnapshot.banners de um 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() remove o banner do cache e publica BannersEvent.DataUpdated com ChannelUpdateReason.CLIENT_ACTION para que UIs personalizadas possam renderizar novamente. Widgets BannerView são ocultados quando recebem BannerDismissedEvent. BannersEvent.DismissEvent é o ciclo de vida de análise de dados para essa dispensa, não um sinal para ocultar a visualização.

Use dismiss() no contexto do banner quando disponível. Este método é idempotente e dispara o retorno de chamada onDismiss automaticamente. Se o contexto não estiver disponível, chame dismiss(using:) diretamente no banner. Ambos os métodos devem ser chamados a partir da thread principal.

// Preferred: dismiss via context.
banner.context?.dismiss()

// Fallback: if context is unavailable.
banner.dismiss(using: braze)

Em Objective-C, estes estão disponíveis como [banner.context dismiss] e [banner dismissUsing:braze].

Braze.dismissBanner("your-placement-id");
braze.dismissBanner("your-placement-id");

Registrar análise de dados personalizada na dispensa de banner

Para executar lógica personalizada quando um banner é dispensado — como registrar análise de dados — use o retorno de chamada de dispensa do seu SDK. O retorno de chamada recebe um objeto de evento com o placementId, stableKey e trackingId do banner.

Use Banner.subscribeToDismissedEvent() para executar lógica personalizada quando um banner específico é dispensado. Inscreva-se no evento antes de exibir o banner.

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"]);

Use subscribeToBannersEvents no Web SDK 7.0.0 e posterior. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 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);
  };
}, []);

Use subscribeToBannersEvents no Web SDK 7.0.0 e posterior. subscribeToBannersUpdates é o padrão anterior, descontinuado a partir da versão 7.0.0.

Defina a propriedade opcional onDismissCallback em 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
}

Defina a prop onDismiss em Braze.BrazeBannerView para executar lógica personalizada quando um banner é dispensado.

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
  }}
/>

Defina o parâmetro onDismiss em BrazeBannerView para executar lógica personalizada quando um banner é dispensado.

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
  },
)

Limite de armazenamento de dispensas pendentes

Os eventos de dispensa são armazenados localmente como entradas pendentes até que possam ser sincronizados com o servidor da Braze na próxima chamada de requestBannersRefresh.

Dimensões e dimensionamento

Veja o que você precisa saber sobre as dimensões e o dimensionamento de Banners:

  • Embora o criador permita pré-visualizar Banners em diferentes dimensões, essa informação não é salva nem enviada ao SDK.
  • O HTML ocupará toda a largura do contêiner em que for renderizado.
  • Recomendamos criar um elemento de dimensão fixa e testar essas dimensões no criador.

Propriedades personalizadas

Você pode usar propriedades personalizadas da sua campanha de Banner para recuperar dados chave-valor através do SDK e modificar o comportamento ou a aparência do seu app. Por exemplo, você poderia:

  • Enviar metadados para análise de dados de terceiros ou integrações.
  • Usar metadados como um timestamp ou objeto JSON para disparar lógica condicional.
  • Controlar o comportamento de um Banner com base em metadados incluídos, como ratio ou format.

Pré-requisitos

Você precisará adicionar propriedades personalizadas à sua campanha de Banner. Além disso, estas são as versões mínimas do SDK necessárias para acessar propriedades personalizadas:

Acessar propriedades personalizadas

Para acessar as propriedades personalizadas de um banner, use um dos seguintes métodos com base no tipo da propriedade definido no dashboard. Se a chave não corresponder a uma propriedade desse tipo ou não existir, o método retorna 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
});
New Stuff!