Have you ever had some new functionality that you would like to showcase for your users? Perhaps your userbase is not the most tech-savvy and they need some guiding when new features are shipped. React Joyride let's you easily create guided tours that your users will enjoy.
3 min read
·
By Sindre Moldeklev
·
December 7, 2021
Let's face it, your users are probably not as tech-savvy as you are. When we develop new functionality for our intended users, it can be easy to take the functionality for granted and just assume that everyone knows how the new features work. With React Joyride we can easily create guided tours for our users, and let them know about new features and how they are to be used.
To get started, we need to install React Joyride as an dependency
npm i react-joyride
We then have to setup our steps for the ride, and hook the steps up to our components. I like to create a new file for our steps called steps.js
// joyride/steps.js
export const steps = [
{
target: "[data-joyride=favourites]",
content: "Here you will get a glimpse of your favourites"
},
{
target: ".add-favourite-btn",
content: (
<div>
<h1>You can add a new favourite with this button</h1>
<p>Adding a new favourite helps you not forget your favourites</p>
</div>
)
}
];
When the steps has been created, we import the steps and add it to the Joyride component in our app
import Joyride from "react-joyride";
import { steps } from "./joyride/steps"; // Import steps
export default function App() {
return (
<div className="App">
<Joyride steps={steps} run continuous /> // Add to Joyride component
<h1>Christmas music</h1>
<h2>Your favourites</h2>
<ul data-joyride="favourites" className="favourites-container">
{favourites.map((fav) => {
return (
<li key={fav.name}>
<div className="favourite">
<h3>{fav.name}</h3>
<img
className="favourite-image"
src={fav.image}
alt={fav.name}
/>
</div>
</li>
);
})}
</ul>
<button data-joyride="addFavourite" className="add-favourite-btn">Add another favourite</button>
</div>
);
}
And that is it!
Here is a working example in Codesandbox
Having a guided tour is nice, but seeing the same tour every time we load a page will annoy your users. As a bonus I will show you how you can use local storage to keep track of which steps your users has seen in your application.
First we will create a function to read from local storage
const JOYRIDE_LOCALSTORAGE_KEY = "joyride-guiding";
function getLocalstorage(): JoyrideTours {
const stored = window.localStorage.getItem(JOYRIDE_LOCALSTORAGE_KEY);
if (!stored) {
return initialState;
}
try {
return JSON.parse(stored) as JoyrideTours;
} catch (error) {
return initialState;
}
}
This function will let us fetch the item stored under the joyride-guiding key. As I am using Typescript, I tell the code that when I return JSON.parse
, the type returned will be of type JoyrideTours
.
We will also need a function to store some state in local storage
function saveToLocalstorage(tours: JoyrideTours) {
window.localStorage.setItem(JOYRIDE_LOCALSTORAGE_KEY, JSON.stringify(tours));
}
Here I just stringify the object tours and save them to the key JOYRIDE_LOCALSTORAGE_KEY
in local storage.
Finally, we need to be able to listen for the callback event from the tour. We will do that with a new function, connected to the callback-property from the Joyride component
function handleJoyrideCallback(callback: CallBackProps, page: Pages) {
const { status, action } = callback;
if (status === STATUS.FINISHED || action === ACTIONS.CLOSE) {
const tours = getLocalstorage();
const saveTours = { ...tours, [page]: true };
saveToLocalstorage(saveTours);
}
}
// Component below is what we will render with React
<Joyride
callback={(e: CallBackProps) => { // Here we can call our own function with whatever data we want
handleJoyrideCallback(e, "my-page");
}}
/>
In this last block of code, we define a function handleJoyrideCallback
which takes a callback from Joyride, as well as our own defined page variable. We then check wether the status is equal to STATUS.FINISHED
or ACTIONS.CLOSE
, and if they are, we store in local storage that the user has seen the page we provided.
The final piece of the puzzle is to not run the tour if the user has already seen it. Otherwise they will get annoyed. To accomplish this, we do as follows
const tours = getLocalstorage();
<Joyride
run={!tours.page} // If the user has not seen tours.page, we run, otherwise don't run
callback={(e: CallBackProps) => {
handleJoyrideCallback(e, "tilbakemelding");
}}
/>
We get the tours from our local storage, and simply check if the page the user is requesting has not been seen. If not we run the joyride tour, otherwise we do not run it.
And there you have it, a rather simple implementation of how to make guided tours in your application. Quick and easy.