In-app messages
UpdatedWhen you use our JavaScript client, you can send in-app messages to your website visitors. This page helps you understand how some in-app features work so that you can better target and display messages.
How it works
In-app messages for your website work differently than push notifications would: they require JavaScript, and they don’t go through a push notification service (like APNs or FCM).
In most cases, you simply need to identify
your web visitors, and they’ll become eligible to receive your in-app messages.
until user opens app a->>b: User opens app b->>c: Identify User c->>b: Send in-app message b->>a: User sees
in-app message
Send an in-app message
To send an in-app message, you’ll need to do the following things. Because most of these things happen outside the SDK, we’ve linked to relevant documentation.
- Enable in-app messaging
- Set up message templates
- Add in-app messages to your campaigns or broadcasts
- In most cases, you’ll need to identify visitors to your website before they can receive an in-app message.
Enable in-app messaging
To set up in-app messages with our JavaScript client, you only need to enable in-app messaging in your workspace. When you have in-app messaging enabled, we’ll automatically load the in-app messaging plugin on pages containing your JavaScript snippet.
Go to Settings > Workspace Settings and click Get Started next to In-App.
Click Enable in-app.
(Optional) Click Send Test and enter the email address or ID of a test user to prove your implementation. If this is your first in-app message, it might take a minute for it to appear and you might need to refresh the page where you expect to see your test message.
When you send your first message, we poll slowly for messages (about once a minute). When you receive your first message, polling speeds up, eliminating the delay.
Add support for anonymous messaging
If you want to send in-app messages to people who aren’t identified, you’ll need to add an anonymousInApp
flag to your snippet. This lets you support anonymous messaging. See Anonymous in-app messages for more information.
!function(){var i="cioanalytics", analytics=(window[i]=window[i]||[]);if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.setAttribute('data-global-customerio-analytics-key', i);t.src="https://cdp.customer.io/v1/analytics-js/snippet/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._writeKey=key;analytics._loadOptions=e};analytics.SNIPPET_VERSION="4.15.3";
analytics.load("YOUR_CDP_API_KEY",
{
"integrations": {
"Customer.io In-App Plugin": {
anonymousInApp: true
}
}
});
analytics.page();
}}();
Listen to in-app message events
We expose in-app message events that you can listen for and respond to—performing additional functions in response to a person interacting with or dismissing your message.
You’ll define functions handling each event type in an events
key when you initialize the SDK. These events all have a detail
object containing additional data about the event, like the deliveryId
or messageId
that you can act on.
analytics.load(
"CDP_WRITE_KEY",
{
"integrations": {
"Customer.io In-App Plugin": {
siteId: "YOUR_SITE_ID",
events: function(event) {
switch (event.type) {
case "in-app:message-opened":
// do something when a message is opened
break;
case "in-app:message-dismissed":
// do something when a message is dismissed
break;
case "in-app:message-action":
// do something when a message is interacted with
break;
case "in-app:message-error":
// do something when a message errors
break;
case "in-app:message-changed":
// do something when a user moves to the next step in a multi-step message
break;
}
}
}
}
}
);
Events and examples
You can listen for the following in-app events:
- Message opened: this happens when your message is displayed to a person.
- Message dismissed: happens when someone dismisses your message. Remember, dismissing a message doesn’t necessarily mean that a person didn’t respond; dismissing a message often happens when someone responds to a message too.
- Message action: these are the things that happen when a person interacts with your message
- Message error: respond when something goes wrong with your message.
- Message changed: respond when someone engages the next step in a multi-step message. See Multi-step messages for more information.
Each event has a detail
object containing additional data about the event, like the deliveryId
or messageId
that you can act on. For the message-action
event, we also expose the actionName
and actionValue
.
{
// one of: "in-app:message-opened", "in-app:message-dismissed",
// "in-app:message-action", "in-app:message-error"
"type": "in-app:message-action",
"detail": {
"deliveryId": "1234567890",
"messageId": "1234567890",
// only for "in-app:message-action and in-app:message-changed"
"actionName": "action name", // for message-changed, this is the name of the next step
"actionValue": "action value"
}
}
Page rules and in-app messages
You want to make sure that your messages are relevant to the pages that your audience visits. Maybe you want to alert people to new features on a particular page or run a tutorial for people in certain parts of your app. That’s what Page Rules are for: they determine the page(s) where people can encounter your message.
Page rules also help avoid conflicting messages by distributing messages to the pages where they’re most relevant to your audience. If you send two messages of the same priority without page rules, they’ll appear one after the other.


When you set a page rule for the Web platform, you’ll use the complete page URL (window.location.href
) unless you pass page
calls with a different name parameter. For example, https://example.com/*/billing
would cover paths on your website like your in-app billing page https://example.com/ui/billing
or documents about billing under https://example.com/billing
. See the page method reference for more information.
Use *
to represent all pages
When you select a channel, you have to enter a page rule. But, if you want to show a message on every page on your website or app, you can simply enter *
.
Page rules for single-page applications
The JavaScript snippet automatically sends page calls when it loads. But if you import/bundle the JavaScript SDK, or have a single page application (SPA), you’ll need to call cioanalytics.page()
manually for each page or route.
This tells the SDK what “page” a person is on so you can target in-app messages to people on certain pages of your app.