Questions and discussions about using the Shopify CLI and Shopify-built libraries.
I am struggling to get @shopify/app-bridge working with my react based embedded app(with RoR setup). I am using react-router and want my history to propogate to shopify admin main url. So when I use following it works all fine:
// RoutePropagator.jsx export default withRouter(function RoutePropagator({ location }) { ShopifyApp.pushState(location.pathname); return null; });
// And I render it in my main app like so: import React from 'react' import { BrowserRouter as Router, Switch, Route } from "react-router-dom" import enTranslations from '@shopify/polaris/locales/en.json' import {Card, Tabs, AppProvider, Page} from '@shopify/polaris' import { transitions, positions, Provider as AlertProvider } from 'react-alert' import AlertTemplate from 'react-alert-template-basic' import { Link } from 'react-router-dom' import { Provider as AppBridgeProvider } from '@shopify/app-bridge-react' import {getShopOrigin} from '@shopify/app-bridge' import RoutePropagator from './RoutePropagator' .... .... function AdapterLink ({ url, ...rest }) { return <Link to={url} {...rest} /> } const alertOptions = { position: positions.BOTTOM_CENTER, timeout: 5000, offset: '30px', transition: transitions.SCALE } export default function App(props) { return ( <AlertProvider template={AlertTemplate} {...alertOptions}> <Router> <AppProvider i18n={enTranslations} linkComponent={AdapterLink}> <AppBridgeProvider config={{ apiKey: ShopifyApp.apiKey, shopOrigin: getShopOrigin() }} > <RoutePropagator /> <Page title='My title' style={{maxWidth: '100%'}}> <Switch> <Route exact path={somePath} component={ABC} /> </Switch> </Page> </AppBridgeProvider> </AppProvider> </Router> </AlertProvider> ); }
As you can see i am using both providers from polaris and react-app-bridge, thats because polaris does not work without its provider(complaints about i18 translations). Anyway, main point is not these providers here, i have been playing around with app-bridge for a long time to get something working without any luck so far, explored numerous issues on github and community forums as well as I exploring docs and code of these libraries on github.
Issue is, ShopifyApp.pushState(location.pathname); works, but if I change this component to:
import React from 'react'; import { withRouter } from 'react-router'; import createApp from '@shopify/app-bridge'; import {History} from '@shopify/app-bridge/actions'; export default withRouter(function RoutePropagator({ location }) { // const app = React.useContext(AppBridgeContext); const app = createApp({ apiKey: ShopifyApp.apiKey, shopOrigin: ShopifyApp.shopOrigin.slice(8), }); const history = History.create(app); history.dispatch(History.Action.PUSH, `${location.pathname}`); console.log(location); // ShopifyApp.pushState(location.pathname); return null; });
It neither complaints about anything neither does it work.
I also obviously tried official way:
import React from 'react'; import {withRouter, RouteComponentProps} from 'react-router'; import {RoutePropagator} from '@shopify/react-shopify-app-route-propagator'; import {Context as AppBridgeContext} from '@shopify/app-bridge-react'; export default withRouter(function Routes(props) { console.log(props); const app = React.useContext(AppBridgeContext); console.log(AppBridgeContext) console.log(app); console.log(!props.server && app && props.location); return !props.server && app && props.location ? ( <RoutePropagator location={props.location} app={app} /> ) : null; });
But no luck, this actually goes into the action till this line: https://github.com/Shopify/quilt/blob/master/packages/react-shopify-app-route-propagator/src/hook.ts... to make it work, but location never propagates to the URL.
I added breakpoints and did my debugging to conclude it does go here but location never changes.
So all the variations I have tried to use app-bridge have gone in vain, and I think I am stuck with EASDK for now. Unless there is any resolution to this issue i will have to build my whole app around EASDK and just hope it does not get deprecated.
I am happy to share anymore details or whatever needed.
Also if this belongs in github issue, please mention so I can move it to there.
Solved! Go to the solution
This is an accepted solution.
Hi ziatkxel,
Ah yes, you're right. If you created your app using the `shopify_app` gem, it comes with `app.js` and EASDK initializers. Unfortunately, `shopify_app` gem is not compatible with App Bridge out of box at the moment. To get App Bridge running, please try these steps below:
Locate this line in `embedded_app.html.erb` template file and remove it:
<script src="https://cdn.shopify.com/s/assets/external/app.js?<%= Time.now.strftime('%Y%m%d%H') %>"></script>
Also remove instances of EASDK initialization code:
document.addEventListener('DOMContentLoaded', () => { var data = document.getElementById('shopify-app-init').dataset; ShopifyApp.init({ apiKey: data.apiKey, shopOrigin: data.shopOrigin, debug: data.debug === 'true', forceRedirect: true }); });
Once EASDK has been removed, App Bridge functionalities should work as expected. Please give that a try, thanks!
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
Hi ziatkxel 👋
Thanks for the detailed description of this issue. I too expect the `History` push action to behave just like `ShopifyApp.pushState()`. The lack of error messages leads me to suspect this might be a result of a quirk when App Bridge and EASDK are initialized simultaneously in one view. Could you check if that might be the case? Where EASDK's `app.js` is included somewhere on the same view as your App Bridge App?
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
Hi Hanna,
Thankyou so much for the response. And yes, it does, I am actually using shopify_app RoR gem, which, as it seems, automatically adds this code:
document.addEventListener('DOMContentLoaded', () => { var data = document.getElementById('shopify-app-init').dataset; ShopifyApp.init({ apiKey: data.apiKey, shopOrigin: data.shopOrigin, debug: data.debug === 'true', forceRedirect: true }); });
Among few other settings it does. I opted to use react within a rails application, so my app renders the react app/code after authentication is doen using the shopify_app gem.
I think just having shopify_app gem might mean it includes easdk automatically(thats why the above code work, right?) but I am not sure. As this is also the official shopify library. I hope you can get me some clarification on this. And i will be happy to change my code to remove easdk initialization and check if it works without that.
This is an accepted solution.
Hi ziatkxel,
Ah yes, you're right. If you created your app using the `shopify_app` gem, it comes with `app.js` and EASDK initializers. Unfortunately, `shopify_app` gem is not compatible with App Bridge out of box at the moment. To get App Bridge running, please try these steps below:
Locate this line in `embedded_app.html.erb` template file and remove it:
<script src="https://cdn.shopify.com/s/assets/external/app.js?<%= Time.now.strftime('%Y%m%d%H') %>"></script>
Also remove instances of EASDK initialization code:
document.addEventListener('DOMContentLoaded', () => { var data = document.getElementById('shopify-app-init').dataset; ShopifyApp.init({ apiKey: data.apiKey, shopOrigin: data.shopOrigin, debug: data.debug === 'true', forceRedirect: true }); });
Once EASDK has been removed, App Bridge functionalities should work as expected. Please give that a try, thanks!
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
Hi Hanna,
Thanks for the tip, it seems to have solved the original issue and propagating route properly. I am assuming alerts and other components will also work from app-bridge now.
But one other issue has came up. That is, in the OAuth process, i get this message and redirection does not happen back to urbangalleria from app url(which this ngrok one in develoment):
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://urban-galleria-home.myshopify.com') does not match the recipient window's origin ('https://26c232bc.ngrok.io'). MessageTransport.js:107
MessageTransport.js is from app-bridge, so i don't know what issue is here. I am not sure if we should continue this issue in this thread or make a new thread for this one.
I think it makes sense to continue here. I will do some hit and trial in the meantime and will post any updates here.
Adding forceRedirect: true to the config of app-bridge provider solved that issue as well.
Thank-you so much.
I'm so happy to hear that you got it all working! Thank you for sharing your solution with using `forceRedirect: true`, it'll be helpful to others.
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