We are pleased to announce that Layer UI for Web is now generally available. Layer UI for Web extends the Layer Web SDK to include a library of customizable, commonly used widgets to be used for creating web-based messaging experiences.

These widgets are intended to allow developers to focus on the look, feel and use-case specific functionality of their web messaging interface rather than building basics from scratch.

This post will serve as an overview of our approach and an introduction to Layer UI for Web. You can view the full documentation here.


Our UI Framework Philosophy

React is popular, so there was a lot of temptation to use it to build a UI framework that would primarily satisfy React developers and call it good enough.

We didn’t.

Our philosophy on JavaScript Frameworks is as follows:

  • Your framework is your choice
  • We’re not going to force you to also use React, or Angular, or any other common framework
  • The ability to easily customize or even replace any single widget or behavior is critical to you building your application the way you want it.

To achieve these goals, we’ve used Web Components. Web Components will work with almost any UI framework (or with plain JavaScript) without requiring dependencies beyond an optional Web Components polyfill. They are also remarkably easy to work with.

To illustrate how Web Components are used, the code below uses no framework to generate the picture above, and depends upon two widgets:

  1. layer-conversations-list: A widget for loading, scrolling through and selecting Conversations that your user is participating in
  2. layer-conversation-panel: A widget for viewing messages in a conversation, sending messages in reply, typing indicators, marking messages as read, paging, etc…
  <layer-conversations-list id='mylist'>
  <layer-conversation-panel listen-to='mylist'>

Web Components provides the capability of telling the browser that the DOM nodes described above exist, as well as the ability to associate rendering and behaviors with those nodes.

We add an optional header row as used in the picture above:

<div class='header'>  
  <div class='layer-conversations-list-header'>
    User <span class='user-name'></span>'s Conversations
  <div class='layer-conversation-header'></div>

The listen-to attribute tells the conversation panel to listen to the conversations list and to show any conversation selected by the user.

Alternatively, instead of using listen-to, we could build this ourselves with a little JavaScript:

// Initialize the Layer UI Framework
    appId: "layer:///apps/staging/UUID"

// Get the dom nodes
var conversationList = document.querySelector('layer-conversations-list');
var conversationPanel = document.querySelector('layer-conversation-panel');
var conversationHeader = document.querySelector('.layer-conversation-header');

// Whenever the user selects a conversation:
conversationList.onConversationSelected = function(evt) {  
    var conversation = evt.detail.item;

    // Tell the Conversation Panel what conversation to show
    conversationPanel.conversation = conversation;

    // Update the label above the Conversation Panel
    conversationHeader.innerHTML = conversation.metadata.conversationName;

Isn’t Web Components just another UI framework?

Well… ok… yes. But it’s also:

– A Web Standard
– Natively supported in many browsers and is supported via polyfill in all other supported browsers
– Can be written using a number of open-source frameworks or with raw JavaScript.

How much coding is really required?

There are products where you just drop an entire chat experience as a widget into your app and you declare done. This is great for certain use cases and providing such a starting point is a goal we are working towards.

But ultimately, as any application evolves, it requires custom UI behaviors that differentiate your app and help focus on your core business goals.

To accomplish this, Layer is making available a library of UI widgets that you can integrate into your application and customize as you see fit. In the above example, the <layer-conversations-list /> provides an event when the user selects a conversation, and you use that event to tell the <layer-conversation-panel /> what the selected conversation is.

Is that all the coding that is needed for a basic, un-customized application? Yes that is all the UI code needed (there is still authentication which is handled separately via Layer’s WebSDK).

Ultimately, more code will always be added:

– Do you want a dialog to show a list of users to create a new conversation?
– Do you want to support custom message types?
– Do you want to allow for deletion of messages or conversations?
– Do you want to modify messages before they are sent?

As you depart from the plainest possible application and head toward customizing an experience, more coding will be needed. But configurability is core to our UI philosophy. Relatively small amounts of code are typically needed to customize behaviors.


A message list is just the beginning of your messaging experience. Being able to send textual messages back and forth provides you with a basic shippable product. But interactive content is where your app stops feeling like an SMS integration and starts feeling like a rich, interactive conversation between participants.

Being able to render content like credit card forms, purchase approvals, work orders, shopping cards, and other resources in the messaging list will help you shape your UX to fit your business needs beyond plain text.

Using any Web Component framework you like, you can implement a message handler capable of rendering the custom resources your application needs. This functionality, available across the Layer platform, allows for the creation of arbitrarily rich, interactive message elements. Examples below will include some basic utilities Layer UI uses to define its own Web Components, but this is not a constraint on your own implementation.

The first step is to tell Layer UI how to handle a custom/credit-card message:

  tagName: 'custom-credit-card-form',
  label: 'Credit Card Form received',
  handlesMessage: function(message) {
    return message.parts[0].mimeType === 'custom/credit-card';

This code includes:

  • tagName: Identifies the DOM node that will be generated to render this message. The example above tells Layer UI to generate a <custom-credit-card-form />.
  • handlesMessage: Tests against each Message to determine if the specified tagName should be generated for this Message.

The second step is to build a Web Components custom-credit-card-form:

var MessageHandler = layerUI.mixins.MessageHandler;  
layerUI.registerComponent('custom-credit-card-form', {  
  mixins: [MessageHandler],
  template: `<form><fieldset>
    <legend>Enter Credit Card</legend>
    <div><label>Card Number</label><input type="text" /></div>
    <div><label>Expiration Date</label><input type="date" /></div>
    <input type='submit'>Setup Payment</input>
  methods: {
    onCreate: function() {          
    validateAndSendCardInfo: function() {
       // custom code for validating the card and sending it to your server

On filling out the credit card form and hitting send, the card information can be sent to your server securely, and then your card could then send a message to other participants indicating that payment was received.

More Customizability

Our documentation is full of examples for how to customize a variety of aspects of your application.

– Defining new message handlers
– Changing the layout and template of a message item in the message list
– Adding, enhancing, and replacing behaviors of widgets using Mixins
– Changing default behaviors such as what happens when the user hits the SEND button after typing a message
– Replacing widgets such as the avatar widgets with your own widget definitions

These are all written up in more detail in the Layer UI Customization Documentation.

What’s Next?

– Check out the Layer UI Documentation
– Check out the
Sample Apps
– Provide feedback at

Get A Free Demo