Esta página foi traduzida automaticamente e pode conter imprecisões. Para relatar um erro de tradução, use o componente de feedback na parte inferior do sumário, à direita da página.
Migrar de Content Cards para Banners
Este guia ajuda você a migrar de Content Cards para Banners para casos de uso de envio de mensagens em estilo banner. Banners são ideais para mensagens inline e persistentes no app e na web que aparecem em posicionamentos específicos na sua aplicação.
Por que migrar para Banners?
- Se sua equipe de engenharia está construindo ou mantendo Content Cards personalizados, migrar para Banners pode reduzir esse investimento contínuo. Banners permitem que profissionais de marketing controlem a interface diretamente, liberando desenvolvedores para outros trabalhos.
- Se você está lançando novas mensagens na página inicial, fluxos de integração ou anúncios persistentes, comece com Banners em vez de construir com Content Cards. Você pode se beneficiar de personalização em tempo real, sem expiração de 30 dias, sem limite de tamanho e priorização nativa desde o primeiro dia.
- Se você está contornando o limite de expiração de 30 dias, gerenciando lógica complexa de reelegibilidade ou frustrado com personalização desatualizada, Banners resolve esses problemas nativamente.
Banners oferecem diversas vantagens em relação a Content Cards para mensagens no estilo banner:
Produção acelerada
- Menos suporte contínuo de engenharia necessário: Profissionais de marketing podem criar mensagens personalizadas usando o editor de arrastar e soltar e HTML personalizado sem precisar de assistência de desenvolvedores para customização
- Opções flexíveis de personalização: Projete diretamente no editor, use HTML ou aproveite modelos de dados existentes com propriedades personalizadas
Melhor experiência do usuário
- Atualizações de conteúdo dinâmico: Banners atualizam a lógica Liquid e a elegibilidade a cada atualização, garantindo que os usuários sempre vejam o conteúdo mais relevante
- Suporte nativo a posicionamento: As mensagens aparecem em contextos específicos em vez de um feed, proporcionando melhor relevância contextual
- Priorização nativa: Controle sobre a ordem de exibição sem lógica personalizada, facilitando o gerenciamento da hierarquia de mensagens
Persistência
- Sem limite de expiração: Campaigns de Banner não têm um limite de expiração de 30 dias como Content Cards, permitindo verdadeira persistência das mensagens
Quando migrar
Considere migrar para Banners se você está usando Content Cards para:
- Destaques na página inicial, promoções em páginas de produtos, ofertas no checkout
- Anúncios persistentes de navegação ou mensagens na barra lateral
- Mensagens sempre ativas com duração superior a 30 dias
- Mensagens em que você deseja personalização e elegibilidade em tempo real
Quando manter Content Cards
Continue usando Content Cards se você precisar de:
- Experiências de feed: Qualquer caso de uso que envolva várias mensagens roláveis ou uma “Caixa de entrada” baseada em cartões.
- Recursos específicos: Mensagens que exigem códigos promocionais, já que os Banners não oferecem suporte nativo a eles. Os Banners oferecem suporte a Connected Content em acesso antecipado.
- Entrega baseada em ação: Casos de uso que exigem estritamente entrega disparada por API ou entrega baseada em ação. Embora os Banners não ofereçam suporte a entrega disparada por API ou baseada em ação, a avaliação de elegibilidade em tempo real significa que os usuários se qualificam ou desqualificam instantaneamente com base na associação ao Segment a cada atualização.
Guia de migração
Pré-requisitos
Antes de migrar, verifique se o SDK da Braze atende aos requisitos mínimos de versão:
Dispensas e reelegibilidade exigem as seguintes versões mínimas do SDK:
Inscrever-se para atualizações
Abordagem com Content Cards
1
2
3
4
5
6
7
8
| import * as braze from "@braze/web-sdk";
braze.subscribeToContentCardsUpdates((cards) => {
// Handle array of cards
cards.forEach(card => {
console.log("Card:", card.id);
});
});
|
1
2
3
4
5
6
| Braze.getInstance(context).subscribeToContentCardsUpdates { cards ->
// Handle array of cards
cards.forEach { card ->
Log.d(TAG, "Card: ${card.id}")
}
}
|
1
2
3
4
5
6
| braze.contentCards.subscribeToUpdates { cards in
// Handle array of cards
for card in cards {
print("Card: \(card.id)")
}
}
|
1
2
3
4
5
6
7
| Braze.addListener(Braze.Events.CONTENT_CARDS_UPDATED, (update) => {
const cards = update.cards;
// Handle array of cards
cards.forEach(card => {
console.log("Card:", card.id);
});
});
|
1
2
3
4
5
6
| StreamSubscription contentCardsStreamSubscription = braze.subscribeToContentCards((List<BrazeContentCard> contentCards) {
// Handle array of cards
for (final card in contentCards) {
print("Card: ${card.id}");
}
});
|
Abordagem com Banners
1
2
3
4
5
6
7
8
9
| import * as braze from "@braze/web-sdk";
braze.subscribeToBannersUpdates((banners) => {
// Get banner for specific placement
const banner = braze.getBanner("sample_placement_id");
if (banner) {
console.log("Banner received for placement:", banner.placementId);
}
});
|
1
2
3
4
5
6
7
| Braze.getInstance(context).subscribeToBannersUpdates { update ->
// Get banner for specific placement
val banner = Braze.getInstance(context).getBanner("sample_placement_id")
if (banner != null) {
Log.d(TAG, "Banner received for placement: ${banner.placementId}")
}
}
|
1
2
3
4
5
6
7
8
| braze.banners.subscribeToUpdates { banners in
// Get banner for specific placement
braze.banners.getBanner(for: "sample_placement_id") { banner in
guard let banner = banner else { return }
print("Banner received for placement: \(banner.placementId)")
}
}
|
1
2
3
4
5
6
7
8
9
| Braze.addListener(Braze.Events.BANNER_CARDS_UPDATED, (data) => {
const banners = data.banners;
// Get banner for specific placement
Braze.getBanner("sample_placement_id").then(banner => {
if (banner) {
console.log("Banner received for placement:", banner.placementId);
}
});
});
|
1
2
3
4
5
6
7
8
| StreamSubscription bannerStreamSubscription = braze.subscribeToBanners((List<BrazeBanner> banners) {
// Get banner for specific placement
braze.getBanner("sample_placement_id").then((banner) {
if (banner != null) {
print("Banner received for placement: ${banner.placementId}");
}
});
});
|
Exibir conteúdo

Nota
Content Cards podem ser renderizados manualmente com lógica de UI personalizada, enquanto Banners só podem ser renderizados com os métodos prontos do SDK.
Abordagem com Content Cards
1
2
3
4
5
6
7
8
9
10
11
| // Show default feed UI
braze.showContentCards(document.getElementById("feed"));
// Or manually render cards
const cards = braze.getCachedContentCards();
cards.forEach(card => {
// Custom rendering logic
if (card instanceof braze.ClassicCard) {
// Render classic card
}
});
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // Using default fragment
val fragment = ContentCardsFragment()
supportFragmentManager.beginTransaction()
.replace(R.id.content_cards_container, fragment)
.commit()
// Or manually render cards
val cards = Braze.getInstance(context).getCachedContentCards()
cards.forEach { card ->
when (card) {
is ClassicCard -> {
// Render classic card
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // Using default view controller
let contentCardsController = BrazeContentCardUI.ViewController(braze: braze)
navigationController?.pushViewController(contentCardsController, animated: true)
// Or manually render cards
let cards = braze.contentCards.cards
for card in cards {
switch card {
case let card as Braze.ContentCard.Classic:
// Render classic card
default:
break
}
}
|
1
2
3
4
5
6
7
8
9
10
| // Launch default feed
Braze.launchContentCards();
// Or manually render cards
const cards = await Braze.getCachedContentCards();
cards.forEach(card => {
if (card.type === 'CLASSIC') {
// Render classic card
}
});
|
1
2
3
4
5
6
7
8
9
10
| // Launch default feed
braze.launchContentCards();
// Or manually render cards
final cards = await braze.getContentCards();
for (final card in cards) {
if (card.type == 'CLASSIC') {
// Render classic card
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| braze.subscribeToBannersUpdates((banners) => {
const banner = braze.getBanner("sample_placement_id");
if (!banner) {
return;
}
const container = document.getElementById("global-banner-container");
braze.insertBanner(banner, container);
if (banner.isControl) {
container.style.display = "none";
}
});
braze.requestBannersRefresh(["sample_placement_id"]);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // Using BannerView in XML
// <com.braze.ui.banners.BannerView
// android:id="@+id/banner_view"
// android:layout_width="match_parent"
// android:layout_height="wrap_content"
// app:placementId="sample_placement_id" />
// Or programmatically
val bannerView = BannerView(context).apply {
placementId = "sample_placement_id"
}
container.addView(bannerView)
Braze.getInstance(context).requestBannersRefresh(listOf("sample_placement_id"))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // Using BannerUIView
let bannerView = BrazeBannerUI.BannerUIView(
placementId: "sample_placement_id",
braze: braze,
processContentUpdates: { result in
switch result {
case .success(let updates):
if let height = updates.height {
// Update height constraint
}
case .failure:
break
}
}
)
view.addSubview(bannerView)
braze.banners.requestBannersRefresh(placementIds: ["sample_placement_id"])
|
1
2
3
4
5
6
7
8
9
10
11
12
| // Using BrazeBannerView component
<Braze.BrazeBannerView
placementId='sample_placement_id'
/>
// Or get banner data
const banner = await Braze.getBanner("sample_placement_id");
if (banner) {
// Render custom banner UI
}
Braze.requestBannersRefresh(["sample_placement_id"]);
|
1
2
3
4
5
6
7
8
9
10
11
12
| // Using BrazeBannerView widget
BrazeBannerView(
placementId: "sample_placement_id",
)
// Or get banner data
final banner = await braze.getBanner("sample_placement_id");
if (banner != null) {
// Render custom banner UI
}
braze.requestBannersRefresh(["sample_placement_id"]);
|
Registrar análise de dados (implementações personalizadas)

Nota
Tanto Content Cards quanto Banners rastreiam análise de dados automaticamente ao usar seus componentes de UI padrão. Os exemplos a seguir são para implementações personalizadas em que você está construindo sua própria UI.
Abordagem com Content Cards
1
2
3
4
5
6
7
| // Manual impression logging required for custom implementations
cards.forEach(card => {
braze.logContentCardImpressions([card]);
});
// Manual click logging required for custom implementations
card.logClick();
|
1
2
3
4
5
6
7
| // Manual impression logging required for custom implementations
cards.forEach { card ->
card.logImpression()
}
// Manual click logging required for custom implementations
card.logClick()
|
1
2
3
4
5
6
7
| // Manual impression logging required for custom implementations
for card in cards {
card.context?.logImpression()
}
// Manual click logging required for custom implementations
card.context?.logClick()
|
1
2
3
4
5
6
7
| // Manual impression logging required for custom implementations
cards.forEach(card => {
Braze.logContentCardImpression(card.id);
});
// Manual click logging required for custom implementations
Braze.logContentCardClicked(card.id);
|
1
2
3
4
5
6
7
| // Manual impression logging required for custom implementations
for (final card in cards) {
braze.logContentCardImpression(card);
}
// Manual click logging required for custom implementations
braze.logContentCardClicked(card);
|

Importante
A análise de dados é rastreada automaticamente ao usar insertBanner(). O registro manual não deve ser usado ao utilizar insertBanner().
1
2
3
4
5
6
7
8
9
| // Analytics are automatically tracked when using insertBanner()
// Manual logging should not be used when using insertBanner()
// For custom implementations, use manual logging methods:
// Log impression
braze.logBannerImpressions([banner]);
// Log click (with optional buttonId)
braze.logBannerClick("sample_placement_id", buttonId);
|

Importante
A análise de dados é rastreada automaticamente ao usar BannerView. O registro manual não deve ser usado ao utilizar BannerView.
1
2
3
4
5
6
7
8
9
| // Analytics are automatically tracked when using BannerView
// Manual logging should not be used for default BannerView
// For custom implementations, use manual logging methods:
// Log impression
Braze.getInstance(context).logBannerImpression("sample_placement_id");
// Log click (with optional buttonId)
Braze.getInstance(context).logBannerClick("sample_placement_id", buttonId);
|

Importante
A análise de dados é rastreada automaticamente ao usar BannerUIView. O registro manual não deve ser usado para o BannerUIView padrão.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // Analytics are automatically tracked when using BannerUIView
// Manual logging should not be used for default BannerUIView
// For custom implementations, use manual logging methods:
// Get banner for specific placement
braze.banners.getBanner(for: "sample_placement_id") { banner in
guard let banner = banner else { return }
// Log impression
banner.context?.logImpression()
// Log click (with optional buttonId)
banner.context?.logClick(buttonId: buttonId)
}
// Control groups are automatically handled by BannerUIView
|

Importante
A análise de dados é rastreada automaticamente ao usar BrazeBannerView. Nenhum registro manual é necessário.
1
2
3
4
5
| // Analytics are automatically tracked when using BrazeBannerView
// No manual logging required
// Note: Manual logging methods for Banners are not yet supported in React Native
// Control groups are automatically handled by BrazeBannerView
|

Importante
A análise de dados é rastreada automaticamente ao usar BrazeBannerView. Nenhum registro manual é necessário.
1
2
3
4
5
| // Analytics are automatically tracked when using BrazeBannerView
// No manual logging required
// Note: Manual logging methods for Banners are not yet supported in Flutter
// Control groups are automatically handled by BrazeBannerView
|
Obter propriedades
Abordagem com Content Cards
1
2
3
| cards.forEach(card => {
console.log("Card id:", card.id, "Extras:", card.extras);
});
|
1
2
3
| cards.forEach { card ->
Log.d(TAG, "Card id: ${card.id} Extras: ${card.extras}")
}
|
1
2
3
| for card in cards {
print("Card id: \(card.id) Extras: \(card.extras)")
}
|
1
2
3
| cards.forEach(card => {
console.log("Card id:", card.id, "Extras:", card.extras);
});
|
1
2
3
| for (final card in cards) {
print("Card id: ${card.id} Extras: ${card.extras}");
}
|
1
2
3
4
5
6
| const banner = braze.getBanner("sample_placement_id");
if (!banner) {
return;
}
console.log("Banner placement:", banner.placementId, "Properties:", banner.properties);
|
1
2
3
4
| val banner = Braze.getInstance(context).getBanner("sample_placement_id")
if (banner != null) {
Log.d(TAG, "Banner placement: ${banner.placementId} Properties: ${banner.properties}")
}
|
1
2
3
4
5
| braze.banners.getBanner(for: "sample_placement_id") { banner in
guard let banner = banner else { return }
print("Banner placement: \(banner.placementId) Properties: \(banner.properties)")
}
|
1
2
3
4
| const banner = await Braze.getBanner("sample_placement_id");
if (banner) {
console.log("Banner placement:", banner.placementId, "Properties:", banner.properties);
}
|
1
2
3
4
| final banner = await braze.getBanner("sample_placement_id");
if (banner != null) {
print("Banner placement: ${banner.placementId} Properties: ${banner.properties}");
}
|
Lidar com grupos de controle
Abordagem com Content Cards
1
2
3
4
5
6
7
| cards.forEach(card => {
if (card.isControl) {
// Logic for control cards ie. don't display but log analytics
} else {
// Logic for cards ie. render card
}
});
|
1
2
3
4
5
6
7
| cards.forEach { card ->
if (card.isControl) {
// Logic for control cards ie. don't display but log analytics
} else {
// Logic for cards ie. render card
}
}
|
1
2
3
4
5
6
7
| for card in cards {
if card.isControl {
// Logic for control cards ie. don't display but log analytics
} else {
// Logic for cards ie. render card
}
}
|
1
2
3
4
5
6
7
| cards.forEach(card => {
if (card.isControl) {
// Logic for control cards ie. don't display but log analytics
} else {
// Logic for cards ie. render card
}
});
|
1
2
3
4
5
6
7
| for (final card in cards) {
if (card.isControl) {
// Logic for control cards ie. don't display but log analytics
} else {
// Logic for cards ie. render card
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| braze.subscribeToBannersUpdates((banners) => {
const banner = braze.getBanner("sample_placement_id");
if (!banner) {
return;
}
const container = document.getElementById("global-banner-container");
// Always call insertBanner to track impression (including control)
braze.insertBanner(banner, container);
// Hide if control group
if (banner.isControl) {
container.style.display = "none";
}
});
|
1
2
3
4
5
| // BannerView automatically handles control groups
// No additional code needed
val bannerView = BannerView(context).apply {
placementId = "sample_placement_id"
}
|
1
2
3
4
5
6
| // BannerUIView automatically handles control groups
// No additional code needed
let bannerView = BrazeBannerUI.BannerUIView(
placementId: "sample_placement_id",
braze: braze
)
|
1
2
3
4
5
| // BrazeBannerView automatically handles control groups
// No additional code needed
<Braze.BrazeBannerView
placementId='sample_placement_id'
/>
|
1
2
3
4
5
| // BrazeBannerView automatically handles control groups
// No additional code needed
BrazeBannerView(
placementId: "sample_placement_id",
)
|
Limitações
Ao migrar de Content Cards para Banners, esteja ciente das seguintes limitações:
Migração de mensagens disparadas
Banners suportam apenas Campaigns de entrega agendada. Para migrar uma mensagem que anteriormente era disparada por API ou baseada em ação, converta-a para direcionamento baseado em Segment:
- Exemplo: Em vez de disparar um cartão “Complete seu perfil” com a API, crie um Segment para usuários que se cadastraram nos últimos 7 dias, mas não completaram seu perfil.
- Elegibilidade em tempo real: Os usuários se qualificam ou desqualificam para o Banner instantaneamente a cada atualização, com base na associação ao Segment.
Diferenças de recursos
| Recurso |
Content Cards |
Banners |
| Estrutura de conteúdo |
|
|
| Múltiplos cartões no feed |
✅ Suportado |
✅ É possível criar múltiplos posicionamentos para obter uma implementação semelhante a carrossel. Apenas um banner é retornado por posicionamento. |
| Múltiplos posicionamentos |
N/A |
✅ Múltiplos posicionamentos suportados |
| Tipos de cartão (Clássico, Com legenda, Somente imagem) |
✅ Múltiplos tipos predefinidos |
✅ Banner único baseado em HTML (mais flexível) |
| Gerenciamento de conteúdo |
|
|
| Editor de arrastar e soltar |
❌ Requer desenvolvedor para personalização |
✅ Profissionais de marketing podem criar/atualizar sem engenharia |
| HTML/CSS personalizado |
❌ Limitado à estrutura do cartão |
✅ Suporte completo a HTML/CSS |
| Pares chave-valor para personalização |
✅ Necessário para personalização avançada |
✅ Pares chave-valor fortemente tipados chamados “propriedades” para personalização avançada |
| Extras de mensagem |
✅ Suportado |
❌ Não suportado atualmente |
| Persistência e expiração |
|
|
| Expiração do cartão |
✅ Suportado (limite de 30 dias) |
✅ Suportado (sem limite de expiração) |
| Persistência real |
❌ Máximo de 30 dias |
✅ Persistência ilimitada |
| Exibição e direcionamento |
|
|
| Interface do feed |
✅ Feed padrão disponível |
❌ Somente baseado em posicionamento |
| Posicionamento específico por contexto |
❌ Baseado em feed |
✅ Suporte nativo a posicionamento |
| Priorização |
❌ Requer lógica personalizada |
✅ Priorização nativa |
| Interação do usuário |
|
|
| Dispensar manualmente |
✅ Suportado |
✅ Suportado |
| Reelegibilidade após dispensar |
❌ Requer filtros personalizados ou lógica de Campaign |
✅ Período de espera padrão |
| Cartões fixados |
✅ Suportado |
N/A |
| Analytics |
|
|
| Analytics automático (interface padrão) |
✅ Suportado |
✅ Suportado |
| Classificação por prioridade |
❌ Não suportado |
✅ Suportado |
| Atualizações de conteúdo |
|
|
| Atualização de templates Liquid |
❌ Uma vez por cartão no envio/lançamento |
✅ Atualiza a cada refresh |
| Atualização de elegibilidade |
❌ Uma vez por cartão no envio/lançamento |
✅ Atualiza a cada sessão |
Limitações do produto
- Até 25 mensagens ativas por posicionamento.
- Até 10 IDs de posicionamento por solicitação de refresh; solicitações além desse limite são truncadas.
Limitações do SDK
- Banners não são suportados atualmente em .NET MAUI (Xamarin), Cordova, Unity, Vega ou plataformas de TV.
- Certifique-se de que você está usando as versões mínimas do SDK listadas nos pré-requisitos.
Artigos relacionados