Shopify app bridge does not work to propagate routes, while EASDK pushState works all fine

Solved
ziatkxel
Shopify Partner
7 0 6

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.

Accepted Solution (1)
hannachen
Shopify Staff
Shopify Staff
54 8 17

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

View solution in original post

Replies 6 (6)
hannachen
Shopify Staff
Shopify Staff
54 8 17

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

ziatkxel
Shopify Partner
7 0 6

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.

hannachen
Shopify Staff
Shopify Staff
54 8 17

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

ziatkxel
Shopify Partner
7 0 6

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.

ziatkxel
Shopify Partner
7 0 6

Adding forceRedirect: true to the config of app-bridge provider solved that issue as well.

 

Thank-you so much.

hannachen
Shopify Staff
Shopify Staff
54 8 17

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