Solved

Using the new @shopify/app-bridge with @shopify/polaris-react

skuharmony
Shopify Partner
27 2 6

I am unsure how to use the new @shopify/app-bridge and @shopify/polaris together. For example, I have tried to make a React component that will use the app-bridge and polaris to display a toast.

 

import React, { Component } from "react";
import * as PropTypes from "prop-types";
import { Toast } from "@shopify/app-bridge/actions";
import { Page } from "@shopify/polaris";

class Start extends Component {
  static contextTypes = {
    polaris: PropTypes.object
  };

  showToast() {
    console.log("SHOW TOAST");
    console.log(this.context.polaris.appBridge);
    const toastNotice = Toast.create(this.context.polaris.appBridge, {
      message: "Test Toast",
      duration: 5000
    });
    toastNotice.dispatch(Toast.Action.SHOW);
  }

  render() {
    this.showToast();
    return (
      <Page title="Do you see toast?">
        <p>I do not see toast.</p>
      </Page>
    );
  }
}

export default Start;

But it does not seem to dispatch the action. Any ideas on why not? Note that my app is wrapped in the AppProvider and app-bridge is initialized.

 

ReactDOM.render(
  <AppProvider
    apiKey={process.env.REACT_APP_SHOPIFY_API_KEY}
    shopOrigin={queryString.parse(window.location.search).shop}
  >
    <Start />
  </AppProvider>,
  document.getElementById("root")
);

Any ideas on why this doesn't work?

Accepted Solution (1)
skuharmony
Shopify Partner
27 2 6

This is an accepted solution.

Well with help from @hannachen we tracked down the bug. It turns out that inside App Bridge, before taking any action, they check that the localOrigin matches the appURL (one that's entered in the partners dashboard). In my case, I have a backend (node.js on heroku used for authentication) and a frontend (react bundle on firebase) my app starts by hitting the backend, and then if authentication checks out, it redirects to the front end. And hence the localOrigin does not match... hmmm, I'm very glad to have figured this out since I lost a lot of sleep over it. Now the question is what to do about it... maybe this is something that could be updated with AppBridge? Or is there a better design I should be considering?

View solution in original post

Replies 31 (31)

iain-campbell
Shopify Staff (Retired)
54 9 23

Hi Chad! I'm puzzled too; your code looks good. What version of Polaris are you using?

To learn more visit the Shopify Help Center or the Community Blog.

skuharmony
Shopify Partner
27 2 6

Hi Brian, these are my versions:

"dependencies": {
    "@shopify/polaris": "^3.11.0",
    "query-string": "^6.4.0",
    "react": "^16.8.5",
    "react-dom": "^16.8.5",
    "react-redux": "^6.0.1",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8",
    "redux": "^4.0.1"
  }
iain-campbell
Shopify Staff (Retired)
54 9 23

Hmmm, I don't see any problems. Two more things to try:

1) Are there any errors or warnings in the console when you run your app in Shopify Admin?

2) Follow our documentation on using the Redux DevTools and let me know what you see when the app loads.

To learn more visit the Shopify Help Center or the Community Blog.

skuharmony
Shopify Partner
27 2 6

One warning in the console:

[bugsnag] notify endpoint is set but sessions endpoint is not. No sessions will be sent.

Screen Shot 2019-04-03 at 2.21.01 PM.png 

skuharmony
Shopify Partner
27 2 6

And no sign of my toast action in Redux Dev Tools:

Screen Shot 2019-04-03 at 2.20.39 PM.png

hannachen
Shopify Staff
54 8 17

Hi Chad, Hanna here taking over for Iain while he's away.

 

The code in your OP looks to be correct, I'm curious about the reason behind using the `Toast` action from App Bridge vs `Feedback indicators` from Polaris (https://polaris.shopify.com/components/feedback-indicators/toast#section-use-in-an-embedded-applicat...). The difference between the two can be a bit confusing, and I was wondering if there was a particular reason for using the `Toast` action?

 

Another question I have is whether you have `@shopify/app-bridge` in your `package.json`?

Hanna | 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

skuharmony
Shopify Partner
27 2 6

Hi Hanna. I'm just using the `Toast` as a way of proving that the app-bridge is working. Is there another App-Bridge action I should test?

skuharmony
Shopify Partner
27 2 6

My dependencies:

 

"dependencies": {
    "@shopify/app-bridge": "^1.2.0",
    "@shopify/polaris": "^3.11.0",
    "query-string": "^6.4.0",
    "react": "^16.8.5",
    "react-dom": "^16.8.5",
    "react-redux": "^6.0.1",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8",
    "redux": "^4.0.1"
  }
hannachen
Shopify Staff
54 8 17

I see! In that case, could you please confirm that `@shopify/app-bridge` is in your `package.json`?

Hanna | 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

skuharmony
Shopify Partner
27 2 6

see above 🙂

hannachen
Shopify Staff
54 8 17

Oops, thanks! Hmm, it's still not working even with `@shopify/app-bridge` package installed? 🤔

Hanna | 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

skuharmony
Shopify Partner
27 2 6

Nope 😞

skuharmony
Shopify Partner
27 2 6

Any other ideas? Do you have a repo with App-Bridge and React working together?

hannachen
Shopify Staff
54 8 17

I ran out of ideas 😞 So I wanted to try out your code in my own test app: https://github.com/hannachen/polaris-app-test

 

Somehow, it appears to be working for me after I added the necessary npm packages! Looking at packages.json, index.jsx, and Start.jsx, does anything stand out as different from your setup?

Hanna | 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

skuharmony
Shopify Partner
27 2 6

They look the same! Can I invite you to a DEV store so you can see my app deployed and confirm it doesn't work. Email me at hello@saskatoonlabs.com and I'll add you.

skuharmony
Shopify Partner
27 2 6

This is an accepted solution.

Well with help from @hannachen we tracked down the bug. It turns out that inside App Bridge, before taking any action, they check that the localOrigin matches the appURL (one that's entered in the partners dashboard). In my case, I have a backend (node.js on heroku used for authentication) and a frontend (react bundle on firebase) my app starts by hitting the backend, and then if authentication checks out, it redirects to the front end. And hence the localOrigin does not match... hmmm, I'm very glad to have figured this out since I lost a lot of sleep over it. Now the question is what to do about it... maybe this is something that could be updated with AppBridge? Or is there a better design I should be considering?

hannachen
Shopify Staff
54 8 17

Hey Chad! After consulting with my team, it's recommended that both front-end and back-end live under the same hostname. That's because the check is in place for security. We need to ensure apps are being served from an expected source, and not redirected to an arbitrary URL. So unfortunately, it's not something that can be changed on the App Bridge side.

 

I normally look into frameworks that will handle both front-end and back-end for me under the same project. Might something like NextJS work for you? https://help.shopify.com/en/api/tutorials/build-a-shopify-app-with-node-and-react

Hanna | 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

skuharmony
Shopify Partner
27 2 6
Next.js is a good suggestion. I’ll look into it.

jordanskole
Shopify Partner
5 0 6

Man am I glad I found this thread. I think there are a couple of points I would like to make:

 

  • It's fine for that to be an explicit policy decision, but right now appbridge fails silently and without error. This is extremely frustrating, since many people build react and SPA apps using a client/server model. I designed my application the same way as chad, and I think there are many others. I would have taken a different approach if the documentation around appBridge and AppProvider were better documented and/or threw the errors. 
  • The security model is a good one, but appBridge should allow for other hosts whitelisted in the redirect section of the app settings in Shopify Partners, not just the root appurl.  
banned
jordanskole
Shopify Partner
5 0 6

An update on my end, to anybody else that finds their way here. 

 

I was able to correct this rather quickly, (although hacky) by adding an `/auth` route to react-router, that grabs the query string parameters, and redirects the whole thing to my server infrastructure where I handle authentication state checks. 

 

const App: React.SFC = () => {
  return (
    <Router>
      <Route path="/auth" exact render={() => window.location.href = REDIRECT_URL  } />
      <Route path="/a" render={() => <AuthRoutes {...props} />} />
    </Router> 
  )
}

 

 

banned
LukaszWiktor
Shopify Partner
314 24 120

I encountered the same issue, although my app front-end and back-end is running on the same server, and the localOrigin matches the App URL specified in Partner Dashboard. After 2 hours, I've finally figured out what was wrong. In my case it was the shopOrigin starting with https://

 

 

var app = AppBridge.createApp({
    apiKey: "<%= api_key %>",
    shopOrigin: "https://<%= shop %>.myshopify.com",
});

 

 

These options used to work with EASDK, but are causing an error with App Bridge.

Chrome Dev Console was silent about this. Thankfully, Firefox revealed the error:

 

app-bridge-shop-origin-error.png

To sum up, the correct value for shopOrigin can't include https://. Only shop name followed by .myshopify.com

 

 

var app = AppBridge.createApp({
    apiKey: "<%= api_key %>",
    shopOrigin: "<%= shop %>.myshopify.com",
});

 

@hannachen maybe it would be worth allowing the shopOrigin to start with https://? This would make the migration from EASDK to App Bridge easier. Or at least give an example of a valid shopOrigin in the docs here https://help.shopify.com/en/api/embedded-apps/shop-origin.

 

I'm a software engineer. I make things happen automatically.
Check out my apps Exporteo, Fulfilleo, Stockeo, and Personal Discount.
iain-campbell
Shopify Staff (Retired)
54 9 23

Hi Lukasz,

 

Thanks for the feedback. The change to shopOrigin could use more visibility, so as of v1.6.0, App Bridge throws an informative error when the shopOrigin starts with https://. 

To learn more visit the Shopify Help Center or the Community Blog.

LukaszWiktor
Shopify Partner
314 24 120

Hi @iain-campbell,

 

Thanks for the update. I like this change!

 

I'm a software engineer. I make things happen automatically.
Check out my apps Exporteo, Fulfilleo, Stockeo, and Personal Discount.
rgb
Shopify Partner
23 0 6

I have my `/auth` route running on a different service than my frontend, so my App URL in my app settings is `https://abc123.ngrok.io/auth`. My auth backend will then redirect the user to 'https://abc123.ngrok.io/'. I got this to work just fine using the new App Bridge in Polaris v3 (although it took forever to figure out why my app wouldn't load and there were no helpful error messages). 

 

If any others are experiencing this issue, then create a new app and try run your app in there. I ran into this issue and it ran fine in a newly created Shopify app. I think some older apps are interacting with the iframe in a legacy way. 

rycerz
New Member
6 0 0

How do You use the new Provider mechanism in the context of React Hospify App tutorial?

https://developers.shopify.com/tutorials/build-a-shopify-app-with-node-and-react/build-your-user-int...

 

The following construction does not work, although it does not produce error, just no connection to the list of products (button does not respond):

 
<React.Fragment>
        <Head>
          <title>Sample App</title>
          <meta charSet="utf-8" />
        </Head>
        <AppProvider>
           <Provider shopOrigin={this.state.shopOrigin} apiKey={API_KEY}>
          <Component {...pageProps} />
          </Provider>
        </AppProvider>
      </React.Fragment>
rgb
Shopify Partner
23 0 6

I don't use `Provider`, just the `AppProvider` component. I'm pretty sure `AppProvider` connects to App Bridge for you. It also gets the `shopOrigin` for you as well. 

 

 

<AppProvider apiKey={apiKey} forceRedirect>
  <App />
</AppProvider>

 

 

rycerz
New Member
6 0 0

Yes, but it is deprecated and will be abandoned soon.

rgb
Shopify Partner
23 0 6

Well I hope they make it actually work before then...

Adam_Hurlburt
Explorer
41 1 11

I'm also having trouble getting Toasts (from @shopify/app-bridge-react) working with the new Provider. I've had a lot of trouble moving to the new Provider from the EmbeddedAppSDK the docs seem half baked (saw some solutions that differ from official docs) and it's very frustrating, I feel the gun has been jumped on the deprecation, the latest tutorials still use the EASDK (though looks like the code has now been updated on github). 

 

I don't see the toast at all, no errors:

 

          <AppProvider>
            <Provider config={config}>
              <Toast 
                content="Test" onDismiss={this.dismissToast} />
              <Component {...pageProps} />
            </Provider>
          </AppProvider>

would appreciate any help.. 

 

Also, if I put the toast in a subcomponent and get this error:

 Element type is invalid: expected a string (for built-in components)

That error doesn't appear when I put the toast in the main app component for testing (first snippet above) but as mentioned it fails silently, any help is appreciated.

iain-campbell
Shopify Staff (Retired)
54 9 23

Hi Adam, would you mind posting this in a new thread? It helps other people find solutions if we can keep each thread to a single topic.

To learn more visit the Shopify Help Center or the Community Blog.

Adam_Hurlburt
Explorer
41 1 11

Sure, I thought this was related. Turns out my code worked as expected but I was testing it outside of the Shopify admin for local dev and the toasts weren't appearing there.