panoply/spx

page reload

haroldao opened this issue ยท 2 comments

Hey ๐Ÿ™Œ๐Ÿฝ. I want to know why sometimes the page is reloaded when we click on a link (on your webshop) ?

Hey, try give me some more context? It might be triggering a hydrate and automatically converting to your currency. Generally speaking the webshop will cache pages on pointer events.

So I think you are referring to the reload which occurs on a non-pjax visit navigation. What's happening here as I mentioned in previous comment is that we are executing an automated currency conversion behind the scenes, but whatever the case I thought I'd outline a couple of potential reasons for this.

Hard Navigation

In our webshop, we typically rely on Pjax to handle navigation, the only page we disable (for what I remember) is the logo href wherein a normal visit is triggered.

Pre-visits

You might be referring to pages being visited when you hover over a link of some type (ie: href). If you are referring to this specifically then that is not actually a reload, it's a request and rather a feature provided by this pjax variation. What's happening here is that XHR visit is being triggered and the page is being saved into a cache where it will live up until a full page refresh is trigger. Whenever a visitor clicks on the href the page is retrieved and a target elements content is swapped. This gives the impression of an instantaneous navigation.

Currency Conversion

I think you are referring to this, so I will explain a little bit about what is going on here. Shopify does not support automated currency conversion for merchants that do not use Shopify Plus. Merchants on other plans (like us) will typically need to rely on customers (visitors) to change into their local currencies manually by selecting from a list of other currencies. This can be somewhat problematic especially in e-commerce because anything that will divert a customers attention elsewhere may result in loss of sale.

Think of it like this, imagine you were to walk into a brick and mortar (physical) store and the moment you entered someone come up to you, handed you a piece of paper with a list of different currencies and asked you mark what currency you will buying in. Most people would likely walk straight out, it's intrusive. This, among other things can be a very disruptive to any online store and while a lot of developers and store owners rely on apps to handle automated conversion none are really capable of supporting this but its possible to do, let me explain.

In order for us (or anyone) to provide automatic currency conversion and localisation to visitors I employ an approach that will trigger the conversion and localization without interrupting the customers browsing experience (ie: not asking them to choose). The reload you observe from the inspector is actually just an XHR request that is reloading the page in the background. That request which is fired is setting the stores currency. Here is the process:

  1. Visitor enters the store
  2. We trigger a GeoIP query to determine where the visitor is from client side.
  3. The geoip will return an ISO country code and currency respectively, eg: NL (eg: Netherlands)
  4. The ISO code is used to retrieve some locale information which includes the currency code of the country.
  5. At this point we have the visitors country and their currency code (among other things)
  6. We fire a POST request to the cart update endpoint with a payload value of {currency: "EUR"}
  7. This cart endpoint will actually convert the stores currency and return a 302 redirect (Shopify handled this)
  8. The 302 looks something like this /services/currency/update?currency=EUR&country=NL&return_to=
  9. Pjax will intercept and hydrate the current page then add it to the cache

The result is automated conversion and the customer is able to shop in their native currency without having to manually perform this action. Another key fundamental in this process is the dynamic conversion. This conversion process is actually ran client side and requires rounding rate context which we leverage in response to some different actions, keep in mind that though this in unrelated to your question per-say, it does somewhat correlate to how and why that reload is executed.

The algorithm Shopify uses for currency conversion and rounding is applied at either the decimal (cents) point of a number or the dollar point. It will vary depending on the price of your base (shop) currency. For example, converting into KRW (South Korean Won) from a base currency like SEK (Swedish Krona) will be round off at the dollar point. Let's say hypothetically the SEK to KRW exchange rate is 130.45. If you are rounding to the 1000 KRW position, Shopify will ceil the value, for example:

  • SEK price is 1,000
  • KRW price will be 130,449.99999999999
  • Rounded price will be 131,000

In order to achieve that conversion you will need to process the product price post-convert, but you will also need to know the conversion rate to exchange at. Relying on automatic rates (the Shopify default) is not really smart, instead I think it's best to manually define rates imo. When it comes to the dynamic conversion operation, there are many ways you can do this but the sake of brevity, here is one really messy way:

const price = 1000
const n = num => Number(num)
const s = num => String(num)
const p = price * 130.45;
const [ d, c = '0' ] = s(p).split('.');
const v = n(c[0]) > 0 ? Math.ceil(p) : d

return  (v + (price - n(s(v).slice(-3))))

In the code example the 1000 will need to be passed (the price) and you would also need reference to the KRW exchange rate of 130.45. Both of which are rather easy to acquire and provide to your webshop. We actually do this here at BRIXTOL statically when we are mapping the ISO country code. The object we map contains the manual rates and many other locale specific information, such as Country name, Continent, Shipping costs and much more. By having that available at runtime we can easily execute dynamic conversion and then trigger the background conversions via this Pjax, from here, hydrate and also cache. Those operations along with the dynamic exchange will ensures that customers are presented the correct currency when entering checkout, ie: the one we dynamically converted without ever having the customer manually define it.


I apologize if this did not answer your question and it diverted off topic a bit but from my experience very few developers, including "engineers" employed by Shopify don't necessarily seem to understand these aspects. When I was 18, I wish someone may had explained it to me. Anyway, hope it helped.

Have a great weekend.