Skip to content

Custom HTML in-app messages

While our standard in-app messages can be customized in a variety of ways, you can gain even greater control over the look and feel of your campaigns using messages designed and built using HTML, CSS, and JavaScript. With some simple composition, you can unlock custom functionality and branding to match any of your needs.

HTML in-app messages allow for greater control over the look and feel of a message, including the following:

  • Custom fonts and styles
  • Videos
  • Multiple images
  • On-click behaviors
  • Interactive components
  • Custom animations

Custom HTML messages can use the JavaScript Bridge methods to log events, set custom attributes, close the message, and more! Check out our GitHub repository that contains detailed instructions on how to use and customize HTML in-app messages for your needs, and for a set of HTML5 in-app messages templates to help you get started.

JavaScript bridge

HTML in-app messages for Web, Android, iOS, and Swift SDKs support a JavaScript “bridge” to interface with Braze SDK, allowing you to trigger custom Braze actions when users click on elements with links or otherwise engage with your content. These methods exist with the global brazeBridge or appboyBridge variable.

For example, to log a custom attribute and custom event, then close the message, you could use the following JavaScript within your HTML in-app message:

<button id="button">Set Favorite Color</button>
// Wait for the `brazeBridge` ready event, "ab.BridgeReady"
window.addEventListener("ab.BridgeReady", function(){
  // Event handler when the button is clicked
  document.querySelector("#button").onclick = function(){
    // Track Button 1 clicks for analytics
    // Note: This requires Android SDK v8.0.0, Web SDK v2.5.0, Swift SDK v5.4.0, and iOS SDK v3.23.0
    // Set the user's custom attribute
    brazeBridge.getUser().setCustomUserAttribute("favorite color", "blue");
    // Track a custom event
    brazeBridge.logCustomEvent("completed survey");
    // Send the enqueued data to Braze
    // Close this in-app message
}, false);

JavaScript Bridge methods

The following JavaScript methods are supported within Braze HTML in-app messages:

Method Name Description
brazeBridge.closeMessage() Close the current in-app message.
window.addEventListener("ab.BridgeReady", function(){...}, false) Callback method for when the brazeBridge has finished loading. All JavaScript code should be run within this callback function.
brazeBridge.requestImmediateDataFlush() Flush queued data to the Braze servers. JS Docs
brazeBridge.logClick(button_id_string) Log a button click for a given button ID. When button_id_string is left blank, a body-click will be logged instead. The button_id_string can be passed out as the button_id in in-app message click events via Currents.

This method was introduced in Android SDK v8.0.0, Web SDK v2.5.0, and iOS SDK v3.23.0

The button_id_string only accepts alphanumeric characters, spaces, dashes, and underscores. Adding a character with an accent (for example, ö,â,ê) breaks the button click tracking, resulting in the button string not appearing in the campaign analytics section and clicks not being accounted for.
brazeBridge.logCustomEvent(eventName,eventProperties) Log a custom event. JS Docs
brazeBridge.logPurchase(productId, price, currencyCode, quantity, purchaseProperties) Log a purchase. JS Docs
brazeBridge.display.showFeed() Show the News Feed. JS Docs
brazeBridge.getUser().addAlias(alias, label) Adds an alias to a user. Introduced in Web SDK v2.7.0, Android v8.1.0, and iOS SDK v3.26.0 JS Docs
brazeBridge.getUser().addToCustomAttributeArray(key, value) Adds to a custom attribute array. JS Docs
brazeBridge.getUser().addToSubscriptionGroup(subscriptionGroupId) Adds a user to an email or SMS subscription group. JS Docs.

This method was introduced in Android SDK v15.0.0, Web SDK v3.4.0, and iOS SDK v4.3.3.
brazeBridge.getUser().removeFromSubscriptionGroup(subscriptionGroupId) Removes a user from an email or SMS subscription group. JS Docs.

This method was introduced in Android SDK v15.0.0, Web SDK v3.4.0, and iOS SDK v4.3.3.
brazeBridge.getUser().setFirstName(firstName) Set a user’s first name. JS Docs
brazeBridge.getUser().setLastName(lastName) Set a user’s last name. JS Docs
brazeBridge.getUser().setEmail(email) Set a user’s email address. JS Docs
brazeBridge.getUser().setGender(gender) Set a user’s gender. JS Docs
brazeBridge.getUser().setDateOfBirth(year, month, day) Set a user’s date of birth. JS Docs
brazeBridge.getUser().setCountry(country) Set a user’s country. JS Docs
brazeBridge.getUser().setHomeCity(city) Set a user’s city. JS Docs
brazeBridge.getUser().setEmailNotificationSubscriptionType(notificationSubscriptionType) Set email notification subscription status. JS Docs
brazeBridge.getUser().setPushNotificationSubscriptionType(notificationSubscriptionType) Set push notification subscription status. JS Docs
brazeBridge.getUser().setPhoneNumber(phoneNumber) Set a user’s phone number. JS Docs
brazeBridge.getUser().setCustomUserAttribute(key, value) Set a custom user attribute. JS Docs
brazeBridge.getUser().removeFromCustomAttributeArray(key, value) Remove a custom user attribute. JS Docs
brazeBridge.getUser().incrementCustomUserAttribute(key, incrementValue) Increment a custom user attribute. JS Docs
brazeBridge.getUser().setLanguage(language) Set a user’s language. Introduced in Android SDK v5.0.0 and Web SDK v2.6.0. JS Docs
brazeBridge.getUser().setCustomLocationAttribute(key, latitude, longitude) Set a custom location attribute. Introduced in Android SDK v5.0.0. JS Docs
brazeBridge.web.registerAppboyPushMessages(successCallback, deniedCallback) Register for web push (web only). This method is a no-op when called in a non-web environment. JS Docs
brazeBridge.requestPushPermission(successCallback, deniedCallback) Register for push across Web, iOS, and Android. Note: the method’s callbacks are only supported on web. This method was introduced as of Web SDK v4.0.0, Android SDK v21.0.0, and Swift SDK v5.4.0. JS Docs
brazeBridge.changeUser(id, sdkAuthSignature?) Identify user with a unique ID. JS Docs

This method was introduced in Web SDK v4.3.0.

In addition to custom JavaScript, Braze SDKs can also send analytics data with these convenient URL shortcuts. Note that these query parameters and URL schemes are all case sensitive.

Button click tracking

To log button clicks for in-app message analytics, you can add abButtonId as a query parameter to any deep link, redirect URL, or anchor element <a>. Use ?abButtonId=0 to log a “Button 1” click, and ?abButtonId=1 to log a “Button 2” click.

As with other URL parameters, the first parameter should begin with a question mark ?, while subsequent parameters should be separated by an ampersand &.


  • - Button 1 click
  • - Button 2 click
  • - Button 1 click with other existing URL parameters
  • myApp://deep-link?page=home&abButtonId=1 - Mobile deeplink with Button 2 click
  • <a href=""> - Anchor element <a> with Button 2 click

To open links outside your app in a new window, set ?abExternalOpen=true. The message will be dismissed before opening the link.

For deep linking, Braze will open your URL regardless of the value of abExternalOpen.

To have Braze handle your HTTP or HTTPS link as a deep link, set ?abDeepLink=true.

When this query string parameter is absent or set to false, Braze will try to open the web link in an internal web browser inside the host app.

News Feed (mobile only)

For mobile apps, you can open the News Feed by setting a link’s URL to braze://feed.

For example, <a href="braze://feed">View Feed</a>.

Close in-app message

To close an in-app message, you can use the brazeBridge.closeMessage() javascript method.

For example, <a onclick="brazeBridge.closeMessage()" href="#">Close</a> will close the in-app message.

HTML upload with preview

When crafting custom HTML in-app messages, you can preview your interactive content directly in Braze.

The message preview panel of the editor shows a realistic preview that renders the JavaScript included in your message. You can preview and interact with your custom messages from the preview panel by clicking through pagination, submitting forms or surveys, watching JavaScript animations, and more!

Interacting with the HTML preview by swiping through pages.

SDK requirements

To use the HTML preview for in-app messages, you must upgrade to the following minimum Braze SDK versions:

Creating a campaign

When creating a Custom Code in-app message, choose HTML Upload with Preview as the custom type. If you haven’t previously created custom code in-app messages (live or drafts), this option is automatically applied and you won’t need to make a selection.

Creating an in-app message that sends to both Mobile and Web browsers where "Message Type" is Custom Code and "Custom Type" is HTML Upload with Preview.

Keep in mind that your mobile app users need to upgrade to the supported SDK versions to receive this message. We recommend that you nudge users to upgrade their mobile apps before launching campaigns that depend on newer Braze SDK versions.

Asset files

When creating custom code in-app messages with HTML upload, you can upload campaign assets to the media library to reference in your message.

The following file types are supported for upload:

File Type File Extension
Font Files .ttf, .woff, .otf, .woff2
SVG Images .svg
JavaScript Files .js
CSS Files .css

Braze recommends uploading assets to the media library for two reasons:

  1. Assets added to a campaign via the media library allow your messages to be displayed even while the user is offline, or has a poor internet connection.
  2. Assets uploaded to Braze can be reused across campaigns.
Adding asset files

You can add new or existing assets to your campaign.

To add new assets to your campaign, use the drag-and-drop section to upload a file. Assets added in this section will also be automatically added to the media library. To add assets that you’ve already uploaded to the media library, select Add from Media Library.

After your assets are added, they will appear in the Assets for this campaign section.

If an asset’s filename matches that of a local HTML asset it will be replaced automatically (for example, cat.png is uploaded and <img src="cat.png" /> exists).

Otherwise, hover over an asset from the list and select Copy to copy the file’s URL to your clipboard. Then paste the copied asset URL into your HTML as you normally would when referencing a remote asset.

HTML editor

Changes you make in the HTML automatically render in the preview panel as you type. Any brazeBridge JavaScript methods you use in your HTML won’t update user profiles while previewing in the dashboard.

You can configure Editor Settings to toggle wrap text, change the font size, or choose a color theme. The code editor includes different color themes for syntax highlighting, which helps you spot potential code errors directly in the message composer and better organize your code (using spaces or tabs—whichever side of that argument you’re on).

Syntax highlighting options in the "Editor Settings" dropdown when composing an HTML in-app message.

Button tracking

You can track performance within your custom code in-app message using the brazeBridge.logClick(button_id) JavaScript method. This allows you to programmatically track “Button 1”, “Button 2”, and “Body Clicks” using brazeBridge.logClick("0"), brazeBridge.logClick("1"), or brazeBridge.logClick(), respectively.

Clicks Method
Button 1 brazeBridge.logClick("0")
Button 2 brazeBridge.logClick("1")
Body click brazeBridge.logClick()
Custom button tracking brazeBridge.logClick("your custom name here")

You can track multiple button click events per impression. For example, to close a message and log a Button 2 click, you can use the following:

<a href="#" onclick="brazeBridge.logClick('1');brazeBridge.closeMessage()"></a>

You can also track new custom button names—up to 100 unique names per campaign. For example, brazeBridge.logClick("blue button") or brazeBridge.logClick("viewed carousel page 3").


  • You can have up to 100 unique button IDs per campaign.
  • Button IDs can have up to 255 characters each.
  • Button IDs can only include letters, numbers, spaces, dashes, and underscores.

Backward incompatible changes

  1. The most notable incompatible change with this new message type is the SDK requirements. Users whose app SDK does not meet the minimum SDK version requirements will not be shown the message.

  2. The braze://close deeplink, which was previously supported on mobile apps, has been removed in favor of the JavaScript brazeBridge.closeMessage(). This allows for cross-platform HTML messages, since the web does not support deeplinks.

  3. Automatic click tracking, which used ?abButtonId=0 for button IDs, and “body click” tracking on close buttons have been removed. The following code examples show how to change your HTML to use our new click tracking JavaScript methods:

    Before After
    <a href="braze://close">Close Button</a> <a href="#" onclick="brazeBridge.logClick();brazeBridge.closeMessage()">Close Button</a>
    <a href="braze://close?abButtonId=0">Close Button</a> <a href="#" onclick="brazeBridge.logClick('0');brazeBridge.closeMessage()">Close Button</a>
    <a href="app://deeplink?abButtonId=0">Track button 1</a> <a href="app://deeplink" onclick="brazeBridge.logClick('0')">Track button 1</a>
    location.href = "braze://close?abButtonId=1"
    window.addEventListener("ab.BridgeReady", function(){
New Stuff!