Development discussions around Shopify APIs
Hi Shopify Community!
Something seems to be amiss with the tutorial Build a Shopify App with Node and React . It seems as though the instructions no longer follow what is possible in the dashboard. I have been spending the last few days, trying to figure out how to install the Sample Embed App that is produced from the tutorial into a store.
I can see that others have been asking this question as well without a response.
(6/17)
Unable to install my shopify app to a development store
(6/18)
Not getting the "Install Unlisted App" popup for some reason.
(6/21)
Stuck in: Build a Shopify App with Node and React
(6/24)
Trouble installing custom embedded app to development store.
Basically, all the fun seems to stop on step 3 Embed your app in Shopify, specifically when we reach the Authenticate and test your app section. It seems the ability to embed your app, or pair it with a store is not working and there is no way to get access to the value of shopOrigin. The valuer of the shopOrigin seems necessary to actually to make a connection through the concept of the Shopify App Bridge.
Questions:
Does anyone know if this Build a Shopify App with Node and React tutorial is still valid?
How does one pair and app with a store, without using the missing dashboard view/controls ( I have outline those missing views below in the steps to reproduce what I am seeing) ?
If this is true, how can I embed my app so as to get the shopOrigin to appear in my server.js Context, is there a workaround or another tutorial that might show a different means of acquiring the shopOrigin ?
Below are the steps I have been going down, and where things seem to fall apart if my questions above don't make sense.
My ngrok, Node/React/NextJs all seem to be running in my local and as I follow the instructions in step 1 and 2 of this section
"1. In the Shopify Partner Dashboard click the Select store button located inside the Test your app card"
'2. Click the development store where you would like to install your app. If you have not
yet created a development store, then click the Create new store button in the top right corner."
Next a pop appears warning user that this App will not be able be transferred
I click Install anyway because there seems to be no other course of action, if I want to pair my app with the store. After doing so I local app appears in the browser, which I believe is correct as it appears to show my current ngrok address and the single next page/index.js appears in the browser : ( looks good so far)
AND THEN..... HERE IS WHERE THE FUN STOPS
Screens 3, 4, and 5 seem in possible to reach, if the even exist.
Step 3 Dashboard View
Step 4 Dashboard View
STEP 5 DASHBOARD
Instead my store appears, with no semblance of the app I created with in the partner view of the dashboard.
I have tried using the "Manage private apps" link which allows me to create a private App. I have spent half the day going down the rabbit hole to no avail.
I have tried adding as a Custom App rather than a Public App, but this does not seem to work, either. Finally, I gave up and decided to just continue the tutorial, having read in a one of the postings in the forums that embedded apps are only loaded in the dashboard for UI design, and would soon be deprecated.
Thinking perhaps there is no need to have the app embedded in the dashboard view, I continue on and made it through most of section 4 Build your user interface with Polaris , until I got to Add Shopify App Bridge, which seems to be impossible to complete, since there is no way to facilitate the shopOrigin value from shopify as a cookie or somehow as an env variable accessible to my server.js ( or other parts of the stack). I suspect that this is happening because I was never able to actually embed the app and so do not have access to the shopOrigin and will never get it until the app is somehow paired with a store.
Maybe, I misread posting regarding the deprecation of the embedded app in the dashboard, but never the less I am stumped and do not know how to continue.
Any Help would be much appreciated.
Solved! Go to the solution
This is an accepted solution.
FYI I don't think "private apps" can be embedded, hence you hit a wall there.
So I didn't build my app using Node and React and am generally relatively new to web development and also haven't yet submitted my app for approval, but hopefully I can help as I've been banging my head against the wall all week. In my experience, their install links within the UI (whether for a custom app for a merchant or to test in your own development store) simply don't work. Instead, you need to generate a permissionUrl that's constructed like this:
https://{shop}.myshopify.com/admin/oauth/authorize?client_id={api_key}&scope={scopes}&redirect_uri={redirect_uri}&state={nonce}&grant_options[]={access_mode}
My suspicion at what's happening is that install link goes straight to your app and whatever code is included in that example isn't properly routing you to generate the above permissionUrl. So instead, just manually create the above link for your development store and paste it into your browser, you should see the OAuth prompt and you can proceed (and redirect you using your redirecturi - at this point make sure you store the code and exchange for access token).
Now you will ask - OK, so we can finally get this installed for a development store, but it's not like we're going to generate that link manually by getting each merchant's shopOrigin and email them the link each time, right? They provide this snippet here: https://shopify.dev/tools/app-bridge/getting-started in the 'Authenticate with OAuth' section - this will enable you to dynamically generate the permissionUrl.
Which brings us to your other question (and one I was immensely confused on), how do we get and store shopOrigin? They have info here: https://shopify.dev/tutorials/get-and-store-the-shop-origin and appear to have a couple built-in libraries to assist with this if you're using Node.
In my case, my app was built simply using JS / HTML / CSS so I didn't use any of that. Let's say your app is ultimately hosted at {myshopifyapp}.myapphosting.com and this is where you point your Shopify app when you create your Shopify app listing. When your app is actually live in the Shopify app store and someone clicks "install," Shopify will automatically append ?shop={shopOrigin} to your URL - so your effective install url that you can use to test an actual installation process that a merchant goes through (I believe, and I hope) becomes {myshopifyapp}.myapphosting.com?shop={shopOrigin}. So this will help get you the shopOrigin of the logged in merchant for the purposes of generating your initial permissionUrl.
For returning merchants accessing your embedded app from within Shopify POS or embedded within Shopify Admin, in my experience, the queryString of every request will also have ?shop={shopOrigin} appended, along with hmac, session, and locale - so you can use window.location.search to get the query string, then parse the query string to grab shopOrigin each time (after validating hmac to confirm it's a valid request from Shopify).
All that being said, this has resulted in me having to manually write annoying conditional logic that goes something like, when someone arrives at my app I check for the presence of the shop and hmac parameter and if that's present, then on the server side I validate hmac - if so, then I check for the presence of a valid API access token for them - if that's there, then welcome back to my app. I'm making an assumption here that if the hmac validation passes it's not a bad actor. If someone sees any issues with this, by all means please let me know.
Lastly, I'll just add this here because if the above works for you, then eventually you'll hopefully get to the point where you'll want beta test your app with an actual merchant. You'll send your merchant your generalized install link {myshopifyapp}.myhosting.com?shop={their shopOrigin} that you've so meticulously created and tested your OAuth flow for and they'll be confronted with an error message during install that they can't install an unlisted, unapproved app (you've been testing this on your own development stores after all, who would have expected their experience would be any different?). So then you'll create another app within Shopify and mark it custom instead of public, and click "generate a custom install link" and send that to them, and that will just result in a broken app page after they click install and when you both check, your app still isn't installed.
So the move here instead is to send them a manually constructed permissionUrl which includes the new client_id and their shopOrigin. If you try to do this BEFORE you generate the broken custom install link and specify which merchant your app is for, it also won't work.
Good luck!
This is an accepted solution.
@yanfaingold, @simplymike, @satwik97
I wrote up my solution, but this chat disconnected me and had not autosaved, and I don't have time to write it up all again, but @policenauts1 direction to use the following solved my issue.
When you arrive to the incongruity between the tutorial dashboard view that offers a view of screens for installing the tutorial app
and all you see is the following screen
this is when @policenauts1 offering fixes the embed, ( at least it did for me)
https://xxx-xxx-xxx.myshopify.com.myshopify.com/admin/oauth/authorize?client_id=xxx-api-key-xxxx&scope=read_products&redirect_uri=https://O3y-current-domain-3cd34.ngrok.io/auth/callback&state=nonce&grant_options[]=access_mode
sticking that in the browser with
1) ngrok running with a Session THAT HAD NOT EXPIRED ( apparently if ngrok session expires, it does not just shut down, and will appear as though it is running, but it will not have the needs ssl)
2) running the Node/React/NextJS app as a true node service and not as next app in dev mode using the webpack server.
so change package.json from "dev":"next" to "dev": "node server.js"
and zippy doo-daa, you should see the following view in you dashboard
clicking on the Sample Embed App should load your app in the dashboard.
Same problem here.
Appears to be broken on Safari/apple devices, i.e. works on Chrome and the Admin/POS app on Android but not on my iPad.
Looks like a change in the way Safari treats third party cookies since March 2020 breaks embedded apps in Shopify. See long discussion below.
https://community.shopify.com/c/Shopify-APIs-SDKs/Safari-13-1-and-embedded-apps/td-p/688416
Still waiting for a fixed version of the API and a fixed version of the tutorial.
Hi Paranthaman,
Thanks for that link mate. I have read through thread and read a couple of the links to a Medium posting, Shopify blog, and a couple of others. I will dig a little harder to see if some of the various methods offered in the in the thread will be access to the sessionId / shopOrigin need to create authorization for the Shopify APIs.
I was a bit thrown off by your response. I have only been working with Chrome thus far and not Safari. I thought my issue was that when I attempted to add my APP to one of my Stores in the Dashboard, it never seem to work. I say it never worked because the screens that are in the tutorial never matched the screens I was seeing in the actual Shopify Dashboard. I take it from your feedback and the discussion in the link in your reply, that
1) Shopify does not actually embed the app in and iframe any longer?
2) We need to use a different means of getting the shopOrigin ?
This is an accepted solution.
FYI I don't think "private apps" can be embedded, hence you hit a wall there.
So I didn't build my app using Node and React and am generally relatively new to web development and also haven't yet submitted my app for approval, but hopefully I can help as I've been banging my head against the wall all week. In my experience, their install links within the UI (whether for a custom app for a merchant or to test in your own development store) simply don't work. Instead, you need to generate a permissionUrl that's constructed like this:
https://{shop}.myshopify.com/admin/oauth/authorize?client_id={api_key}&scope={scopes}&redirect_uri={redirect_uri}&state={nonce}&grant_options[]={access_mode}
My suspicion at what's happening is that install link goes straight to your app and whatever code is included in that example isn't properly routing you to generate the above permissionUrl. So instead, just manually create the above link for your development store and paste it into your browser, you should see the OAuth prompt and you can proceed (and redirect you using your redirecturi - at this point make sure you store the code and exchange for access token).
Now you will ask - OK, so we can finally get this installed for a development store, but it's not like we're going to generate that link manually by getting each merchant's shopOrigin and email them the link each time, right? They provide this snippet here: https://shopify.dev/tools/app-bridge/getting-started in the 'Authenticate with OAuth' section - this will enable you to dynamically generate the permissionUrl.
Which brings us to your other question (and one I was immensely confused on), how do we get and store shopOrigin? They have info here: https://shopify.dev/tutorials/get-and-store-the-shop-origin and appear to have a couple built-in libraries to assist with this if you're using Node.
In my case, my app was built simply using JS / HTML / CSS so I didn't use any of that. Let's say your app is ultimately hosted at {myshopifyapp}.myapphosting.com and this is where you point your Shopify app when you create your Shopify app listing. When your app is actually live in the Shopify app store and someone clicks "install," Shopify will automatically append ?shop={shopOrigin} to your URL - so your effective install url that you can use to test an actual installation process that a merchant goes through (I believe, and I hope) becomes {myshopifyapp}.myapphosting.com?shop={shopOrigin}. So this will help get you the shopOrigin of the logged in merchant for the purposes of generating your initial permissionUrl.
For returning merchants accessing your embedded app from within Shopify POS or embedded within Shopify Admin, in my experience, the queryString of every request will also have ?shop={shopOrigin} appended, along with hmac, session, and locale - so you can use window.location.search to get the query string, then parse the query string to grab shopOrigin each time (after validating hmac to confirm it's a valid request from Shopify).
All that being said, this has resulted in me having to manually write annoying conditional logic that goes something like, when someone arrives at my app I check for the presence of the shop and hmac parameter and if that's present, then on the server side I validate hmac - if so, then I check for the presence of a valid API access token for them - if that's there, then welcome back to my app. I'm making an assumption here that if the hmac validation passes it's not a bad actor. If someone sees any issues with this, by all means please let me know.
Lastly, I'll just add this here because if the above works for you, then eventually you'll hopefully get to the point where you'll want beta test your app with an actual merchant. You'll send your merchant your generalized install link {myshopifyapp}.myhosting.com?shop={their shopOrigin} that you've so meticulously created and tested your OAuth flow for and they'll be confronted with an error message during install that they can't install an unlisted, unapproved app (you've been testing this on your own development stores after all, who would have expected their experience would be any different?). So then you'll create another app within Shopify and mark it custom instead of public, and click "generate a custom install link" and send that to them, and that will just result in a broken app page after they click install and when you both check, your app still isn't installed.
So the move here instead is to send them a manually constructed permissionUrl which includes the new client_id and their shopOrigin. If you try to do this BEFORE you generate the broken custom install link and specify which merchant your app is for, it also won't work.
Good luck!
Hi policenauts1,
Thank you so much!. I was able to use what you said concerning the creating the correct url to grant permissions. I have not been able to get the shopOrigin to work correctly. I have to admit I still trying to parse together the information you provided. I have extensive experience with React, NextJs, and Node, and I have used ngrok in other development efforts. However, the insight your provided revealed how there is most likely some other fundamental concepts I am missing about how shopify app development is actually performed, so I have begun taking some of the shopify academy class to get a better understanding. In the next coming days, I will delve into the shopOrigin tutorial, and try to figure out some more about the differences between Custom. Private, Public and embedded apps. I will return to this post with my finding, perhaps it will help you and others facing the same issues.
For now I am going to leave the post open ( not mark it as a success response, as there may be some more answers that will complete the challenges I still facing)
Thanks buddy
No problem!
Just to recap on shopOrigin, after your app is installed, any time someone accesses your app, even though your browser URL will say {shopOrigin}.myshopify.com/app/your-app-name, because of the iframe there is an actual authentication URL that you can access using window.location.search which points to your app hosting URL and always has a shop parameter. So it seems those two Shopify libraries in that link will automatically grab and store it for you, or if you're doing it manually like me, you should be able to grab it using URLParams. Hope this helps.
This is an accepted solution.
@yanfaingold, @simplymike, @satwik97
I wrote up my solution, but this chat disconnected me and had not autosaved, and I don't have time to write it up all again, but @policenauts1 direction to use the following solved my issue.
When you arrive to the incongruity between the tutorial dashboard view that offers a view of screens for installing the tutorial app
and all you see is the following screen
this is when @policenauts1 offering fixes the embed, ( at least it did for me)
https://xxx-xxx-xxx.myshopify.com.myshopify.com/admin/oauth/authorize?client_id=xxx-api-key-xxxx&scope=read_products&redirect_uri=https://O3y-current-domain-3cd34.ngrok.io/auth/callback&state=nonce&grant_options[]=access_mode
sticking that in the browser with
1) ngrok running with a Session THAT HAD NOT EXPIRED ( apparently if ngrok session expires, it does not just shut down, and will appear as though it is running, but it will not have the needs ssl)
2) running the Node/React/NextJS app as a true node service and not as next app in dev mode using the webpack server.
so change package.json from "dev":"next" to "dev": "node server.js"
and zippy doo-daa, you should see the following view in you dashboard
clicking on the Sample Embed App should load your app in the dashboard.
User | RANK |
---|---|
51 | |
11 | |
8 | |
6 | |
6 |
Thanks to all who participated in our AMA with 2H Media on planning your 2023 marketing bu...
By Jacqui Mar 30, 2023Thanks to all Community members that participated in our inaugural 2 week AMA on the new E...
By Jacqui Mar 10, 2023Upskill and stand out with the new Shopify Foundations Certification program
By SarahF_Shopify Mar 6, 2023