Have your say in Community Polls: What was/is your greatest motivation to start your own business?

Re: Shopify App Proxy gets CORS error or 404

Solved

Why am I getting a CORS error or 404 with my Shopify app proxy?

DevBijan
Shopify Partner
54 2 17

Hello all, I am working on a Shopify app, and with it a theme extension to pull data from my database and display it for users. I've gone through all the posts I could find about this topic and tried all the suggestions I found, however I am still getting either a CORS error or a 404 not found for my api endpoint.

 

I have set up an app proxy in my partner's dashboard and I updated the proxy URL every time it's updated. I am using the default cloudflare tunnel setup.

tempsnip.png

I am using the Remix template, here is my folder structure

 

Project{

  app{

     routes{

       api{

        data.server.js //MY ENDPOINT

       }

     }

  }

  EXTENSIONS{

     My_Extension{

      blocks{

        App_block.liquid //MY APP BLOCK

      } 

    }

  }

}

 

In my App Block I am trying to fetch data from my data.server.js using an App proxy. This returns a 404 error. I added fetch options and headers to try and solve the problem with no luck. If I use the cloudflare tunnel URL in my fetch, I will get the cors policy, that's why I have 'Access-Control-Allow-Origin': 'https://{STORE-NAME}.myshopify.com' as an option.

 

async function fetchData() {
    try {
      const response = await fetch('/apps/api', {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': 'https://{STORE-NAME}.myshopify.com',
        }
      });
      if (!response.ok) {
        throw new Error('Network response was not ok ' + response.statusText);
      }
      const data = await response.json();
      const container = document.getElementById('app-block-container');
      container.innerText = JSON.stringify(data, null, 2);
    } catch (error) {
      console.error('There has been a problem with your fetch operation:', error);
    }
  }

  fetchData();

 

And then my data.server.js

 

 

import { authenticate } from "../../shopify.server";
import prisma  from '../../db.server';


export let data = async ({ request }) => {
    try {
        const shopy = await authenticate.admin(request);
        const allModels = await prisma.MY_DATA.findMany({
          where: { 
            shop: { equals: shopy.session.shop} 
          },
        });
        return {
          status: 200,
          headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': 'https://{STORE-NAME}.myshopify.com',
            'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
          },
          data: JSON.stringify(allModels),
        };
      } catch (error) {
        console.error(error);
        return {
          status: 500,
          data: 'An error occurred while fetching data.',
        };
      } finally {
        await prisma.$disconnect();
      }


  };

 

 

I'm not sure where I'm going wrong. Like I said, I've looked through a bunch of posts, it seems like a relatively common problem, but without any luck on solving it.

 

Any help would be appreciated! Thanks!

Accepted Solution (1)

DevBijan
Shopify Partner
54 2 17

This is an accepted solution.

I fixed my issue.

  1. Moved my api route to the main folder according to remix documentation
  2. Reinstalled app.

My proxy URL changed to .....cloudflare.com/MY_ENDPOINT

View solution in original post

Replies 26 (26)

DevBijan
Shopify Partner
54 2 17

This is an accepted solution.

I fixed my issue.

  1. Moved my api route to the main folder according to remix documentation
  2. Reinstalled app.

My proxy URL changed to .....cloudflare.com/MY_ENDPOINT

joseacat
Shopify Partner
3 0 0

Hi, @DevBijan

 

Thanks a lot for sharing your experience. Currently, I am in the same problem: I have to fetch an application route from a block.
With the example you give above, with the subpath 'api' and proxy url '....cloudflare.com/my_endpoint'. What url do you fetch?

DevBijan
Shopify Partner
54 2 17

Hey, I am fetching '/prefix/subpath' so for example: '/apps/api'

joseacat
Shopify Partner
3 0 0

Thank you so much!
And if that's not too many questions... What URL proxy do you have in the configuration and what route do you use in the app?
Is it necessary to reinstall the app?

DevBijan
Shopify Partner
54 2 17

You can name the route inside your app anything you want. For me my route is 'modelData.jsx' so my proxy url is '...cloudflare.com/modelData'

 

This will result in fetch('/apps/api') to fetch from '...cloudflare.com/modelData'

 

If everything is set up correctly but not working during testing, try reinstalling the app to your store.

joseacat
Shopify Partner
3 0 0

Exact! After reinstalling it worked.
Thank you so much!

iffikhan30
Shopify Partner
291 37 53

Hello DevBijan,

I am stuck a same as you.

1) I add file to main folder getData.jsx as per your solution
2) Reinstalled app 

My proxy URL apps/api
ENDPOINT getData

I am using ngrok for tunnel

On My console network api error show 302 and auth login 404 not found.

Custom theme and app [remix] expert.

Email: irfan.sarwar.khan30@gmail.com
Chat on WhatsApp
DevBijan
Shopify Partner
54 2 17

Hello, 

 

make sure to double check that the app-proxy url is using the same ngrok tunnel url. It doesn't update automatically so you will need to adjust your app setup each time.

 

If your path is /apps/api and you have a tunnel url that looks like: ....ngrok.com/getData

 

you can do a fetch statement like this via an app block.

 

      const response = await fetch('/apps/api', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
      });
 
 
 
iffikhan30
Shopify Partner
291 37 53

Hi Dev,

 

Thanks for reply i figure out the issue, I add admin auth that's why not fetch api, when i change to public auth its work. 
Thanks Dev.

Custom theme and app [remix] expert.

Email: irfan.sarwar.khan30@gmail.com
Chat on WhatsApp
seunoyebode
Shopify Partner
11 0 0

Hi Irfan, please what do you mean by public auth? As I am having the same issue as you.

Thank you.

iffikhan30
Shopify Partner
291 37 53

Hello @seunoyebode ,

 

I using this public proxy App proxy (shopify.dev)

Custom theme and app [remix] expert.

Email: irfan.sarwar.khan30@gmail.com
Chat on WhatsApp
921Kiyo
Shopify Partner
19 0 3

How did you fix auth login 404 error? My server (remix) returns auth login 404 to the client, and I am not sure why. 

export const action = async ({ request }: ActionFunctionArgs) => {
  const { session } = await authenticate.public.appProxy(request);
  return json(
      { status: 200 },
    );
};

 

CarlosC24
Shopify Partner
8 0 2

Hi, I'm also having the auth login 404 error. Did you ever fix it?

921Kiyo
Shopify Partner
19 0 3

Yes, I used https://remix.run/resources/remix-utils#cors and 404 is gone! 

CarlosC24
Shopify Partner
8 0 2

Oh nice thank you! I'll try to implement cors. However, I may ask for help later if I can't figure it out.

CarlosC24
Shopify Partner
8 0 2

Can you explain how you got it to work? Been trying to implement cors but I'm unable to get past the /auth/login error. 

921Kiyo
Shopify Partner
19 0 3

It is something like this.

```

import { cors } from "remix-utils/cors"; 
import { json } from "@remix-run/node";
 
export const action = async ({ request }: ActionFunctionArgs) => {

const { session } = await authenticate.public.appProxy(request);
my logic...
return cors(request, json({status: 200}));

```

CarlosC24
Shopify Partner
8 0 2

I still get the same error. I guess my issue is from something else. Thank you for helping out!

bkmahapatra27
Shopify Partner
5 0 0

I encounter a similar problem when attempting to fetch data from my Shopify Remix app to the Checkout UI, resulting in a CORS error.Screenshot 2024-01-12 124316.png

DevBijan
Shopify Partner
54 2 17

Make sure you are setting CORS headers. 

 

My fetch looks like this:

const response = await fetch('/apps/ymm' + queryParams, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' },
      });

 

 

bkmahapatra27
Shopify Partner
5 0 0

bkmahapatra27_0-1706791202690.png

I'm using the latest remix template so i need to use this above ,It's in the docshttps://shopify.dev/docs/api/shopify-app-remix/v2/authenticate. Any one having this problem in the latest template can go through this docs

Vertonnes
Shopify Partner
2 0 0

The main folder is/app/routes/ ?

 

I created a template in /app/routes/ that imports actions from another template located in the /app/routes/api/createTemplate directory.

 

I've had this headache for several days.

 

Can you tell me if I added any wrong parameters to get to Prisma?

 

IMG-20240212-WA0002.jpg

 

IMG-20240212-WA0000.jpg

 

seunoyebode
Shopify Partner
11 0 0

I'm having http 404 error.

seunoyebode_0-1706703929944.png


I've uninstalled and reinstalled, but it is still the same

this is my fetch call

seunoyebode_1-1706704077391.png

 



this is my action function 

seunoyebode_2-1706704128422.png

is there anything I'm doing wrong? @DevBijan @iffikhan30 

Thank you

bkmahapatra27
Shopify Partner
5 0 0
DevBijan
Shopify Partner
54 2 17

Hey I would recommend going into your network tab in the browser console and making sure the link to the resource is set correctly. You are getting a 404 which means the data can't be found at the link it's searching. Go to the actual link you are trying to fetch and see if there is a page of JSON information. Nothing appears to be wrong with your code otherwise (at least nothing I can see right now).

Charles_Roberts
Shopify Partner
49 0 17

You should point the proxy at a Remix route and not the server, so, for example:

 

app/routes folder:

 

app.api.jsx

 

Then the App Proxy URL would be:

 

https://mydomain.trycloudflare.com/app/api

 

Then your fetch() URL would be like:

 

/subpath_prefix/subpath

 

Which would actually  be:

 

/apps/api

 

Note that, you don't have to add the domain part of the URL, in the fetch() URL param.

 

Please remember that form POST requests, hit the:

 

Remix action() method

 

And GET requests, hit the:

 

Remix loader() method