> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/en/crm-marketing/in-app-message-guide/html-message/in-app-message-html-javascript-bridge.md).

# In-App Message JavaScript Bridge

{% hint style="warning" %}
All methods covered in this document are JavaScript APIs available only in [HTML-based in-app messages](/en/crm-marketing/in-app-message-guide/html-message.md).
{% endhint %}

JavaScript Bridge is a tool for the HTML in-app message and Hackle's SDK to interact with each other.

* When a close button is clicked
* When navigating to a link
* When an action corresponding to a campaign conversion is performed
* When a Hackle feature call is needed within the in-app message

In these situations, you can use JavaScript Bridge to control user behavior tracking, URL navigation, and in-app message display.

## hackleBridgeReady

When `Hackle.bridge` becomes available in the HTML, the `hackleBridgeReady` event is published.\
It is recommended to access `Hackle.bridge` inside the callback of that event listener.

Access to `Hackle.bridge` must always occur after the Ready event has been fired.

#### Example

```html
<button id="hackle-url">
	Go to Hackle
</button>
<script>
  window.addEventListener("hackleBridgeReady", function(){
    document.querySelector("#hackle-url").addEventListener("click", function(e) {
      Hackle.bridge.openUrl("https://hackle.io");
    });
	})
</script>
```

## Opening a URL

Opens the URL in the browser of the device where the in-app message is displayed and closes the in-app message.

* Supports deep links.
* Does not track click events.

```typescript
Hackle.bridge.openUrl(url: string): void
Hackle.bridge.openUrl(url: HackleInAppMessageLink): void

interface HackleInAppMessageLink {
  url: string
  target: "CURRENT" | "NEW_TAB" | "NEW_WINDOW"
  shouldCloseAfterLink: boolean
}
```

<table><thead><tr><th width="205.21484375">target</th><th>Description</th></tr></thead><tbody><tr><td><code>CURRENT</code></td><td>Open in the current page</td></tr><tr><td><code>NEW_TAB</code></td><td>Open in a new tab</td></tr><tr><td><code>NEW_WINDOW</code></td><td>Open in a new window</td></tr></tbody></table>

{% hint style="warning" %}
Apps (Android, iOS, Flutter, React Native) support only `CURRENT`.
{% endhint %}

#### Example

Opens the URL in the current page and closes the in-app message.

```html
<button id="hackle-url">
	Go to Hackle
</button>
<script>
  window.addEventListener("hackleBridgeReady", function(){
    document.querySelector("#hackle-url").addEventListener("click", function(e) {
      Hackle.bridge.openUrl("https://hackle.io");
    });
	})
</script>
```

#### Open in new tab and close in-app message

```html
<button id="hackle-url">
	Go to Hackle
</button>
<script>
  window.addEventListener("hackleBridgeReady", function(){
    document.querySelector("#hackle-url").addEventListener("click", function(e) {
      Hackle.bridge.openUrl({
        url: "https://hackle.io",
        target: "NEW_TAB",
				shouldCloseAfterLink: true
 			});
    });
	})
</script>
```

#### Open in new window and close in-app message

```html
<button id="hackle-url">
	Go to Hackle
</button>
<script>
  window.addEventListener("hackleBridgeReady", function(){
    document.querySelector("#hackle-url").addEventListener("click", function(e) {
      Hackle.bridge.openUrl({
        url: "https://hackle.io",
        target: "NEW_WINDOW",
				shouldCloseAfterLink: true
 			});
    });
	})
</script>
```

## Personalization

In in-app message HTML, you can display personalized messages using user information and event information.

### Querying User Properties

Queries the properties of the user that triggered the message.

```javascript
Hackle.bridge.getUser(): User
```

#### Example

```javascript
const user = Hackle.bridge.getUser();
const props = user?.properties ?? {};
const age = props["age"] ?? -1;

if (age > 20) {
  document.getElementById("new-year-text").textContent 
    = `A special deal exclusively for you, turning ${age} in the new year!`;
}
```

### Querying the Trigger Event

Queries the information of the event that triggered the in-app message.\
It includes the event key, value, and the full list of properties.

```javascript
Hackle.bridge.getTriggerEvent(): HackleEvent | undefined
```

#### Example

```javascript
const event = Hackle.bridge.getTriggerEvent();
const promoDate = event?.properties?.["promo_date"] ?? "11.29";
document.getElementById("period-text").textContent = promoDate + " FRI — Special sale until midnight";
```

### Querying a Trigger Event Property

Queries a single property of the event that triggered the in-app message.

```javascript
Hackle.bridge.getTriggerEventProperty(
    key: String, 
    defaultValue: string | number | boolean | Array<string | number>
): PropertyValue
```

#### Example

```javascript
const promoDate = Hackle.bridge.getTriggerEventProperty("promo_date", "11.29");
document.getElementById("period-text").textContent = promoDate + " FRI — Special sale until midnight";
```

## User Behavior Tracking

### Tracking Clicks

You can track click events corresponding to **conversions** in an in-app message campaign.

The `$in_app_action` event is triggered, and based on this event, you can check campaign performance in the Hackle Dashboard.

* [View performance measurement in detail](/en/crm-marketing/in-app-message-guide/analyze-in-app-message.md)
* [View in-app message events in detail](/en/event-management/hackle-event.md)

```typescript
trackClick(elementId?: string): void
```

#### Example

```html
<button id="hackle-conversion">
	Hackle Conversion
</button>
<script>
  window.addEventListener("hackleBridgeReady", function(){
    document.querySelector("#hackle-conversion").addEventListener("click", function(e) {
      Hackle.bridge.trackClick("main-funnel-user-conversion-1");
    });
	})
</script>
```

![elementId added as $in\_app\_action event property](/files/ky5YERQHgRNkMSPH4On9)

### Handling link click and click tracking simultaneously

When a link click itself is considered a conversion, handle opening the URL and collecting the link click event simultaneously.

```typescript
handleUrl(url: string | HackleInAppMessageLink, elementId?: string): void
```

#### Example

```html
<button id="hackle-link">
	Hackle Link
</button>
<script>
  window.addEventListener("hackleBridgeReady", function(){
    document.querySelector("#hackle-link").addEventListener("click", function(e) {
      Hackle.bridge.handleUrl("https://hackle.io","main-funnel-user-conversion-1");
    });
	})
</script>
```

### Event Tracking

Sends an event.\
Same as the [method for sending events in the JavaScript SDK](/en/development-guide/javascript/event-tracking.md).

#### Example

```html
<button id="custom-btn">X</button>
<script>
  window.addEventListener("hackleBridgeReady", () => {
    const closeButton = document.querySelector("#custom-btn");

    const event = {
      key: "purchase",
      properties: {
        pay_method: "CARD",
        discount_amount: 800,
        is_discount: true
      }
    };

    closeButton.addEventListener("click", () => {
      Hackle.bridge.track(event);
    });
})
</script>
```

## Closing an In-App Message

Closes the in-app message.

```typescript
closeInAppMessage(hideDuration?: boolean | number): void
```

<table><thead><tr><th width="220.390625">hideDuration</th><th>Description</th></tr></thead><tbody><tr><td><code>true</code></td><td>Hide for one day</td></tr><tr><td><code>false</code></td><td>Close immediately</td></tr><tr><td><code>number</code></td><td>Hide for the number of minutes passed</td></tr><tr><td><code>null / undefined</code></td><td>Close immediately</td></tr></tbody></table>

#### Example

```html
<button id="close-btn">X</button>
<button id="hide-today-btn">Do not show today</button>
<button id="hide-10m-btn">Do not show for 10 minutes</button>

<script>
  window.addEventListener("hackleBridgeReady", () => {
    const closeButton = document.querySelector("#close-btn");
    const hideTodayButton = document.querySelector("#hide-today-btn");
    const hide10mButton = document.querySelector("#hide-10m-btn");

    closeButton.addEventListener("click", () => {
      Hackle.bridge.closeInAppMessage();
    });

    hideTodayButton.addEventListener("click", () => {
      Hackle.bridge.closeInAppMessage(true);
    });

    hide10mButton.addEventListener("click", () => {
      Hackle.bridge.closeInAppMessage(10);
    });
  });
</script>
```

{% hint style="info" %}
Get started quickly with the HTML in-app message template.

We provide [HTML In-App Message Templates](/en/crm-marketing/in-app-message-guide/html-message/in-app-message-html-template.md) that you can use immediately with copy-paste.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/en/crm-marketing/in-app-message-guide/html-message/in-app-message-html-javascript-bridge.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
