Shopify / ui-extensions

MIT License
268 stars 36 forks source link

useBuyerJourneyIntercept impossible to know what triggers it. #1219

Open tommypepsi opened 1 year ago

tommypepsi commented 1 year ago

Please list the package(s) involved in the issue, and include the version you are using

"@shopify/ui-extensions": "2023.7.0", "@shopify/ui-extensions-react": "2023.7.0"

Describe the bug

Currently it is impossible to know what is triggering the intercept. The issue that this cause is that if you are trying to block the checkout based on an information selected on a later step, you might not be able to make the correct decision about blocking or not the checkout.

Another example we encountered was about adding a third party gift card system. We needed to intercept when the user is trying to complete the order to lock the amount used on the third party gift card. Since we couldn't detect that particular step we had to go with another less ideal solution.

Steps to reproduce the behavior:

For example if you are trying to block the checkout if the selected shipping method is "standard", when you are on the information step you will get that the selected shipping method is "standard" but the user is not yet at the shipping method step so you wouldn't want to block the checkout yet. You would want to wait at least the shipping method step to block but right now it is now possible to know.

Expected behavior

I would expect some kind of property coming from the intercept telling us what is triggering the intercept.

Something like that:

useBuyerJourneyIntercept(({
  interceptLocation
}) => {
  if (interceptLocation != "information") {
    return {
      behavior: 'block',
      reason: 'Blocking from a step after the information step',
    }
  }

  return {
    behavior: "allow"
  }
}
tommypepsi commented 1 year ago

A not so ideal solution that I managed to implement:

Instead of using a single static extension in the summary, I changed the extension to be a dynamic one that will need to be added on each step of the checkout. I also added a setting to the extension:

[extensions.settings]
  [[extensions.settings.fields]]
    key = "step"
    type = "single_line_text_field"
    name = "Checkout step"
    description = "Make sure to add this extension on each step of the checkout and set the corresponding step here. For shop pay, only activate the block that is on the payment step."

    [[extensions.settings.fields.validations]]
      name = "choices"
      value = "[\"information\", \"shipping\", \"payment\"]"

So the user will need to add the extension on each step and make sure to specify the corresponding step in the settings.

In the code I added something like that:

const TEST_STEP = 'shipping';
const checkoutSteps = ["information", "shipping", "payment"];
const checkoutStep = settings.current.step || TEST_STEP;
const checkoutStepIndex = checkoutSteps.indexOf(checkoutStep);

So now I can do something like:

if (checkoutStepIndex >= 1) {
  console.log("on shipping step or after")
}

This works but makes it hard to test locally as you can only test one target at a time.

FiliSantillan commented 8 months ago

The proposal you show in the top is perfect, in my case I had to use static targets, this way I make sure that the component reacts to t he user's interaction.

Have you tried using a react hook? How does useDeliveryGroup to know where the user is located or some other API?