User personalization is the delivery of content and functionality that fits a user’s wants and needs, without any effort required by the user.
“The term “eCommerce personalization” relates to the set of practices in which an online store displays dynamic content based on customer data, such as demographics, intent, preferences, browsing history, previous purchases, and device usage—for instance, whether the customer is shopping on a mobile, tablet, or even a smartwatch.” - Magnolia CMS
Providing your users with a seamless, tailored experience helps with:
Offering a “dark mode” is proven to reduce bounce rates and retain visitors. Typically, a visitor’s site preferences are stored in session or local storage which does not persist between browsing modes (normal and incognito).
Browsing fingerprinting allows websites to remember anonymous visitor preferences regardless of a visitor’s browsing mode.
linkedId
in Fingerprint requestlinkedId
on app launch using the server APIDemo: Storing Anonymous Browsing Preferences Using Browser Fingerprinting
Case Study: How Terra improved user engagement thanks to Dark Mode
Apps like Airbnb display content based on time to return visits, such as days or weeks later. An example of this is Mozilla's Geolocation API.
Persistent items in a visitor’s shopping cart can reduce sales lost to shopping cart abandonment. Remembering shopping carts days up to weeks can also decrease checkout time for return visitors.
visitorId
”visitorId
Saving product purchases and browsing history can help drive sales from return visitors. Typical cookie-based solutions, fortunately for everyone, do not work when a visitor switches from normal to private browsing mode (or vice versa). We can solve this problem with browser fingerprinting.
Article: 56% of shoppers more likely to return a site that recommends products
Running e-commerce promotions without user verification is risky and prone to abuse. Traditional methods of verification require signing up for email or phone number marketing lists. Fortunately, we can streamline the verification process without the user knowing. A stable and unique identifier is great for assigning promotions to anonymous visitors and preventing duplicate promotion abuse. Furthermore, promotions can be uniquely applied based on certain visit behavior, i.e. return visits.
Fingerprint Pro provides a unique identifier for every visitor to your website (the visitorId
) collected behind the scenes anytime someone performs a specific action with our JavaScript fingerprinting agent installed. Since the client-side data might be forged, Fingerprint Pro also provides tools for validating these identifiers sent by your front end. As a result, you can provide your users with a tailored experience between incognito and normal mode even without cookies.
Since you know your product and business landscape best, it’s up to you to decide how to configure personalization workflows to utilize the visitorId
to improve user experience. Below, we have described some steps and best practices to use as a starting point for your custom solution.
We recommend that when a new user requests your site content, the visitorId
and requestId
are sent to your application server. Using this data, you can return personalized content such as search history, customized user interface, or even the user’s shopping cart.
At first, you need to obtain visitorId
and requestId
from Fingerprint Pro. Then, for the specific content that should be personalized, such as shopping cart, search queries, or dark mode, send these pieces of information within your request, persist necessary data if needed, and provide personalized content. Here are a few steps to provide these features to your users.
To start, you need to add the Fingerprint Pro JavaScript agent to your webpage. Alternatively, if your frontend uses modern frameworks such as React.js or Angular, one can use one of our libraries instead.
// Initialize the agent
const fpPromise = import('https://fpjscdn.net/v3/your-public-api-key')
.then(FingerprintJS => FingerprintJS.load({
endpoint: 'https://metrics.yourdomain.com'
}));
// Once you need result, get and store it.
// Typically on page load or on button click.
fpPromise
.then(fp => fp.get())
.then(fpResult => { result = fpResult })
The endpoint
property is quite important and is used for the custom subdomain setup. Using a subdomain is required for correct identification while using Fingerprint Pro.
Send the user's visitorId
and requestId
to your servers when requesting shopping cart content.
To get the user’s cart content on the server side, use similar code to the following.
// Returns cart items for the given visitorId
const cartItems = await UserCartItem.findAll({
where: {
visitorId: {
[Op.eq]: visitorId,
},
},
order: [['timestamp', 'DESC']],
include: Product,
});
return res.status(200).json({
data: cartItems,
size: cartItems.length,
});
To add an item to the user's shopping cart, update cart items for the given visitorId
.
// Adds an item to cart for the given visitorId
const [cartItem, created] = await UserCartItem.findOrCreate({
where: {
visitorId: {
[Op.eq]: visitorId,
},
productId: {
[Op.eq]: productId,
},
},
defaults: {
visitorId,
count: 1,
timestamp: new Date(),
productId,
},
});
if (!created) {
cartItem.count++;
await cartItem.save();
}
return res.status(200).json({
data: cartItem,
});
Send the user's visitorId
and requestId
when getting search history.
// Get user search history for given visitorId
const history = await UserSearchHistory.findAll({
order: [['timestamp', 'DESC']],
where: {
visitorId: {
[Op.eq]: visitorId,
},
},
});
return res.status(200).json({
data: history,
size: history.length,
});
Similarly, to update the user's search history, use the following code to persist or retrieve the search history for the specific visitorId
.
// Persists search query for given visitorId
const existingHistory = await UserSearchHistory.findOne({
where: {
query: {
[Op.eq]: query,
},
visitorId: {
[Op.eq]: visitorId,
},
},
});
if (existingHistory) {
existingHistory.timestamp = new Date().getTime();
await existingHistory.save();
return;
}
await UserSearchHistory.create({
visitorId,
query,
timestamp: new Date().getTime(),
});
Analogically, you can get or set other users' preferences such as user interface dark mode.
To get or set user's preferences according to their visitorId
:
// Updates user preferences for given visitorId
const { hasDarkMode } = JSON.parse(req.body);
const hasDarkModeBool = Boolean(hasDarkMode);
const [userPreferences, created] = await UserPreferences.findOrCreate({
where: {
visitorId: {
[Op.eq]: visitorId,
},
},
defaults: {
visitorId,
hasDarkMode: hasDarkModeBool,
},
});
if (!created) {
userPreferences.hasDarkMode = hasDarkModeBool;
await userPreferences.save();
}
return res.status(200).json({
data: userPreferences,
});
visitorId
and requestId
provided by the Client SideSince data such as visitorId
and requestId
provided by the client-side might be spoofed, it's a good practice to check and validate provided data with our Server API or Webhooks. If some validation fails, we recommend serving default content instead. Take a look at the source code for more advanced validations or check recommended approaches for the Payment Fraud use case.
We have a Personalization demo to demonstrate the above concepts. Use the demo to visualize using Fingerprint Pro in conjunction with simple logic rules provides a tailored experience to your users. If you want to explore code, check our interactive Stackblitz demo or open-source GitHub repository. If you have any questions, please feel free to reach out to support@fingerprint.com.
Fingerprint’ open source technology is supported by contributing developers across the globe. Stay up to date on our latest technical use cases, integrations and updates.