@shapediver/viewer.session deployment fails on Shopify's Hydrogen

Not sure if anyone ever tried this or is this meant to work but @shapediver/viewer.session can’t be deployed on Shopify’s headless stack Hydrogen.

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:

  1. Scaffold Shopify Hydrogen project using npm create @shopify/hydrogen@latest
  2. Install NPM package @shapediver/viewer.session
  3. Update vite.config.ts optimizeDeps to include @shapediver/viewer.session
  4. Update entry.server.tsx security policy
    connectSrc: [
      'https://sdr8euc1.eu-central-1.shapediver.com'
    ]
  1. Add this code below on products.$handle.tsx. Needs to be inside useEffect inside Product component. Need to make sure it runs on a client side.
        const session = await createSession({
          ticket:
            'session-id',
          modelViewUrl: 'model-view-ur',
        });

This works locally, session is being created on the product page.
image

  1. 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 opened a [Github Issue for this here] (Uncaught Error: Disallowed operation called within global scope. · Issue #2805 · Shopify/hydrogen · GitHub) there are some some more details there.

They said:

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?

Hello @Sebastian_Meckovski,

thank you for your message.

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!

Cheers, Michael

1 Like

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

Hello @Sebastian_Meckovski,

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.

Cheers, Michael

Hello @MajorMeerkatThe3rd ,

Thanks for the response,

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.


Let me know if there’s anything else I can help to narrow down the issue,

Seb

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.

Deployment fails with the same error:
image

Maybe there’s some shared code between different packages?

Hello @Sebastian_Meckovski,

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?

Cheers, Michael

Hello @MajorMeerkatThe3rd,

I updated to version 3.9.4 on this branch and unfortunately the same error is still there.

Hello @Sebastian_Meckovski,

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.

Cheers, Michael

Hi @MajorMeerkatThe3rd

In addition to the logs which I included in the GitHub issue, I can also share the verbose logs but I couldn’t find anything useful.

Hydrogen build log.txt (26.4 KB)

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.

I’ll read more about how these cloudflare javascript workers actually work as this is what Oxygen is based on

Hello @Sebastian_Meckovski,

I tried the deployment process with your Repo, but I got an error with my connection to the Shopify login that I was not able to solve yet.

I’ll evaluate the logs you have sent and will get back to you!

Cheers, Michael

Hello @MajorMeerkatThe3rd

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?

Hi,

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

...
  ssr: {
    external: ['@shapediver/viewer.session', '@shapediver/viewer.viewport'],
    optimizeDeps: {
    include: [],
    },
  },
...
1 Like