For discussing the development and usage of Checkout UI extensions, post-purchase extensions, web pixels, Customer Accounts UI extensions, and POS UI extensions
Hello,
I'm exploring Checkout Extensions - I have a use case where we want a custom checkout extension to show on Desktop but we do not want it to show on Mobile (because it feels too crowded and distracting).
Is there a way to target checkout extensions only for desktop or mobile?
e.g. what is the equivalent approach of:
@media screen and (max-width:749px) {
.checkout-bar-thing {
display:hide;
}
}
I can't find this in the docs but maybe I'm looking in the wrong place. Thank you.
We have the same question. It looks like there's a `Layout` API for admin UI extensions: https://community.shopify.com/c/extensions/checking-if-extension-editor-is-in-mobile-or-desktop-view...
But I don't see anything for checkout UI extensions. Will something become available? Or are we missing something in the docs?
Hi Sdevscotland,
I've connected with the product time on this, and it does seem that Checkout Extensions don't have a built-in feature to prevent loading based on screen size. Extensions should be designed to be responsive and work across all device sizes. There is no equivalent to a media query that can be used to prevent an extension from rendering on mobile screens.
Liam | Developer Advocate @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Hi Liam,
I appreciate you checking on this and clarifying, thanks! - For the product team if they read this: my use case is for discount/loyalty apps - on some device sizes repeating those blocks is useful to remind customers to apply their points etc, others it is just distracting/overwhelming.
Hey Liam, I also appreciate your response. I have a follow-up question: You said, "Extensions should be designed to be responsive and work across all device sizes" -- is there a way to detect inside a checkout UI extension what size the window is? That would be the only way to make the extension responsive, right? That's what we're looking for -- a way to detect the window size inside a checkout UI extension. I'm pretty sure the `window` object is `undefined` in checkout UI extensions, and I didn't see a Shopify API for them that would expose the window size separately.
Hi Ezekielp,
It's not possible to access the `window` object from within checkout extensions unfortunately.
Liam | Developer Advocate @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
Understood. Thanks for clarifying, Liam
Liam,
Good morning! And thank you as always for your help here.
"I've connected with the product team on this, and it does seem that Checkout Extensions don't have a built-in feature to prevent loading based on screen size...There is no equivalent to a media query that can be used to prevent an extension from rendering on mobile screens"
When convenient, can you please confirm - did the product team happen to communicate whether or not this is on the roadmap? Confirmed that this has been requested by a few of our merchant partners.
I figured out a work around for this by using the StyleHelper along with the <BlockLayout> component. My task was to create a banner that was only visible on mobile. I imagine something similar could be achieved with other components, but this solution below worked for me...
function Extension() {
return (
<BlockLayout
rows={Style.default([60]).when(
{ viewportInlineSize: { min: 'medium' } },
[0]
)}
>
<View overflow="hidden">
<Banner title="mobile-order-summary-reminder"></Banner>
</View>
</BlockLayout>
);
Basically, if the screen is larger than "medium" make the single row 0px in height, otherwise make it 60px. Giving the <View> component `overflow="hidden"` is important to avoid wonky-ness.
Hope that helps!
This is a good workaround, but sadly, when hidden, it'll keep the extra spacing inside the container.
An alternative is to get the user agent on the server side, assuming you send any requests from the extension to your own backend. Based on that, we can hide/show/customize a banner based on the operating system.
While it makes sense to restrict access to the window, I think it would be appropriate to provide access to the user agent, at least (e.g. through a `use..` hook similar to how we access settings and everything else).
Hello @sdevscotland , Do you have any idea why the UI extension is not showing on mobile devices? It's displaying on desktop, though.
Hello @sdevscotland , Do you have any idea why a UI extension is not showing on mobile devices? It's displaying on desktop, though.
Hi,
since api_version = "2024-07" you can do this:
Example with Banner and StyleHelper:
shopify.extension.toml
api_version = "2024-07"
...
...
[extensions.settings]
[[extensions.settings.fields]]
key = "hide_on_mobile"
type = "boolean"
name = "Hide on mobile"
[[extensions.settings.fields]]
key = "hide_on_desktop"
type = "boolean"
name = "Hide on desktop"
Extension.jsx
import {
Banner,
View,
Style,
useExtensionEditor,
useSettings,
reactExtension,
} from '@shopify/ui-extensions-react/checkout';
export default reactExtension("purchase.checkout.block.render", () => (
<Extension />
));
function Extension() {
const design_mode = useExtensionEditor() ? true : false;
let {
title,
description,
collapsible,
status,
hide_on_mobile,
hide_on_desktop
} = useSettings();
let view_display_attr = 'auto';
if (hide_on_mobile && hide_on_desktop) {
view_display_attr = 'none';
} else if (hide_on_desktop) {
view_display_attr = Style.default('auto').when({viewportInlineSize: {min: 'medium'}}, 'none');
} else if (hide_on_mobile) {
view_display_attr = Style.default('none').when({viewportInlineSize: {min: 'medium'}}, 'auto');
}
if (!design_mode && !title) {
return null;
}
if (!status) {
status = 'info';
}
if (collapsible && !description) {
collapsible = false;
}
return (
<View padding="none" border="none" display={view_display_attr}>
<Banner title={title} status={status} collapsible={collapsible}>
{description}
</Banner>
</View>
);
}
Lukas