Create an in-app message
Write the message, choose when it shows and who sees it, set how often, send a test, and launch.
Build an in-app message from blank to launch. The example is Medly, a health app, showing a card to people who open their plan screen for the third time without subscribing.
Your app or site needs iOS SDK 3.1.0, Android SDK 3.1.0 or Web SDK 2.1.0 or later. See SDK requirements for Flutter, React Native and Unity. Until a platform is connected, In-App shows Connect a platform to show in-app messages instead of the list.
Go to Engage › In-App and click New message. Choose Blank message, or Start from a template for a ready-made Ask people to update, Rate the app or Quick question message.
The composer has six steps: Message, Trigger, Audience, Experiment, Limits and schedule and Check and launch. Drafts can be incomplete; Save draft works at any time.
In Message, pick a Template (see Formats) and fill in Title, Message and Image.
Under What people can do, choose:
- Tap a button: up to two buttons, plus an optional action for a tap on the message itself.
- Answer a question: stars or a choice. See Surveys and ratings.
Each button has a label and an action:
| Action | Does |
|---|---|
| Close the message | Closes it |
| Open a link | Opens a web or app link, such as https://medly.app/plans or medly://plans. See Links and in-app browsers |
| Send data to the app | Passes up to 20 key-value pairs to your app's click callback |
| Ask for push permission | Shows the system permission prompt. Apps only |
| Ask for an app rating | Shows the system review prompt. Apps only |
| Open the app's store page | Opens your app in the App Store or Google Play. Apps only |
Messages with an app-only action never show on the web. A push permission message is skipped for people who already granted it.
Set how the message closes:
- People can close it without answering: close button, tap outside or swipe. Turn it off for something that must be acted on, such as a required update. The message then stays until a button or the message is tapped.
- Show a close button
- Dim the app behind the message
Pick Colours from a theme or set your own, and an Orientation if the message only works one way.
Insert a value adds a person's attribute or a property of the triggering event, with a fallback:
Hi {{ user.first_name | default: "there" }}
{{ event.plan_name | default: "Your plan" }} is one tap awayFields work in the title, message, button labels and links. In a link, the value is URL-encoded and can't supply the scheme or host. If a field has no value and no fallback, the message isn't shown for that trigger.
In Trigger, choose what shows the message:
| Trigger | Fires |
|---|---|
| The app is opened | Once per visit (SDK session) |
| A screen is viewed | When a screen or page is viewed: one by name, or any. Case-insensitive |
| An event is tracked | When a custom event is tracked. Exact name match. Add up to five filters under Only when the event has; all must pass |
Add another trigger allows up to five; any one fires the message.
For Medly: A screen is viewed, screen Plans.
Under When to show it, a Delay of a few seconds lets the screen settle. After the delay the message is re-checked and shown only if it still applies. A waiting message is dropped if the app goes to the background.
In Audience, choose:
- Everyone: every visitor of the project.
- People in a segment: refreshed hourly, so people become eligible within about an hour of joining. See Segments.
Under Conditions on the device (optional), add up to ten conditions. All must hold at trigger time. The device checks them itself, with no delay.
| Condition | Checks |
|---|---|
| Platform | iOS, Android or web |
| App version, OS version | Compared as versions, so 2.10 is above 2.9. On the web, OS version is empty and app version is what your site passes to the SDK |
| Language | The device's main language, such as en |
| User attribute | An attribute your app has set |
| Times an event happened | How often this device tracked an event. Counting starts when a message naming the event first reaches the device; earlier history isn't seen. Use a segment for past behaviour |
| First seen | Before or after a date, or in the last so many days |
For Medly: Times an event happened plans_viewed is above 2, and User attribute subscribed is not true.
In Experiment, add a Goal (built-in event, custom event, screen or purchase, within 1, 3 or 7 days, or 30 days for purchases), a Control group, and up to two extra content variants. See Experiments.
The control group and number of variants are fixed at launch.
In Limits and schedule, set How often one person sees it: at most so many times per visit, day, week or ever. Day and week allow up to 20. Leave a box empty for no limit.
Visit, day and week limits are per device. The "ever" limit also holds across a person's devices and reinstalls, once they're identified.
The project caps messages per device per visit and per day (10 each by default, in Engagement Settings). Not held back by the project limit exempts a message that must always show; it then doesn't count toward that limit either.
Priority runs from 1, lowest to 10, highest. When several messages match, only the highest priority shows; on a tie, the older message wins. One message is on screen at a time, with at most one waiting.
Under When it runs, set a start and an end, or Until I end it. These are one moment for everyone, entered in your time zone. Only on certain days or hours follows each device's clock, so 09:00 is local. A window such as 22:00 to 06:00 crosses midnight.
Under See it on a device, enter a User identifier and click Send test. Save first: the test uses the last saved version.
Use the identifier your app gives the SDK (Grovs.userIdentifier on iOS, Grovs.setUserIdentifier() on the web). The test goes to all of that person's devices, up to 50, and shows at each device's next sync within 30 minutes. It ignores triggers, conditions, limits and schedule, shows once, and isn't counted in the report.
| Device | Shows the test |
|---|---|
| iOS app | When the app returns to the foreground, or at its next sync |
| Web page | On the next page load, when the tab comes back into view, or at the next 15-minute sync of an open, visible tab |
The 30-minute window outlasts the web SDK's 15-minute sync, so an open tab still gets the test. After 30 minutes it expires; send it again.
A test is refused if nobody in the project has that identifier, or the message isn't complete enough to launch. Browsers skip tests that use an app-only action.
Check and launch summarizes the message in one sentence and lists anything to fix. Click Launch.
- An Everyone message goes Live, or Scheduled if its start is in the future.
- A segment message shows Preparing audience first. If the audience can't be resolved, it returns to Draft with the reason.
After launch
You can edit a live message's content, triggers, conditions, limits and schedule; devices pick up changes at their next sync. You can't change its template, audience, control group or number of variants.
| Action | Does |
|---|---|
| Pause / Resume | Stops and restarts delivery. Devices in use stop usually within a minute, and at most about 15 minutes on an idle device |
| End | Stops it for good. The report stays |
| Update audience | Moves a segment message to the segment as it is now. The old audience is served until the new one is ready |
| Duplicate | Copies it into a new draft |
| Delete | Drafts only |
People who answered a question or hit the "ever" limit won't see the message again. To ask again, duplicate it.