Shopify / ui-extensions

MIT License
260 stars 36 forks source link

Support for Extensions to talk to each other. #2231

Open edhgoose opened 1 month ago

edhgoose commented 1 month ago

Please list the related package(s)

checkout-ui-extensions

If this related to specific APIs or components, please list them here

Outside Shopify, I'd use window.postMessage.

Is your feature request related to a problem? Please describe.

We have an extension which our clients can install. We would like the same extension to exist for all of them (i.e., we don't want to customise the extension for each client as we'd have to maintain very many code bases).

In the pre-extension world, we would:

  1. Load an iframe in a popup
  2. Let the user do something (interact with our UI)
  3. Send a window.postMessage event to the parent window on completion

The client could listen for this postMessage and then do something.

For instance, the popup may give the user a coupon code and we would expose that coupon code to the client's JavaScript which in turn could have something done to it (e.g. maybe they want to record it in their analytics somehow, or maybe they want to modify the code before applying it to the checkout).

The model was very flexible, and we publicised the code so clients could do whatever they wanted. For instance, displaying different UI could also be part of it.

Furthermore, we would like to be able to read data from our clients about their customers. For instance, details about a customer such as whether they are a VIP customer, or whether they belong to a membership or loyalty program. Different customers may store this data in different ways (e.g. some may use a tag, some may use a meta field, some may have it via an API to a 3rd party, etc).

In the current version (pre extensions) of Shopify a basic JavaScript section is available in the "Additional Scripts" section, or JavaScript can be added into the checkout.liquid. This means that data can be retrieved and transformed using any JavaScript before being given to our JavaScript tags.

In the new extensions, we cannot determine a standardised way to allow clients to pass that data to us. We would like a way for them to implement custom code which they can post to us in our extension.

Describe the changes you are looking for

We would like an API similar to window.postMessage, which we could use to send events to other extensions that they could listen to.

The API would allow an object (JSON) to be sent from one extension to another.

The API would include a way to listen to events from other extensions too. (e.g. window.addEventListener("message", (data) => {});

Bonus points if we can determine whether any extensions are listening for our events - rather than the "fire and forget" model that window.postMessage has. (e.g. if we know an extension is listening, we might change the behaviour of our app).

I expect there may need to be some sort of "wait" component to it as well - e.g. extensions I imagine load asynchronously and so finding a way to determine which extensions are loading and which extensions have sent their data may be important.

Describe alternatives you’ve considered

I note there's an attributes API - https://shopify.dev/docs/api/checkout-ui-extensions/unstable/apis/attributes, but this doesn't work on accelerated payment methods. I'm also not sure this is suitable as we're looking to apply a blob of JSON rather than a string. It's not clear if there is a limitation on what the strings can be here. Perhaps if this model was available in all checkout types this might be a viable option, but I'd love to see some documentation on how you'd recommend doing this.

I've also considered the analytics API - https://shopify.dev/docs/api/checkout-ui-extensions/unstable/apis/analytics - but this seems to only send data to other WebPixels, not to other extensions.

Lastly, I've considered allowing users to write custom JavaScript code in our admin panel which is then dynamically loaded using eval in our extension.

This seems like a good way to shoot myself in the foot, and I am uncertain from exploring Shopify's documentation whether the availability of eval in an extension is a deliberate choice or not. I do not know if it will be removed.

Additional context

I believe this will make the interaction between different marketing tools much more seamless and successful. Given many of our clients use very many marketing tools, I believe this will aid interoperability.

edhgoose commented 1 month ago

An example that came up today - a client wants to A/B test two extensions. One from Company A and one from Company B. There isn't a way for us to programatically decide to show one or the other.

I think you'd have to make an extension that is composed of the two extensions to make it work?