Message Personalization

Concepts - Ways to personalize messages to individual users

Personalizing messages helps users connect more with your app and website. Common examples are putting the person's name or abandoned cart item in the notification title, message or image.

There are generally 2 ways to go about this:

  1. Using OneSignal's Data Tags for tag substitution. Refer to this chart to see which fields support tag substitution.
  2. Track the Player ID or External User ID through your CRM or database and target the device directly with custom messages. See our Internal Database, DMP, & CRM for more on how to set this up.

Tag Variable Substitution

Push Notifications, In-App Messages, Emails, and SMS all support liquid syntax inline placeholders based on Data Tags set on each user's device. The tag key will be substituted with each individual device's tag value.

FieldPushIn-AppEmailSMSLive Activities
Content Click URLYesN/AYesN/AN/A
ImageYesYesImage substitution available with the HTML Block or HTML Editor

<img src="{{image_url}}"/>
Image Click URLN/AYesYesN/AN/A
Button Click URLYes (Web Only)YesYesN/AN/A
Event Updates
(Live Activities Only)

Let says for example you want to send a message with a user's name and current stage they are on in your game. Example:

Hello Josh! We just improved our controls, come back and see if you can beat level 10!

You can set 2 tags to all your users, for example: first_name and current_level.

Within the message, set the "tag key" within the liquid syntax inline with your message, for example: {{ tag_key | default: 'default_value' }}. Replacing tag_key with your own key, as well as the required default value.

Example tags set across 3 users.

User 1: tags: first_name : Josh, current_level: 10
User 2: tags: first_name: George, current_level: 9
User 3: No Tags

Send a notification with the following contents:
Hello {{ first_name | default: 'there'}}! We just improved our controls, come back and see if you can beat level {{ current_level | default: '1' }}!

This will result in the following notifications going out to each user.

User 1Hello Josh! We just improved our controls, come back and see if you can beat level 10!
User 2Hello George! We just improved our controls, come back and see if you can beat level 9!
User 3Hello there! We just improved our controls, come back and see if you can beat level 1!

Tag Substitution happens client side for In-App Messages but server side for Push, Email, and SMS.


Character Limitations

Only use alphanumeric characters and an underscore ("_"). Spaces, Periods (or "dots"), etc in tag keys cannot be substituted/processed and will result in a blank.

Launch URL Substitution

You can add tag substitution into the Launch URL (and associated web URL and app URL) of the push. You should not include the http:// or https:// protocol in the tag. Also not recommended to include the site origin. It is recommended to only tag the path of the URL the user should go to.

For example, let's say you want to send the user to an abandoned cart page: where jonf867 is my "cart id"

You would tag the user with OneSignal.sendTag("cart_id", "jonf867");

Then set the Launch URL to be:{{cart_id}} the cart_id tag key will be replaced with the tag value when clicked by the user.

Another example we share is to Auto-Segment By Subscription Page where you tag the user with the sub_page : pathname which is the path of the subscription page which the user subscribed.

For instance, if I subscribed on, my device will be tagged with sub_page : /finance/tesla-soars-today

  OneSignal.sendTag("sub_page", location.pathname);

However, if the URL also contains query parameters that you want to include. For example:

Then you can use the location.pathname + browser variables to capture the entire URL.

  OneSignal.sendTag("sub_page", location.pathname +;

You can reference this in the Launch URL by adding:{{sub_page}} because the tag already contains "/". If the tag does not contain "/" make sure you add it.

You can always test your implementation by setting yourself as a test user. See Find Devices & Set Test Users more details.

Image Substitution

A common example for Abandoned Cart is to add the last item set to the cart's image in the push. You can simply tag the user with a key like "cart_image" and the value is the full URL to the image.

Then in the Dashboard Image field or API Image parameters, you can set the tag key surrounded by curly brackets {{cart_image}} and/or add a default image
{{cart_image | default: ''}}

In addition to the main notification image, you can also use tag substitution for images and icons for different platforms under platform settings.

Live Activity Event Updates Tag Substitution

Tag substitution of live_activity_ios_event_updates enables sending personalized live activities to many end-users at once.

For example:{ 'home_score': '100', 'visitor_score': '101', 'seat': 'Seat: {{ seat_number | default: "Unknown" }}' }

Where seat_number would be substituted with the corresponding tag value for the player. Reference our Message Personalization Guide for more information.

Advanced Substitution

Helpful options available with liquid syntax.

Date Substitution

If you are using Time Operators you are likely setting tags with unix timestamps. For example, your tags might look like: expiration_date : 1671489108

With the liquid syntax date option, you can set the day of week %a, month %b, day %d, and year %y like this:
{{ expiration_date | date: "%a, %b %d, %y" }}

This will show in your message as: Mon, Dec 19, 22

IF Statements

The push and email fields that support tag substitution use Liquid syntax which can come in handy for certain situations. Be careful not to get too complex with this code as it could create delays or issues with sending. Anything beyond simple if-else statements or addition/subtraction options are not recommended.

{% assign balance = balance %}
{% if balance == 0 %}Your balance is 0.
{% endif %}
{% if balance != 0 %}Your balance from 1000 is {{1000 | minus: balance}}
{% endif %}
{% assign first_name = first_name %}
{% if first_name contains "guest" %} Hi Amazing Person!
{% else %}
{{first_name | default: "Amazing Person"}}!
{% endif %}
{% assign balance = balance %}
{% if balance == 0 %}
    <a href=“some-link”>My Cool Link</a>
{% endif %}
{% if balance != 0 %}Your balance from 1000 is {{1000 | minus: balance}}
    <a href=“another-link”>Here is a different link</a>
{% endif %}


Why is substitution not working?

Tag substitution will not work when sending to test users via the "Send Test Message" buttons. You need to send the actual message.

Tag substitution will not work if you have spaces, periods, or "dots" in tag keys. Only use alphanumeric characters and an underscore ("_") or hyphen ("-") in your tag keys if needed.

Tag substitution will not work in the previews. You need to send the actual message.