In-App Experiences

Instrument your website or web application for in-app experiences. Web SDK 2+

The Airship Web SDK v2 supports ScenesA single or multi-screen in-app experience cached on users’ devices and displayed when users meet certain conditions in your app or website, such as viewing a particular screen or when a Custom Event occurs. They can be presented in fullscreen, modal, or embedded format using the default swipe/click mode or as a Story. Scenes can also contain survey questions., including Embedded Content. See also Implementing Web SDK v2 .

Instrumenting your Application

In order for Scenes to function, you must Create a channel. This will count the current browser toward your Monthly Unique Visitors.

To get the most out of Scenes, instrument your website or web application to emit events for triggering and event segmentation. The following sections describe the events and provide code samples.

See also:

Custom Events

Custom EventsEvents that indicate that a user performed a predefined action, such as adding an item to a shopping cart, viewing a screen, or clicking an Unsubscribe button. Custom Events can trigger automation, including Sequences and Scenes. You can code them into your app or website, or send them to Airship from an external source using the Custom Event API. Custom Events contain properties that you can use to personalize messages. can be used to track any interaction you wish, for example a purchase or a product view.

Sending a Custom Event
const sdk = await UA
const evt = new sdk.CustomEvent('purchase', 34.5, {productId: 1337})
await evt.track()

Screen View Events

Tracking App Screens can make it easy to trigger a Scene or to ensure a Scene is only displayed when currently on a given screen. You must define App Screens in the Airship dashboard.

In the context of a website or web application, you can think of a “screen” as a page with a general purpose. For example, home, product_listing, and product_detail are good generic screen names, whereas product_id_18957 is too specific and unlikely to be generally useful for reporting or targeting.

Tracking a Screen View
const sdk = await UA
await sdk.analytics.trackScreen('home')

Feature Flag Interactions

When using Feature FlagsAn experimentation tool for controlling the availability of content or functionality in your app or website. A flag’s Configurations determine the audience, schedule, and property values to apply when the flag is enabled. Flag properties enable making immediate code updates, bypassing the need for traditional code changes and release processes., you should track when a user has interacted with the feature the flag controls. The interaction event is included in Feature Flag reporting and can also be used for triggering:

Tracking Interaction with a Flagged Feature
const sdk = await UA
const flag = await sdk.components.featureFlags.get('new_product_pages')

// later, when the user interacts with the new product pages
await sdk.components.featureFlags.trackInteraction(flag)

App Version Updates

If you version your web app and wish to be able to target users who may have seen an earlier version of the app, when initializing the SDK, use the appVersion property set to your app’s version number. This will be passed in your snippet as well as your push worker:

Setting your App Version
<script type="text/javascript">
var options = {
  appKey: '<your_app_key>',
  token: '<your_token>',
  vapidPublicKey: '<your_vapid_public_key>',
  // your app version, as `<major>.<minor>.<patch>`
  appVersion: '1.2.1'
}
!function(n,r,e,t,c){var i,o="Promise"in n,u={then:function(){return u},catch:function(n){
return n(new Error("Airship SDK Error: Unsupported browser")),u}},s=o?new Promise((function(n,r){i=function(e,t){e?r(e):n(t)}})):u
;s._async_setup=function(n){if(o)try{i(null,n(c))}catch(n){i(n)}},n[t]=s;var a=r.createElement("script");a.src=e,a.async=!0,a.id="_uasdk",
a.rel=t,r.head.appendChild(a)}(window,document,'https://aswpsdkus.com/notify/v2/ua-sdk.min.js','UA', options);
</script>

Controlling Scenes

If Scenes are enabled for your project, they will display according to their trigger and conditions settings. You can control their display programmatically or disable them completely, if desired.

Screen Sizes and Breakpoints

When creating Scene view styles in your project’s default settings, you can define alternative settings that apply to a Scene based on a device’s screen size. These sizes are defined by screen width breakpoints in the SDK:

  • Small: Less than 1024px
  • Medium: Greater or equal to 1024px and less than 1920px
  • Large: 1920px and greater

You can override the values by setting custom breakpoints that better match your web application. Pass the following options in your SDK initialization snippet:

Setting Screen Sizes
components: {
  inAppAutomation: {
    displayBreakpoints: {
      // the size at which a screen will be considered "medium", in pixels; inclusive
      medium: 800,
      // the size at which a screen will be considered "large", in pixels; inclusive
      large: 1024
    }
  }
}

Anything smaller than “medium” is considered to be a “small” screen, so no value needs to be set for that breakpoint.

If you set custom breakpoints, also add them to your project settings for more accurate device previews when creating Scenes. Follow the steps for Setting Scene defaults in In-App Experience Defaults and set Breakpoint values in a view style’s Background settings.

Disabling

To permanently disable Scenes in the current browser, pass the following options in your SDK initialization snippet:

Disabling Scenes
components: {
  inAppAutomation: {
    enabled: false
  }
}

Pausing and Resuming Display

You can choose to pause and resume Scene display. For example, you might wish to only disable showing new Scenes when opening a modal on your site or during a checkout flow.

Pausing and Resuming Scenes
const sdk = await UA

// pause display of scenes
await sdk.components.inAppAutomation.setPaused(true)
// get the paused status; resolves to a boolean value
await sdk.components.inAppAutomation.isPaused()
// resume display
await sdk.components.inAppAutomation.setPaused(false)

By default, displays are not paused. If you’d like to start in a paused state so that you can manually unpause at a time of your choosing, pass the following configuration in your SDK initialization snippet:

Starting Scenes in Paused State
components: {
  inAppAutomation: {
    startInPausedState: true
  }
}

Delegating Display

You can choose to implement your own display delegate, which can control if a Scene is allowed to be displayed. It can also be notified when a Scene is displayed or has finished displaying.

Your display delegate must implement the InAppDisplayDelegate interface. All methods are optional.

 Note

When using a display delegate, we recommended that you start display in a paused state and then unpause after setting your delegate. Otherwise, it is not guaranteed your delegate will be registered before displays occur.

Controlling Display using a Delegate
const delegate = {
  isMessageReadyToDisplay: (message) => {
    if (myApp.canDisplayMessage(message)) {
      return true
    }
    return false
  }
}
await sdk.components.inAppAutomation.setDisplayDelegate(delegate)
await sdk.components.inAppAutomation.setPaused(false)

If you need to pass additional information to your application, you can use Custom Keys when composing your Scene. They will be available on the extras property of the InAppAutomationDetails that are passed to your delegate.

Dark Mode

By default, Scenes follow the browser preferences for dark mode. This behavior can be disabled by a configuration value. When disabled, all displayed content will use the colors configured for light mode.

Disabling Automatic Dark Mode
components: {
  inAppAutomation: {
    matchBrowserDarkMode: false
  }
}

Custom Views

A Custom View is a native view from your mobile or web application embedded into a Scene. Custom Views can display any native content your app exposes, so you can reuse that existing content within any screen in a Scene. For a web page, this means embedding an HTML view into a Scene.

 Note

When using Custom Views, you should initialize In-App Experiences in a paused state. If you do not, there’s no guarantee that your Custom View delegate will be registered by the time a Scene displays, and the Custom View would not be shown. See the section on Pausing and Resuming Display for further information.

Implementation

To display Custom Views, you must implement the InAppCustomViewDelegate interface and register it using the setCustomViewDelegate method of the InAppAutomationManager. Only one delegate may be registered at a time.

When it’s time for a Custom View to be displayed, your delegate’s onCustomViewShown method will be called with the following parameters:

  • name — The name of the Custom View, which is referenced when adding it to a Scene
  • element — The HTML element into which your Custom View should render
  • properties — Any additional properties set for your Custom View as a key/value object; all keys and values will be strings

When called, your onCustomViewShown method must return an object that fulfills the InAppCustomViewHandler interface. This will contain the destroy method, which will be called with no parameters when your view is to be removed.

 Important

Your delegate should render synchronously into the provided element. If it does not, you may cause the Scene’s layout to shift after rendering.

Example Custom View

The following example shows a Custom View that renders an embedded Google Map when called to render a Custom View named map. This example assumes that you have started In-App Experiences in a paused state, as recommended above.

In our example, we pass properties to the view to determine the location the map should show. q is the query to pass to the map view.

Example Custom View rendering a map
// a React Function Component for rendering an embedded Google Map
const Map = ({ q }) => {
  return (
    <iframe
      width="100%"
      height="250"
      frameBorder="0"
      style={{ border: 0 }}
      referrerPolicy="no-referrer-when-downgrade"
      src={`https://www.google.com/maps/embed/v1/place?key=<YOUR_API_KEY>&q=${encodeURIComponent(q)}`}
      allowFullScreen
    />
  )
}

// our delegate method which will be called when the Custom View is displayed
const onCustomViewShown = (name, el, properties) => {
  switch (name) {
    case "map":
      // when the `name` is `map`, render our map view
      const { q } = properties
      ReactDOM.render(<Map q={q} />, el)
      break
  }
  return {
    // remove the react component when the view is destroyed
    destroy: () => ReactDOM.unmountComponentAtNode(el),
  }
}

const sdk = await UA
// define the delegate
const delegate = {onCustomViewShown}
// register the delegate with the Airship SDK
await sdk.components.inAppAutomation.setCustomViewDelegate(delegate)
// resume display
await sdk.components.inAppAutomation.setPaused(false)