Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies

Wednesday, July 24, 2024

Building A User Segmentation Matrix To Foster Cross-Org Alignment

 Many organizations prioritize internal structures and services over customer-centricity, hindering effective decision-making. Through a case study, Talke Hoppmann-Walton advocates for a shift towards an outside-in perspective and proposes the use of a user segmentation matrix to foster alignment across departments and prioritize customer needs. If you are an experienced product or UX professional or a team leader dealing with stakeholder management to drive the organization as a whole forward, this article provides you with a canvas for better decision-making and focus.

Do you recognize this situation? The marketing and business teams talk about their customers, and each team thinks they have the same understanding of the problem and what needs to be done. Then, they’re including the Product and UX team in the conversation around how to best serve a particular customer group and where to invest in development and marketing efforts. They’ve done their initial ideation and are trying to prioritize, but this turns into a long discussion with the different teams favoring different areas to focus on. Suddenly, an executive highlights that instead of this customer segment, there should be a much higher focus on an entirely different segment — and the whole discussion starts again.

This situation often arises when there is no joint-up understanding of the different customer segments a company is serving historically and strategically. And there is no shared understanding beyond using the same high-level terms. To reach this understanding, you need to dig deeper into segment definitions, goals, pain points, and jobs-to-be-done (JTBD) so as to enable the organization to make evidence-based decisions instead of having to rely on top-down prioritization.

The hardest part about doing the right thing for your user or customers (please note I’m aware these terms aren’t technically the same, but I’m using them interchangeably in this article so as to be useful to a wider audience) often starts inside your own company and getting different teams with diverging goals and priorities to agree on where to focus and why.

But how do you get there — thinking user-first AND ensuring teams are aligned and have a shared mental model of primary and secondary customer segments?

Personas vs Segments

To explore that further, let’s take a brief look at the most commonly applied techniques to better understand customers and communicate this knowledge within organizations.

Two frequently employed tools are user personas and user segmentation.

Product/UX (or non-demographic) personas aim to represent the characteristics and needs of a certain type of customer, as well as their motivations and experience. The aim is to illustrate an ideal customer and allow teams to empathize and solve different use cases. Marketing (or demographic) personas, on the other hand, traditionally focus on age, socio-demographics, education, and geography but usually don’t include needs, motivations, or other contexts. So they’re good for targeting but not great for identifying new potential solutions or helping teams prioritize.

In contrast to personas, user segments illustrate groups of customers with shared needs, characteristics, and actions. They are relatively high-level classifications, deliberately looking at a whole group of needs without telling a detailed story. The aim is to gain a broader overview of the wider market’s wants and needs.

Tony Ulwick, creator of the “jobs-to-be-done” framework, for example, creates outcome-based segmentations, which are quite similar to what this article is proposing. Other types of segmentations include geographic, psychographic, demographic, or needs-based segmentations. What all segmentations, including the user segmentation matrix, have in common is that the segments are different from each other but don‘t need to be mutually exclusive.

As Simon Penny points out, personas and segments are tools for different purposes. While customer segments help us understand a marketplace or customer base, personas help us to understand more about the lived experience of a particular group of customers within that marketplace.

Both personas and segmentations have their applications, but this article argues that using a matrix will help you prioritize between the different segments. In addition, the key aspect here is the co-creation process that fosters understanding across departments and allows for more transparent decision-making. Instead of focusing only on the outcome, the process of getting there is what matters for alignment and collaboration across teams. Let’s dig deeper into how to achieve that.User Segmentation Matrix: 101

At its core, the idea of the user segmentation matrix is meant to create a shared mental model across teams and departments of an organization to enable better decision-making and collaboration.

And it does that by visualizing the relevance and differences between a company’s customer segments. Crucially, input into the matrix comes from across teams as the process of co-creation plays an essential part in getting to a shared understanding of the different segments and their relevance to the overall business challenge.

Additionally, this kind of matrix follows the principle of “just enough, not too much” to create meaning without going too deep into details or leading to confusion. It is about pulling together key elements from existing tools and methods, such as User Journeys or Jobs-to-be-done, and visualizing them in one place.

For a high-level first overview, see the matrix scaffolding below.

Visualization of the user segmentation matrix scaffolding
Visualization of the user segmentation matrix scaffolding. (Large preview)

Case Study: Getting To A Shared Mental Model Across Teams

Let’s look at the problem through a case study and see how building a user segmentation matrix helped a global data products organization gain a much clearer view of its customers and priorities.

Here is some context. The organization was partly driven by NGO principles like societal impact and partly by economic concerns like revenue and efficiencies. Its primary source of revenue was raw data and data products, and it was operating in a B2B setting. Despite operating for several decades already, its maturity level in terms of user experience and product knowledge was low, while the amount of different data outputs and services was high, with a whole bouquet of bespoke solutions for individual clients. The level of bespoke solutions that had to be maintained and had grown organically over time had surpassed the “featuritis” stage and turned utterly unsustainable.

And you probably guessed it: The business focus had traditionally been “What can we offer and sell?” instead of “What are our customers trying to solve?”

That means there were essentially two problems to figure out:

  1. Help executives and department leaders from Marketing through Sales, Business, and Data Science see the value of customer-first product thinking.
  2. Establish a shared mental model of the key customer segments to start prioritizing with focus and reduce the completely overgrown service offering.

For full disclosure, here’s a bit about my role in this context: I was there in a fractional product leader role at first, after running a discovery workshop, which then developed into product strategy work and eventually a full evaluation of the product portfolio according to user & business value.

Approach

So how did we get to that outcome? Basically, we spent an afternoon filling out a table with different customer segments, presented it to a couple of stakeholders, and everyone was happy — THE END. You can stop reading…

Or not, because from just a few initial conversations and trying to find out if there were any existing personas, user insights, or other customer data, it became clear that there was no shared mental model of the organization’s customer segments.

At the same time, the Business and Account management teams, especially, had a lot of contact with new and existing customers and knew the market and competition well. And the Marketing department had started on personas. However, they were not widely used and weren’t able to act as that shared mental model across different departments.

But How To Proceed Quickly While Taking People Along On The Journey?

Here’s the approach we took:

1. Gather All Existing Research

First, we gathered all user insights, customer feedback, and data from different parts of the organization and mapped them out on a big board (see below). Initially, we really tried to map out all existing documentation, including links to in-house documents and all previous attempts at separating different user groups, analytics data, revenue figures, and so on.

The key here was to speak to people in different departments to understand how they were currently thinking about their customers and to include the terms and documentation they thought most relevant without giving them a predefined framework. We used the dimensions of the matrix as a conversation guide, e.g., asking about their definitions for key user groups and what makes them distinctly different from others.

Discovery Board feeding into the User segmentation
Discovery Board feeding into the User segmentation. (Large preview)

2. Start The Draft Scaffolding #

Secondly, we created the draft matrix with assumed segments and some core elements that have proven useful in different UX techniques.

In this step, we started to make sense of all the information we had collected and gave the segments “draft labels” and “draft definitions” based on input from the teams, but creating this first draft version within the small working group. The aim was to reduce complexity, settle on simple labels, and introduce primary vs secondary groups based on the input we received.

We then made sure to run this summarized draft version past the stakeholders for feedback and amends, always calling out the DRAFT status to ensure we had buy-in across teams before removing that label. In addition to interviews, we also provided direct access to the workboard for stakeholders to contribute asynchronously and in their own time and to give them the option to discuss with their own teams.

3. Refine

In the next step, we went through several rounds of “joint sense-making” with stakeholders from across different departments. At this stage, we started coloring in the scaffolding version of the matrix with more and more detail. We also asked stakeholders to review the matrix as a whole and comment on it to make sure the different business areas were on board and to see the different priorities between, e.g., primary and secondary user groups due to segment size, pain points, or revenue numbers.

4. Prompt 

We then promoted specifically for insights around segment definitions, pain points, goals, jobs to be done, and defining differences to other segments. Once the different labels and the sorting into primary versus secondary groups were clear, we tried to make sure that we had similar types of information per segment so that it would be easy to compare different aspects across the matrix.

5. Communicate

Finally, we made sure the core structure reached different levels of leadership. While we made sure to include senior stakeholders in the process throughout, this step was essential prior to circulating the matrix widely across the organization.

However, due to the previous steps, we had gone through, at this point, we were able to assure senior leadership that their teams had contributed and reviewed several times, so getting that final alignment was easy.

We did this in a team of two external consultants and three in-house colleagues, who conducted the interviews and information gathering exercises in tandem with us. Due to the size and global nature of the organization and various different time zones to manage, it took around 3 weeks of effort, but 3 months in time due to summer holidays and alignment activities. So we did this next to other work, which allowed us to be deeply plugged into the organization and avoid blind spots due to having both internal and external perspectives.

Building on in-house advocates with deep organizational knowledge and subject-matter expertise was a key factor and helped bring the organization along much better than purely external consultants could have done.

User Segmentation Matrix: Key Ingredients

So, what are the dimensions we included in this mapping out of primary and secondary user segments?

The dimensions we used were the following:

  1. Segment definition
    Who is this group?
    Define it in a simple, straightforward way so everyone understands — NO acronyms or abbreviations. Further information to include that’s useful if you have it: the size of the segment and associated revenue.
  2. Their main goals
    What are their main goals?
    Thinking outside-in and from this user groups perspective these would be at a higher level than the specific JTBD field, big picture and longer term.
  3. What are their “Jobs-to-be-done”?
    Define the key things this group needs in order to get their own work done (whether that’s currently available in your service or not; if you don’t know this, it’s time for some discovery). Please note this is not a full JTBD mapping, but instead seeks to call out exemplary practical tasks.
  4. How are they different from other segments?
    Segments should be clearly different in their needs. If they’re too similar, they might not be a separate group.
  5. Main pain points
    What are the pain points for each segment? What issues are they currently experiencing with your service/product? Note the recurring themes.
  6. Key contacts in the organization
    Who are the best people holding knowledge about this user segment?
    Usually, these would be the interview partners who contributed to the matrix, and it helps to not worry too much about ownership or levels here; it could be from any department, and often, the Business or Product org are good starting points.

This is an example of a user segmentation matrix:

An example of a user segmentation matrix
Separating out primary & secondary user segments and providing key information in one space to share across the organization. (Large preview)

Outcomes & Learning #

What we found in this work is that seeing all user segments mapped out next to each other helped focus the conversation and create a shared mental model that switched the organization’s perspective to outside-in and customer-first.

Establishing the different user segment names and defining primary versus secondary segments created transparency, focus, and a shared understanding of priorities.

Building this matrix based on stakeholder interviews and existing user insights while keeping the labeling in DRAFT mode, we encouraged feedback and amends and helped everyone feel part of the process. So, rather than being a one-time set visualization, the key to creating value with this matrix is to encourage conversation and feedback loops between teams and departments.

In our case, we made sure that every stakeholder (at different levels within the organization, including several people from the executive team) had seen this matrix at least twice and had the chance to input. Once we then got to the final version, we were sure that we had an agreement on the terminology, issues, and priorities.

Below is the real case study example (with anonymized inputs):

A final version of a user segmentation matrix with anonymized inputs
Final version with anonymized inputs. (Large preview)

Takeaways And What To Watch Out For

So what did this approach help us achieve?

  1. It created transparency and helped the Sales and Business teams understand how their asks would roughly be prioritized — seeing the other customer segments in comparison (especially knowing the difference between primary vs secondary segments).
  2. It shifted the thinking to customer-first by providing an overview for the executive team (and everyone else) to start thinking about customers rather than business units and see new opportunities more clearly.
  3. It highlighted the need to gather more customer insights and better performance data, such as revenue per segment, more detailed user tracking, and so on.

In terms of the challenges we faced when conducting and planning this work, there are a few things to watch out for:

We found that due to the size and global nature of the organization, it took several rounds of feedback to align with all stakeholders on the draft versions. So, the larger the size of your organization, the more buffer time to include (or the ability to change interview partners at short notice).

If you’re planning to do this in a startup or mid-sized organization, especially if they’ve got the relevant information available, you might need far less time, although it will still make sense to carefully select the contributors.

Having in-house advocates who actively contributed to the work and conducted interviews was a real benefit for alignment and getting buy-in across the organization, especially when things started getting political.

Gathering information from Marketing, Product, Business, Sales and Leadership and sticking with their terms and definitions initially was crucial, so everyone felt their inputs were heard and saw it reflected, even if amended, in the overall matrix.

And finally, a challenge that’s not to be underestimated is the selection of those asked to input — where it’s a tightrope walk between speed and inclusion.

We found that a “snowball system” worked well, where we initially worked with the C-level sponsor to define the crucial counterparts at the leadership level and have them name 3-4 leads in their organization, looking after different parts of the organization. These leaders were asked for their input and their team’s input in interviews and through asynchronous access to the joint workboard.

What’s In It For You? 

To summarize, the key benefits of creating a user segmentation matrix in your organization are the following:

  • Thinking outside-in and user-first.
    Instead of thinking this is what you offer, your organization starts to think about solving real customer problems — the matrix is your GPS view of your market (but like any GPS system, don’t forget to update it occasionally).
  • Clarity and a shared mental model.
    Everyone is starting to use the same language, and there’s more clarity about what you offer per customer segment. So, from Sales through to Business and Product, you’re speaking to users and their needs instead of talking about products and services (or even worse, your in-house org structure). Shared clarity drastically reduces meeting and decision time and allows you to do more impactful work.
  • Focus, and more show than tell.
    Having a matrix helps differentiate between primary, secondary, and other customer segments and visualizes these differences for everyone.

When Not To Use It

If you already have a clearly defined set of customer segments that your organization is in agreement on and working towards — good for you; you won’t need this and can rely on your existing data.

Another case where you will likely not need this full overview is when you’re dealing with a very specific customer segment, and there is good alignment between the teams serving this group in terms of focus, priorities, and goals.

Organizations that will see the highest value in this exercise are those who are not yet thinking outside-in and customer-first and who still have a traditional approach, starting from their own services and dealing with conflicting priorities between departments.

Next Steps

And now? You’ve got your beautiful and fully aligned customer segmentation matrix ready and done. What’s next? In all honesty, this work is never done, and this is just the beginning.

If you have been struggling with creating an outside-in perspective in your organization, the key is to make sure that it gets communicated far and wide.

For example, make sure to get your executive sponsors to talk about it in their rounds, do a road show, or hold open office hours where you can present it to anyone interested and give them a chance to ask questions. Or even better, present it at the next company all-hands, with the suggestion to start building up an insights library per customer segment.

If this was really just the starting point to becoming more product-led, then the next logical step is to assess and evaluate the current product portfolio. The aim is to get clarity around which services or products are relevant for which customers. Especially in product portfolios plagued by “featuritis,” it makes sense to do a full audit, evaluate both user and business value, and clean out your product closet.

If you’ve seen gaps and blind spots in your matrix, another next step would be to do some deep dives, customer interviews, and discovery work to fill those. And as you continue on that journey towards more customer-centricity, other tools from the UX and product tool kit, like mapping out user journeys and establishing a good tracking system and KPIs, will be helpful so you can start measuring customer satisfaction and continue to test and learn.

Like a good map, it helps you navigate and create a shared understanding across departments. And this is its primary purpose: getting clarity and focus across teams to enable better decision-making. The process of co-creating a living document that visualizes customer segments is at least as important here as the final outcome.

Wednesday, July 17, 2024

Uniting Web And Native Apps With 4 Unknown JavaScript APIs

 Have you heard of the Screen Orientation API? What about the Device Orientation API, Vibration API, or the Contact Picker API? interested in these under-the-radar web features and discusses how they can be used to create more usable and robust progressive web apps if and when they gain broader suppo

A couple of years ago, four JavaScript APIs that landed at the bottom of awareness in the State of JavaScript survey. I took an interest in those APIs because they have so much potential to be useful but don’t get the credit they deserve. Even after a quick search, I was amazed at how many new web APIs have been added to the ECMAScript specification that aren’t getting their dues and with a lack of awareness and browser support in browsers.

That situation can be a “catch-22”:

An API is interesting but lacks awareness due to incomplete support, and there is no immediate need to support it due to low awareness.

Most of these APIs are designed to power progressive web apps (PWA) and close the gap between web and native apps. Bear in mind that creating a PWA involves more than just adding a manifest file. Sure, it’s a PWA by definition, but it functions like a bookmark on your home screen in practice. In reality, we need several APIs to achieve a fully native app experience on the web. And the four APIs I’d like to shed light on are part of that PWA puzzle that brings to the web what we once thought was only possible in native apps.

You can see all these APIs in action in this demo as we go along.

1. Screen Orientation API #

The Screen Orientation API can be used to sniff out the device’s current orientation. Once we know whether a user is browsing in a portrait or landscape orientation, we can use it to enhance the UX for mobile devices by changing the UI accordingly. We can also use it to lock the screen in a certain position, which is useful for displaying videos and other full-screen elements that benefit from a wider viewport.

Using the global screen object, you can access various properties the screen uses to render a page, including the screen.orientation object. It has two properties:

  • type: The current screen orientation. It can be: "portrait-primary", "portrait-secondary", "landscape-primary", or "landscape-secondary".
  • angle: The current screen orientation angle. It can be any number from 0 to 360 degrees, but it’s normally set in multiples of 90 degrees (e.g., 0, 90, 180, or 270).

On mobile devices, if the angle is 0 degrees, the type is most often going to evaluate to "portrait" (vertical), but on desktop devices, it is typically "landscape" (horizontal). This makes the type property precise for knowing a device’s true position.

The screen.orientation object also has two methods:

  • .lock(): This is an async method that takes a type value as an argument to lock the screen.
  • .unlock(): This method unlocks the screen to its default orientation.

And lastly, screen.orientation counts with an "orientationchange" event to know when the orientation has changed.

Browser Support #

Browser Support on Screen Orientation API
Source: Caniuse. (Large preview)

Finding And Locking Screen Orientation #

Let’s code a short demo using the Screen Orientation API to know the device’s orientation and lock it in its current position.

This can be our HTML boilerplate:

<main>
  <p>
    Orientation Type: <span class="orientation-type"></span>
    <br />
    Orientation Angle: <span class="orientation-angle"></span>
  </p>

  <button type="button" class="lock-button">Lock Screen</button>

  <button type="button" class="unlock-button">Unlock Screen</button>

  <button type="button" class="fullscreen-button">Go Full Screen</button>
</main>

On the JavaScript side, we inject the screen orientation type and angle properties into our HTML.

let currentOrientationType = document.querySelector(".orientation-type");
let currentOrientationAngle = document.querySelector(".orientation-angle");

currentOrientationType.textContent = screen.orientation.type;
currentOrientationAngle.textContent = screen.orientation.angle;

Now, we can see the device’s orientation and angle properties. On my laptop, they are "landscape-primary" and .

Screen Orientation type and angle being displayed
(Large preview)

If we listen to the window’s orientationchange event, we can see how the values are updated each time the screen rotates.

window.addEventListener("orientationchange", () => {
  currentOrientationType.textContent = screen.orientation.type;
  currentOrientationAngle.textContent = screen.orientation.angle;
});
Screen Orientation type and angle are displayed in portrait mode
(Large preview)

To lock the screen, we need to first be in full-screen mode, so we will use another extremely useful feature: the Fullscreen API. Nobody wants a webpage to pop into full-screen mode without their consent, so we need transient activation (i.e., a user click) from a DOM element to work.

The Fullscreen API has two methods:

  1. Document.exitFullscreen() is used from the global document object,
  2. Element.requestFullscreen() makes the specified element and its descendants go full-screen.

We want the entire page to be full-screen so we can invoke the method from the root element at the document.documentElement object:

const fullscreenButton = document.querySelector(".fullscreen-button");

fullscreenButton.addEventListener("click", async () => {
  // If it is already in full-screen, exit to normal view
  if (document.fullscreenElement) {
    await document.exitFullscreen();
  } else {
    await document.documentElement.requestFullscreen();
  }
});

Next, we can lock the screen in its current orientation:

const lockButton = document.querySelector(".lock-button");

lockButton.addEventListener("click", async () => {
  try {
    await screen.orientation.lock(screen.orientation.type);
  } catch (error) {
    console.error(error);
  }
});

And do the opposite with the unlock button:

const unlockButton = document.querySelector(".unlock-button");

unlockButton.addEventListener("click", () => {
  screen.orientation.unlock();
});

Can’t We Check Orientation With a Media Query? #

Yes! We can indeed check page orientation via the orientation media feature in a CSS media query. However, media queries compute the current orientation by checking if the width is “bigger than the height” for landscape or “smaller” for portrait. By contrast,

The Screen Orientation API checks for the screen rendering the page regardless of the viewport dimensions, making it resistant to inconsistencies that may crop up with page resizing.

You may have noticed how PWAs like Instagram and X force the screen to be in portrait mode even when the native system orientation is unlocked. It is important to notice that this behavior isn’t achieved through the Screen Orientation API, but by setting the orientation property on the manifest.json file to the desired orientation type.

2. Device Orientation API #

Another API I’d like to poke at is the Device Orientation API. It provides access to a device’s gyroscope sensors to read the device’s orientation in space; something used all the time in mobile apps, mainly games. The API makes this happen with a deviceorientation event that triggers each time the device moves. It has the following properties:

  • event.alpha: Orientation along the Z-axis, ranging from 0 to 360 degrees.
  • event.beta: Orientation along the X-axis, ranging from -180 to 180 degrees.
  • event.gamma: Orientation along the Y-axis, ranging from -90 to 90 degrees.

Browser Support #

Browser Support on Device Orientation API
Source: Caniuse. (Large preview)

Moving Elements With Your Device #

In this case, we will make a 3D cube with CSS that can be rotated with your device! The full instructions I used to make the initial CSS cube are credited to David DeSandro and can be found in his introduction to 3D transforms.

See the Pen Rotate cube [forked] by Dave DeSandro.

You can see raw full HTML in the demo, but let’s print it here for posterity:

<main>
  <div class="scene">
    <div class="cube">
      <div class="cube__face cube__face--front">1</div>
      <div class="cube__face cube__face--back">2</div>
      <div class="cube__face cube__face--right">3</div>
      <div class="cube__face cube__face--left">4</div>
      <div class="cube__face cube__face--top">5</div>
      <div class="cube__face cube__face--bottom">6</div>
    </div>
  </div>
  <h1>Device Orientation API</h1>
  <p>
    Alpha: <span class="currentAlpha"></span>
    <br />
    Beta: <span class="currentBeta"></span>
    <br />
    Gamma: <span class="currentGamma"></span>
  </p>
</main>

To keep this brief, I won’t explain the CSS code here. Just keep in mind that it provides the necessary styles for the 3D cube, and it can be rotated through all axes using the CSS rotate() function.

Now, with JavaScript, we listen to the window’s deviceorientation event and access the event orientation data:

const currentAlpha = document.querySelector(".currentAlpha");
const currentBeta = document.querySelector(".currentBeta");
const currentGamma = document.querySelector(".currentGamma");

window.addEventListener("deviceorientation", (event) => {
  currentAlpha.textContent = event.alpha;
  currentBeta.textContent = event.beta;
  currentGamma.textContent = event.gamma;
});

To see how the data changes on a desktop device, we can open Chrome’s DevTools and access the Sensors Panel to emulate a rotating device.

Emulating a device rotating on the Chrome DevTools Sensor Panel
(Large preview)

To rotate the cube, we change its CSS transform properties according to the device orientation data:

const currentAlpha = document.querySelector(".currentAlpha");
const currentBeta = document.querySelector(".currentBeta");
const currentGamma = document.querySelector(".currentGamma");

const cube = document.querySelector(".cube");

window.addEventListener("deviceorientation", (event) => {
  currentAlpha.textContent = event.alpha;
  currentBeta.textContent = event.beta;
  currentGamma.textContent = event.gamma;

  cube.style.transform = `rotateX(${event.beta}deg) rotateY(${event.gamma}deg) rotateZ(${event.alpha}deg)`;
});

This is the result:

Cube rotated according to emulated device orientation
(Large preview)

3. Vibration API #

Let’s turn our attention to the Vibration API, which, unsurprisingly, allows access to a device’s vibrating mechanism. This comes in handy when we need to alert users with in-app notifications, like when a process is finished or a message is received. That said, we have to use it sparingly; no one wants their phone blowing up with notifications.

There’s just one method that the Vibration API gives us, and it’s all we need: navigator.vibrate().

vibrate() is available globally from the navigator object and takes an argument for how long a vibration lasts in milliseconds. It can be either a number or an array of numbers representing a patron of vibrations and pauses.

navigator.vibrate(200); // vibrate 200ms
navigator.vibrate([200, 100, 200]); // vibrate 200ms, wait 100, and vibrate 200ms.

Browser Support #

Browser Support on Vibration API
Source: Caniuse. (Large preview)

Vibration API Demo #

Let’s make a quick demo where the user inputs how many milliseconds they want their device to vibrate and buttons to start and stop the vibration, starting with the markup:

<main>
  <form>
    <label for="milliseconds-input">Milliseconds:</label>
    <input type="number" id="milliseconds-input" value="0" />
  </form>

  <button class="vibrate-button">Vibrate</button>
  <button class="stop-vibrate-button">Stop</button>
</main>

We’ll add an event listener for a click and invoke the vibrate() method:

const vibrateButton = document.querySelector(".vibrate-button");
const millisecondsInput = document.querySelector("#milliseconds-input");

vibrateButton.addEventListener("click", () => {
  navigator.vibrate(millisecondsInput.value);
});

To stop vibrating, we override the current vibration with a zero-millisecond vibration.

const stopVibrateButton = document.querySelector(".stop-vibrate-button");

stopVibrateButton.addEventListener("click", () => {
  navigator.vibrate(0);
});

4. Contact Picker API #

In the past, it used to be that only native apps could connect to a device’s “contacts”. But now we have the fourth and final API I want to look at: the Contact Picker API.

The API grants web apps access to the device’s contact lists. Specifically, we get the contacts.select() async method available through the navigator object, which takes the following two arguments:

  • properties: This is an array containing the information we want to fetch from a contact card, e.g., "name", "address", "email", "tel", and "icon".
  • options: This is an object that can only contain the multiple boolean property to define whether or not the user can select one or multiple contacts at a time.

Browser Support #

I’m afraid that browser support is next to zilch on this one, limited to Chrome Android, Samsung Internet, and Android’s native web browser at the time I’m writing this.

Browser Support on Contacts Manager API
Source: Caniuse. (Large preview)

Selecting User’s Contacts #

We will make another demo to select and display the user’s contacts on the page. Again, starting with the HTML:

<main>
  <button class="get-contacts">Get Contacts</button>
  <p>Contacts:</p>
  <ul class="contact-list">
    <!-- We’ll inject a list of contacts -->
  </ul>
</main>

Then, in JavaScript, we first construct our elements from the DOM and choose which properties we want to pick from the contacts.

const getContactsButton = document.querySelector(".get-contacts");
const contactList = document.querySelector(".contact-list");

const props = ["name", "tel", "icon"];
const options = {multiple: true};

Now, we asynchronously pick the contacts when the user clicks the getContactsButton.


const getContacts = async () => {
  try {
    const contacts = await navigator.contacts.select(props, options);
  } catch (error) {
    console.error(error);
  }
};

getContactsButton.addEventListener("click", getContacts);

Using DOM manipulation, we can then append a list item to each contact and an icon to the contactList element.

const appendContacts = (contacts) => {
  contacts.forEach(({name, tel, icon}) => {
    const contactElement = document.createElement("li");

    contactElement.innerText = `${name}: ${tel}`;
    contactList.appendChild(contactElement);
  });
};

const getContacts = async () => {
  try {
    const contacts = await navigator.contacts.select(props, options);
    appendContacts(contacts);
  } catch (error) {
    console.error(error);
  }
};

getContactsButton.addEventListener("click", getContacts);

Appending an image is a little tricky since we will need to convert it into a URL and append it for each item in the list.

const getIcon = (icon) => {
  if (icon.length > 0) {
    const imageUrl = URL.createObjectURL(icon[0]);
    const imageElement = document.createElement("img");
    imageElement.src = imageUrl;

    return imageElement;
  }
};

const appendContacts = (contacts) => {
  contacts.forEach(({name, tel, icon}) => {
    const contactElement = document.createElement("li");

    contactElement.innerText = `${name}: ${tel}`;
    contactList.appendChild(contactElement);

    const imageElement = getIcon(icon);
    contactElement.appendChild(imageElement);
  });
};

const getContacts = async () => {
  try {
    const contacts = await navigator.contacts.select(props, options);
    appendContacts(contacts);
  } catch (error) {
    console.error(error);
  }
};

getContactsButton.addEventListener("click", getContacts);

And here’s the outcome:

Contact Picker showing three mock contacts
(Large preview)

Note: The Contact Picker API will only work if the context is secure, i.e., the page is served over https:// or wss:// URLs.

Conclusion #

There we go, four web APIs that I believe would empower us to build more useful and robust PWAs but have slipped under the radar for many of us. This is, of course, due to inconsistent browser support, so I hope this article can bring awareness to new APIs so we have a better chance to see them in future browser updates.

Aren’t they interesting? We saw how much control we have with the orientation of a device and its screen as well as the level of access we get to access a device’s hardware features, i.e. vibration, and information from other apps to use in our own UI.

But as I said much earlier, there’s a sort of infinite loop where a lack of awareness begets a lack of browser support. So, while the four APIs we covered are super interesting, your mileage will inevitably vary when it comes to using them in a production environment. Please tread cautiously and refer to Caniuse for the latest support information, or check for your own devices using WebAPI Check.