Search code examples
reactjsherokushopifyasset-pipelineassets

Shopify App Proxy - How to include my asset files in the request response | React / JS / Heroku


I'm building a Shopify App with React & Express, deployed via Heroku, which I'm trying to embed into my storefront using an Application Proxy.

When I finally load the proxied URL on my store - I get a blank screen and a bunch of 404's in the console for my .css and .js chunk files. The request was sent, authenticated, and my API's response is (200) - it just won't render anything.

Finally, after much research, I realized that Shopify has changed the path to these CSS and JS files to be my-store.myshopify.com/hash.chunk.js etc. instead of the reference to my Heroku server.

It appears this problem has been encountered before in this thread: Shopify app - how to include assets using an app-proxy with ruby on rails However, I can't seem to find a node/react/heroku equivalent to the Ruby solution presented here.

Any guidance or help would be greatly appreciated!

I begin by serving my React App through express with:

app.use(express.static(path.join(__dirname, 'client/build')));

and then when my proxy URL is hit I send back the index file within the client/build folder:

router.get('/proxy', (req, res) => {

    res.set('Content-Type', 'application/liquid').sendFile(path.join(__dirname, '../client/build/index.html'));

  });

Solution

  • I've managed to find a working solution to my problem after much trial and error.

    The homepage in package.json is important. I had it set to just my Heroku address when it should actually be set to herokuaddress.com/YOURPROXYROUTE (i.e. /app/my-app)

    Some additional middleware is required as well - for those interested I have the following routes set up to field requests from Shopify's app proxy.

    This is set up above any of my route imports in server.js:

    app.use(express.static(path.join(__dirname, 'client/build')));
    

    and these routes are imported below that from a /shopify-routes.js file:

    router.get('/proxy', (req, res) => {
        res.set('Content-Type', 'application/liquid').sendFile(path.join(__dirname, '../client/build/index.html'));
      });
    
      router.get('/proxy/static/css/:file', (req, res) => {
        res.set('Content-Type', 'text/css').sendFile(path.join(__dirname, `../client/build/static/css/${req.params.file}`));
      });
    
      router.get('/proxy/static/js/:file', (req, res) => {
        res.set('Content-Type', 'text/javascript').sendFile(path.join(__dirname, `../client/build/static/js/${req.params.file}`));
      });
    

    Though this may be a bit heavy-handed, it has solved the problem and the app is loading within the Shopify storefront now.