A space to discuss online store customization, theme development, and Liquid templating.
Any method I've attempted to request information from a Shopify store from a different domain results in the familiar CORS error:
"Access to fetch at 'https://x.myshopify.com/admin/api/2019-04/graphql.json' from origin 'https://x.ngrok.io' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled."
I'm trying to create a customer-facing site which is very simple and is just for managing (creating and logging in) customer accounts, and doing specific things with those accounts like setting tags and sending emails to store staff to update details on those accounts once they're created. Using GraphQL or the REST API, is there a way to get the Shopify store to allow API requests from my separate domain without triggering the CORS error? Any way at all to add the appropriate "Access-Control-Allow-Origin" header in the response from the API endpoint?
(The security implications are not my concern here, as I believe API credentials can be obfuscated using backend middleware on the site doing the requests)
Or am I going about it the wrong way and there's another recommended way to do this besides those two APIs?
Or is what I'm trying to do only possible on the same domain as the store, by design, no exceptions?
Solved! Go to the solution
This is an accepted solution.
If you want to make an API request to the admin API, you have to do it from a back end. Front end requests, as you observed, will be blocked by the CORS policy on our end. What you can do is from your front end, delegate to your backend to make the request, and return the response data from that request to your front end.
Alex | 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 the Shopify Help Center or the Shopify Blog
This is an accepted solution.
If you want to make an API request to the admin API, you have to do it from a back end. Front end requests, as you observed, will be blocked by the CORS policy on our end. What you can do is from your front end, delegate to your backend to make the request, and return the response data from that request to your front end.
Alex | 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 the Shopify Help Center or the Shopify Blog
Hi,
Can you please explain more how to achieve this delegation from Frontend to Backend?
regards
@I_KNOW_NOTHING wrote:Hi,
Can you please explain more how to achieve this delegation from Frontend to Backend?
regards
The flow is fairly simple but refer to the docs for extra info on authentication. You should never be trying to access the Admin API from the front end as it's not secure. You will be passing auth details that anyone could steal so this is just a crazy idea.
General delegation (high level):
What are you trying to do that needs a call to the Admin API in the first place?
Hi Jason,
Thank you for quick reply,
what I am using is an GraphQL Admin API. This is my sample query
Hello,
Does have any example code or steps to do this?
Because I am new in it and don't have much idea.
Thank you
@sunildeshkar: Here's what I put together, for the purposes of demonstration. You should be able to replace the Storefront access token and store name with your own, to pull through some data. Is this what you were after?
@Ross_Angus Thank you for replying. Actually I don't want call SHOPIFY API to get product and all. I need to call third party API which is created my self and It means, end point must be "https://devdemo.pro/outreachbee2/API/index.php" . I wrote code to call on product details template page, https://sbd-ds.myshopify.com/products/chikan-food this is the page where I need to call API via ajax code. Here is ajax code:
This is dead simple to fix. Tell your server to allow incoming calls from sbd-ds.myshopify.com
Nothing else to it. It is your server causing the CORS issue. You are not allowed to call domain A from domain B without a CORS issue for the most part.The Internet has 1000 pages dedicated to explaining how to mitigate CORS issues, you should be able to solve this in < 5 minutes yourself.
we are currently facing this issue in our store, can you show us how to implement it ???
Can you show me your code?
PS: don't show the real api password or any private details
This is not solved. What about the Storefront API. Does that require a backend too? I literally can't get a straight answer out of this forum because every question is about a different kind of API. Public, private, custom. Dudes. Make better docs.
Think of it this way:
Storefront API is a public API and the token for it is meant to be used on the client side.
Admin API is a private API and the token is not meant to be shared publicly. If you share this token to everyone by making requests from the browser, they can potentially access private information about your store, financial information, CUSTOMER information etc.
This could lead to both inconvenience to your customers as they would be subject to fraud as well as you could run into legal issues if someone decides to sue you because of it.
Hence, Shopify throws a CORS error when detecting that you use a browser to send a request to a private API. While the CORS error might not be the most appropriate response here, it is valid for them to deny your request.
Hope that clarifies the issue for others encountering this error.
It doesn't clear up the issue because it doesn't answer my question. It only reitterates other docs.
The question is Does Storefront API actually work Client-Side or are there unavoidable CORS issues that require a server-side proxy?
I'm not talking about the difference between Storefront and Admin.
You sound like a bot.
Hence, Shopify throws a CORS error when detecting that you use a browser to send a request to a private API.
This is the answer to your question based on my comment. Storefront API is a public API and Admin API is a private one.
That's exactly why the difference between the APIs was pointed out.
Of course, you do not need a backend for Storefront API.
It takes very little time to verify that by sending a simple fetch request from Chrome dev tools console.
Aside from that, there is also a library (jsbuysdk) made by Shopify that utilizes Storefront API and is meant for the browser.
You can find more here: https://shopify.github.io/js-buy-sdk/
Hi Nester,
My questions are very related to the topic at hand and, although I'm pretty sure it's a few very tiny things that I'm missing, I too am struggling for answers.
My situation is simple: I have an Express server (Node) that can authenticate and call the Shopify admin API without problems when the process is initiated from a client app sitting on the same domain. When I initiate the oAuth flow from a client app sitting on a different domain (i.e. this client calls my secure server and this server attempts to establish contact with Shopify) then I end up with the CORS error described above.
I believe this is a reasonable (and possibly even popular) architecture and so it must be something simple I'm missing on my end.
Can you confirm if this is possible and - if so - if an example exists that I can study to see where I'm going wrong?
Hein
Did you manage to find any solution? In 2023, I am struggling with the same issue - Angular as SPA and Express as backend. CORS error 😞
I am using Storefront API using apollo and get CORS, how to handle that?
Surprised that no one yet addressed how people managed work around the CORS issue.
The actual answer is despite what the docs say, you have to use a middleman server to use Storefront API as well. You cannot just do it from the frontend like Stripe allows. So spin up a whole server that just passes messages, folks. Worry about it silently falling over at checkout, folks. That's the only way to use this "serverless solution" of a scam product.
Bottom line, after 2 integrations and endless trouble and even more monthly fees, I can attest, Shopify is a garbage fire built on a garbage framework, run by people who are just swimming in their money bin, don't care and don't answer questions on the forum. Good F'ing luck.
You're doing it wrong. If you use Storefront API as intended, there is no CORS issue.
Shopify is fundamentally built with the exact same HTTP protocols as all other Internet properties. Shopify is not pushing any unique technology, so comparing it to Stripe as if Stripe is somehow doing Internet computing different or more correct, is plain silly. Once you can do one pattern with one service, you can repeat with any other. oAuth is oAuth, for example.
It's ok to just say you don't understand, and ask for help. Mostly, you have to learn to help yourself. Like anything worth doing.
Using it as intended? I've used it on 2 projects and you need a middle man server to use Storefront API and the docs suck. Period.
and Stripe.JS allows for client side calls to the stripe.com api, so does google analytics script tag. that's how CORS works, dick.
You are the expert of a pile of shit.
You sure you are not mixing up Storefront API with the GraphQL Admin API?
Storefront API even has a simple library - JS Buy SDK that can be used on any website to implement product catalog / cart functionality with your Shopify store.
You can see an example here: https://jamstack-ecommerce.nesters.me/
That's a static Nuxt.js storefront outside of Shopify that is utilizing Storefront API.
GraphQL Admin API rightfully will have CORS issues due to sensitive data that can be exposed if you leave your credentials available to everyone on the internet.
Since my question is closely related to the way the convo has shifted, I'm using the Storefront API and am getting a CORS error from a Gatsby development server on localhost.
Been reading for a few days now and can't figure it out why this is happening. Does CORS behave differently for localhost?
Thanks
When you setup a token to do Storefront API calls, do you not pin it to a domain? I pin my to https://mystore.test for example, as the .test domain is perfect for localhost work. So I get no CORS problems. But if you pinned your token to a different domain from your calls, CORS is indeed your problem. Without more details, it is hard to help you out.
Thanks for the quick reply. I did a little more investigating and realized that my environment variable isn't suppose to include ".myshopify.com" so it was appended twice and I'd been staring for so long I was blind to it. I didn't consider that because Gatsby's Shopify source plugin was doing static graphql queries successfully using the same source plugin with the same credentials, but not queries in the browser. Not sure why.
Appreciate the help
Puberty is hitting you hard! I get it though, I had kids, so your 'tude is like water off a ducks back. One day you'll be out of your mom's basement, and perhaps less bitter about things you should be enjoying more.
That's a lot of assumptions Hunky Bill. It's okay to admit this platform is garbage and ruining e-commerce for developers.
Hey Alex,
I can't figure out how to delegate this to the backend. Is there any documentation?
I'm trying to GET /admin/api/themes/{theme_id}/assets.json from the index.js of a custom app that's embedded in the Shopify Admin.
It is similar to registering a webhook?
I've looked everywhere but I can find a concrete example of how to do this.
Cheers!
Andrew
A theme asset is not pinned to a "custom App" embedded in the Admin. Assets belong to a theme, and hence are available to any App with API permission to read theme assets. If you are having trouble making API GET requests for theme assets, ensure your App has permission to do so. After that, it remains a simple GET.
I was trying that at first. I'm using ngrok to develop the app and tried a few different get combinations:
fetch("/admin/api/themes/{theme_id}/assets.json", {method: "GET"}) - this fetched https://no234oiasd.ngrok.io/admin/api/..etc and returned 404.
fetch("{hardcoded_store_name}//admin/api/themes/{theme_id}/assets.json", {method: "GET"}) - cors policy, and an opaque response.
I do have the app set up for theme permissions as well.
1. the correct endpoint is /admin/api/2020-10/themes/{theme_id}/assets.json
2. If you are getting CORS errors you are doing your API calls all wrong. That would be an indication you are calling from some domain other than your App, which is clearly a violation of CORS
Yeah, sorry the endpoint I'm using is that one (I can paste it into the URL of the store I'm developing for and receive the output I'm expecting).
So, I followed the Shopify React/Node.js custom app tutorial and got to the end with all the steps working. So, now I have a custom app that's embedded in the Shopify Admin Panel.
I'm just looking to start with a button (on the index.js page) that returns the /admin/api/../assets.json data to the console.
I can't find any documentation that shows how to simply query that endpoint from the index.js page. Is there documentation that you can point me towards?
I am using ngrok so my domain is different than my store but I do have the /auth/callback set to the ngrok url I'm using. I've seen that I might have to set up a route in server.js that index.js calls but I just can't find the right docs.
Thanks for the help btw
The easiest way to avoid all the pitfalls you are running into would be to implement this functionality via an app proxy --> https://shopify.dev/tutorials/display-data-on-an-online-store-with-an-application-proxy-app-extensio.... Once this app proxy is configured and installed in the Shopify store then you just reference your URL with the DNS name of the Shopify store. The path equates to the app proxy call, and Shopify does the rest. Your external resource can then validate the API request via HMAC signature verification to ensure the call is legit. Once you get whatever data you need then you pass values back to the request caller.
Thank you, sir! I'd been looking for this for the past 3 hrs!
So you speak of index.js being the home page of your own custom embedded App in the Admin. And you don't know where to start. OK. Well, to make a GET request to your App, you can use fetch() or even better, try the axios library. It is simple, and works well with all the bells and whistles. It is likely you can code up your GET request within a minute and see your results. So hook your button click event listener to an axios (or fetch) GET and you will see in the response, what you asked for.
Thanks Greg and Bill!
I think Bill was right about that it should be easy.
In case anyone else is wondering the full set up:
So about using the api directly on browser, you take note of the ff:
Got to admit though, the gql documentation is not very friendly. 🙂
Here's a sample query you can try
query {
products(first:3) {
edges {
node {
id
handle
variants(first:3) {
edges {
node {
id
}
}
}
}
}
}
}
What baffles me about this issue is that I have no idea how this CodePen example works. Perhaps the later API has stricter CORS rules.
There are no CORS issues when you make calls with the Storefront API token. So this simple Codepen does a request that gets product tags. The result is returned and appended to DOM. Can you describe what baffles you about that? Perhaps we can help then.
I was getting CORS errors when I tried to connect. The CodePen example gave me enough of a working example to get over this hump. No idea why it was happening the Storefront access.
Hi,
I'm having a similar CORS issue.
In my case, I have a custom frontend on a different domain with a third party app trying to pull some data from Shopify at {{shopify_domain}}/tools/{{some_endpoint}}
This fails because of CORS.
Since I can confirm that I'm not exposing any keys using this app.
I'm wondering if there's a way to add my new domain to a cors whitelist?
@HunkyBill @Ross_Angus any ideas please?
Shameful admission, but as I've not been in the guts of this subject for a while, it's mostly drifted out of my head.
My CodePen proof-of-concept was working towards a headless solution using the CMS TakeShape. Unfortunately, TakeShape makes it easy to import Shopify data and mix it up with custom data patterns created in TakeShape itself, so I'm not even sure I solved some of these problems myself.
My guess would be that getting your domain added to a whitelist by Shopify isn't going to happen. My proof-of-concept was about pulling publicly available Shopify data to a third party domain, which is thankfully possible without any CORS issues.
(just to reiterate, I don't actually understand what CORS is!)
Access to fetch at 'https://interiortonic-united-states.myshopify.com/admin/api/2024-01/draft_orders.json' from origin 'https://interiortonic.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the
I am create the darft order than show me this error please solve this
The standard way to call the Admin API from the front-end of your store is to use the App Proxy pattern. The proxy accepts a call from your store Interior Tonic, and secures it for your backend. Your backend makes the Draft Order, returns and URL if you want, and you redirect your customer to that URL so they can checkout and turn the draft into a real order.
Everything what you need to know about this issue:
1) You can make Admin API requests from front-end side only on "same domain" urls.
2) If you want to make a call from frontend to your shop, but this shop has another domain - you cannot do this from frontend thanks CORS. That's why you need to use some backend feutures or make an app that reply your functionality and gives you need data back to the frontend side.
So the fasters solution for this is to find (or create) an app.