It’s essentially a Shopify’s React app template that works with their existing ecommerce backend. Runs on Oxygen, which is Cloudflare’s worker-based JavaScript runtime,
Works locally but deployment fails.
Steps to reproduce:
Scaffold Shopify Hydrogen project using npm create @shopify/hydrogen@latest
This works locally, session is being created on the product page.
Deploy to Shopify using npx shopify hydrogen deploy. Error shown below.
Deployment failed, error: Uncaught Error: Disallowed operation called within global scope. Asynchronous I/O (ex: fetch() or connect()), setting a timeout, and generating random values are not allowed within global scope. To fix this error, perform this operation within a handler. https://developers.cloudflare.com/workers/runtime-apis/handlers/
I'm pretty sure this means that the built prod version of shapediver is a bit different than the dev version. Oxygen runs on a Cloudflare worker, and Cloudflare workers do not allow async code to be executed statically outside a function.
Can anyone advise if this is bug or are there any workarounds?
As far as I know, there haven’t been any attempts to implement ShapeDiver that way, but that doesn’t mean that it shouldn’t work.
We’ll have a closer look at this issue, I’ll get back to you once I know more.
If you have any new insights in the meantime, let us know!
Thank you! Hopefully this can get fixed as Hydrogen is a quite powerful way of custom building e-commerce stores with React and supports SSR. It’s very customisable.
If you need an example to reproduce the issue above you can use this POC repo debug branch
I looked into your repo and noticed that you also include @shapediver/viewer.viewport. Does it work if you only use @shapediver/viewer.session without the viewport package?
I know that this would not create a viewport, but it would provide valuable insights on where the issue could be.
I removed @shapediver/viewer package in my last commit (same branch), and tested again. Outcome is the same - works locally (session is being created) but deployment fails with the same error.
Not sure if this helps or not, I also tried to just create an empty viewer without a session only using @shapediver/viewer.viewport package on this branch
I can see it works locally as all the elements are being loaded into dom.
I’ve made some simple changes about how things are handled in the global scope. Can you please try version 3.9.4 and let me know if that works for you now?
thank you, that’s unfortunate as this were some issues that could be obvious.
Do you have any more details on the errors, like a stack trace that is pointing to the lines?
Otherwise, it will be very difficult to solve this, as it is like finding a needle in a haystack.
I don’t suppose you could reproduce the issue on your local machine? This can be reproduced quite easily. You just need a Shopify store (they give free trial) and scaffold a Hydrogen template using npm create @shopify/hydrogen@latest and install shapediver npm package in that project. My repo is nothing but a Shopify’s scaffold. You might have more visibility this way.
You don’t need my repo to reporduce it. If you follow the npm create @shopify/hydrogen@latest steps it will take you through basic setup journey, one of the steps is linking your Shopify account with the Hydrogen app. It will then create all environment variables necessary for this to happen and enable Hydrogen in the Shopify Admin panel.
npm create @shopify/hydrogen
Connect to Shopify?
Use sample data from Mock.shop (no login required)
Link your Shopify account
Press ↑↓ arrows to select, enter to confirm
Where would you like to create your storefront?
>./some-folder
Choose a language:
JavaScript
>Typescript
Select a styling library:
Tailwind
>CSS Modules
My repo is based on the template it creates with few minor cosmetic changes, so you should be able to reproduce it. Just need to udpate vite vite.config.ts and entry.server.tsx as I mentioned here
As discussed on our onboarding call, please try to change the code splitting settings of your remix app to make sure the @shapediver/viewer.session package isn’t included in the resulting backend code. Prompt for LLM which is useful for figuring out options to do this:
When developing a remix app, how can I make sure that certain npm packages are only used client side, and not included in the server side code?
Thanks for your insights during the call. I managed to resolve the issue, feel free to check the my POC branch to see the example. To resolve this, 2 things had to happen.
1. Dynamically import createSession from @shapediver/viewer.session
import { ISessionApi } from '@shapediver/viewer.session'; // Safe to import the interface at global scope, doesn't trigger SSR issues
...
export default function Product() {
const sessionRef = useRef<ISessionApi>;
useEffect(() => {
const init = async () => {
try {
if (sessionRef.current) return;
const {createSession} = await import('@shapediver/viewer.session');
const session = await createSession({
ticket: 'ticketId',
modelViewUrl: 'modelViewUrl',
});
sessionRef.current = session;
console.log('Session created:', session);
} catch (error) {
console.error('Error initializing the session or viewport:', error);
}
};
init();
}, []);
...
2. Mark @shapediver packages in vite.config.ts as external