reactioncommerce/example-storefront

Checkout flow not functioning as expected when running in local production mode

jrw421 opened this issue ยท 12 comments

Type: major

Describe the bug
When running the app locally in production mode the example-storefront checkout flow does not function as expected. When the user has placed items in their cart and clicks checkout, the items are removed from the cart preventing the user from checking out. Additionally the language switches to German (this behavior is not consistent). However, hovering over the cart prior to clicking it shows the items in the cart as expected. After exiting the cart page, the on hover behavior of the cart once again shows the correct orders. This issue is only seen in production mode run locally.

To Reproduce
Steps to reproduce the behavior:

  1. Start the app locally in production mode (make).
  2. Ensure that you have a payment method enabled and have a shipping method listed in the admin portal.
  3. Log into the example storefront.
  4. Add items to cart if your cart is empty. You should be able to hover over the cart icon and see the popup appear as expected with the items in your cart.
  5. Click on the cart icon.
  6. You should see "Your shopping cart is empty" and the language will now be German. On hover of the cart icon it should also say "Your shopping cart is empty".
  7. Click "Continue shopping".
  8. This should redirect you to the home page, where you should see the cart icon display the number of items in your cart correctly.

Expected behavior
The expectation is that when a user clicks the cart they will be redirected to the checkout view and will successfully see the items they have added to their cart, in addition being able to successfully check out.

Screenshots
Screen Shot 2021-01-19 at 4 19 06 PM

Desktop (please complete the following information):

  • OS: Catalina
  • Browser: chrome, safari
  • Version 10.15.7

Additional context
This issue has been reported by a few different users with V4.0.0 for example-storefront and V3.11.0 for Reaction.

I ran a lot of experiments on this one and this is what I could narrow it down to:

  1. If you make a local image from storefront, while you have the reaction api running on localhost:3000 and use this image, the bug is not there.
  2. If you make a local image from storefront, while reaction api is not running and use this image, the bug is reproducible.

This leads me to believe that the SSR that next is generating is missing something that is needed from the reaction api call.

Regarding the language:
This is probably due to the fallback here in the serverside browser language detection:

const fallback = "de";

This could however soon be made obsolete by just using the i18n routing nextjs now provides out of the box, which would reduce boilerplate overall.

There seems to be no specific cart-related bug here, the underlying way the pages are built currently requires the api to be active and reachable, this is relevant for all pages that use shop data.

Hi @Akarshit!
For example, take a look at how the product detail page currently does it:

export async function getStaticProps({ params: { slugOrId, lang } }) {
const productSlug = slugOrId && slugOrId[0];
const primaryShop = await fetchPrimaryShop(lang);
if (!primaryShop) {
return {
props: {
shop: null,
translations: null,
products: null,
tags: null
},
// eslint-disable-next-line camelcase
unstable_revalidate: 1 // Revalidate immediately
};
}
return {
props: {
...primaryShop,
...await fetchTranslations(lang, ["common", "productDetail"]),
...await fetchCatalogProduct(productSlug),
...await fetchAllTags(lang)
},
// eslint-disable-next-line camelcase
unstable_revalidate: 120 // Revalidate each two minutes
};
}

(BTW nextjs should be updated soon, revalidate is stable for some time)

The cart page and some other pages currently lack a directive to revalidate and stick with the built time vars.
To remove boilerplate and have that check to skip on build time, revalidate and so on, the getStaticProps logic could also be generalized in one util which then gets reexported per page.

@janus-reith I tried the above approach. The behavior I got was a little weird. Here is what's happening if I use unstable_revalidate:

  1. During the build I get the cart page without the shop. So it's the empty cart page.
  2. When I visit the cart page for the first time, I get served the empty cart page. At this point next start building the new page which would have the shop.
  3. If I refresh, I still get the empty cart page, because next hasn't finished building the page yet.
  4. If I refresh again(and the page was built), I get the cart page with shop and everything works.

I am pretty sure we don't want this behaviour.

@Akarshit No, we most probably don't, the initial intention was to have the api reachable during build of these pages.
However, as that was not an option for everyone, this workaround above was created, which as you already noticed has some drawbacks, as it still serves the empty build-time page on first request, initiating a rebuild in the background.

See my post here: #718 (comment)
This could be a feasible approach that would not need to serve the stale build-time page upon first request.

@janus-reith Yeah, your example works fine. But one slight problem is that I tried to find documentation for it and can't seem to find anything that would suggest to use notFound the way you are doing. Everywhere it says to just use it to return a 404 page.
I am a bit skeptical about using that. If I have missed some resource, do you mind pointing me to it?

@Akarshit No, I did not find documentation that states how notFound behaves when returned on build time. It's not behind an _unstable flag so I'd not expect it to change much, but we could just ask them to confirm that the current behavior is intended and meant to stay this way.

Not closing this one, as I still want to followup with next folks and see if we can get a better solution.

Hey, community!

We had the same problem with the checkout flow, so we recorded a video (that reproduce the issue).

This is E-commerce that was built with the project, example-storefront:4.0.2, using instances on compute engine and cloud dns (i.e. Google Cloud Platform).

Also, when the user clicks on the checkout, the cart is empty and changes the path language (e.g. The user was on the path "/en", then the checkout path was changed to "/de".

I hope to give you some help.