I like to drink good wine, itās one of my favorite drinks. Also, Iām a huge fan of Vivino app. If you donāt know it is an awesome app with a big collection of wine reviews. This collection is that big, so I couldnāt find a wine that wasnāt registered in Vivino.
Also, I live in Sweden. Thereās only one retail store allowed to sell alcoholic beverages, itās called āSystembolagetā. Usually, I go there, start taking a photo of every available wine and after ~20 minutes I choose some. Yeah, I look like an idiot, but always choose a good wine. Recently I thought maybe thereās a way to optimize the process of choosing the right wine?
Systembolaget has a very nice website and webshop. You can look what is available to deliver or can be picked up in the nearest store. But thereās no Vivino score or at least reviews from other buyers.
Vivino has a web version of app as well. Thereās no possibility to scan labels via photo, but itās not needed actually. You can just search for wine by name and find more details. Unfortunately, you canāt filter wines that available in the nearest Systembolaget. Of course, you can copy-paste the name, but itās even more annoying than taking a photo of every wine in the store.
āChallenge acceptedā - I said and started to think about how to integrate Vivino score into Systembolaget website.
It was obvious that I needed to create some chrome extension to achieve that. After some research, I concluded that Vivino doesnāt have any public API and has no alternatives. So I started to think about how can I use their website for my needs.
The answer was simple - just use the search functionality. Make a request, parse HTML using cheerio and extract the info. Quite simple!
But as always - everything is not as simple as it seems. CORS š”. Due to security reasons, you canāt make cross-origin requests from content scripts. But thereās another way to do it - fetch URLs via background script as advised here
Ok. I can extract information from Vivino by name, how to add this info to Systembolaget website. I looked to the markup, found some places where I can attach Vivino score ā¦ and itās working! wow!
Then I scrolled down and realized they have a lazy-loading mechanism on a wine list. Ok - just add MutationObserver and append Vivino score after the list item is loaded. Unfortunately, it didnāt work. Maybe Iām stupid and missed something or thereās some magic in their app - but MutationObserverās callback didnāt want to be executed. My theory is because of using React, it recreates DOM nodes and doesnāt attach MutationObservers to a new one. But Iām not sure, Iām not an expert at such low-level things, itās just my theory.
I came up with a simpler solution - just attaching scores on list items on a scroll. I also applied debounce
to achieve better performance.
Another thing for better perfomace is cache. I used axios-cache-adapter for cache mechanizm itself, and localForage with localforage-webExtensionStorage-driver to store this cache in extensionās local storage.
Hereās the screenshot how it looks like:
Source code is available here