Architecture Design to Support Feature Introduction within Resilia App
by Amanda Huang and Taihua Rubin, Software Engineers @ Resilia — Our goal is to make onboarding easy and increase product adoption and retention.
Resilia’s tech team has been hard at work building out features such as Impact Initiatives, Stories, and Funder Finder to help our nonprofit customers build capacity and have more time to focus on their mission. We’re excited to see all the ways our customers use these new tools and decided to focus on making sure that each of these tools is simple to understand and seamless to get set up.
The engineering team’s mandate was to work with product and design to set up an architecture that would allow us to easily add feature introduction to Resilia’s tools in the form of a side guide with steps and contextual tips as users navigate through the tool.
We started out evaluating some third party tools that provide personalized user onboarding, but found they didn’t fit our use cases. It would have been easy to jump into development at this point adding the guide and tips to one of our tools. We decided to prioritize spending extra time with product and design to come up with an architecture that could work across many of our tools while having customization where we needed it.
As engineers we focused on two things to help us achieve this:
- Creating a configuration that could be filled out by product so it was very clear which parameters they could customize
- Designing reusable React components and state management that would make it easy to add this functionality to many places in our app
Feature Introduction Guide
Configuration
First we worked with product to fill out the configuration for the guide. This is where all the customization for the specific tool occurs. The product manager can specify the following:
- Title and description of the tool
- Steps to get started, including what action a user needs to take to complete each step (based on Segment analytics events)
- Relevant resources pertaining to the capacity building concept the tool is meant to help with
State Management
For the guide we decided to use a combination of a custom hook and a reusable component in order to be able to easily add it to different Resilia tools. The useGuide hook handles state about the drawer status (dismissed, minimized, expanded) and makes backend calls to retrieve data about what actions a user has performed.
Component
The <GuideComponent /> takes in state props returned from the useGuide hook as well as configuration which is specific to the tool it’s being added to. It renders the steps to get started and determines which ones have been completed. It also renders helpful resources specified within the configuration.
User Interface
Below the guide appears in context within the Initiatives tool to act as a reference as the user is navigating around. The guide keeps track of which steps have been completed by the user. The user can minimize the guide or dismiss it completely if they no longer need it.
Feature Introduction Tips
Configuration
Similar to the Feature Introduction guide, we also have a configuration where product can specify the content of each feature introduction tip, and let us know the open and close triggers for each tip. These tips correspond with the guide; they are there to hold our users’ hands through each significant step while the guide’s “Steps to Get Started” section provides a rundown list of tasks they can accomplish to effectively use the tool they’re on.
Event Based Rendering
Since we only want our users to see these tips once, we have set up analytics events for when our user sees each tip. After that, a custom hook is used to pull from our database to see whether such analytics events already exist for the user before we display the tip on the screen.
State Management
On top of that, we also only want to show one tip at a time. At the parent component, we set a state for whether the tips are active, and that state is available to all child components in the page. When a tip shows, we want the guide to minimize, and vice versa. A function called “tipOnAndOffHandler” is implemented, and it takes in a tip’s id, and a boolean for whether we are turning it on or off.
Components
There are two kinds of tips. The contextual tips point the user where to take action and the celebration tips give the user confetti to reward them for completing a task. The main difference when it comes to implementation is that the contextual tips need to be anchored on another element, while the celebration tips display on the bottom of the window.
Two types of reusable React components to handle two types of Feature Introduction tips:
- Contextual tip component is a React wrapper component. It takes in children elements as a prop. Inside the component, the children elements are wrapped inside Material UI’s Tooltip to allow anchoring the tooltip on the children. When the tooltip’s state (see the state management section) is active, we render the tip along with the children elements, and when it’s inactive, only the children elements will be rendered.
In the user interface section, you can see that the contextual tip is anchored on the “Add Data” button. When placing the contextual tip component across our code base, all we have to do is to wrap it where we want it. Very Convenient.
<ContextualTipComponent tipContent={contentFromConfig}>
{children}
</ContextualTipComponent> - Celebration tip component is very similar to the contextual tip component, except that it does not need to be wrapped around any children elements. It follows the pattern of the contextual tips, and only renders when the state management tells it that it’s active. <CelebrationTipComponent /> is placed on the bottom of the page. A Material UI Popover is wrapped by another Popover to allow the tip to have a “background picture”. Party.js is used to enable the confetti view. 🎉
User Interface
Next Steps
To measure the success of feature introduction, our product team has narrowed down areas where tracking for customer activity is necessary. We have implemented event tracking through Segment’s track call, while our data and product team worked on putting together an analytics funnel to help us all understand changes in activation rate and high value actions performed by users.
We hope these steps and the insights they bring will allow us to better understand how we can best provide our users with actionable steps and empower them to continue utilizing Resilia’s platform to build capacity for their organizations.