Questions and discussions about using the Shopify CLI and Shopify-built libraries.
I am trying to use the hook for App Bridge but it is blowing chunks because I don't know. Please assist. So I load the useAppBridge. I then call it. I then try and use it. But the browser barks back at me this Uncaught Error. I was assuming the call to the hook useAppBridge, would return an App Bridge instance. Apparently, I was wrong. What is the deal here?
Uncaught Error: No AppBridge context provided. Your component must be wrapped in an AppBridge <Context> component.useAppBridge
useAppBridge.js:16
import { Provider, TitleBar, useAppBridge } from '@shopify/app-bridge-react';
import { getSessionToken } from '@shopify/app-bridge-utils';
const instance = axios.create();
export default instance;
function MyApp() {
const [status, setStatus] = useState();
const app = useAppBridge();
instance.interceptors.request.use(
function (config) {
return getSessionToken(app) // requires an App Bridge instance
.then((token) => {
config.headers['Authorization'] = `Bearer ${token}`;
console.log("Token from callback ", token);
return config;
});
}
);
Solved! Go to the solution
This is an accepted solution.
Solved. Just had to ensure any call to useAppBridge() is in a component already a child of the Provider component, which instantiates App Bridge.
What happens when you try the sample that's listed in the Shopify docs? https://shopify.dev/tools/app-bridge/react-components/provider
Specifically, this one sample. I'm still stuck in the Dark Ages using the Embedded App SDK and haven't played much with the App Bridge SDK...
import React from 'react';
import {Provider, useAppBridge} from '@shopify/app-bridge-react';
function MyFunctionalComponent() {
const app = useAppBridge();
return (
<div>
{(app) => {
// Do something with App Bridge `app` instance...
if (app) {
app.getState().then((state) => console.log(state));
}
return <span>Hello world!</span>;
}}
</div>
);
};
function MyApp() {
const config = {apiKey: '12345', shopOrigin: shopOrigin};
return (
<Provider config={config}>
<MyFunctionalComponent />
</Provider>
);
}
const root = document.createElement('div');
document.body.appendChild(root);
ReactDOM.render(<MyApp />, root);
That example fails. Shopify is sloppy in their examples BTW. As a brief explanation of that, note that they use a ReactDOM render call, but there is no import of ReactDOM. So that tells you how much care they took with this concept. Nearly none I suspect. So we need to be careful of copy and pasting their example code!!
Simply put. If I use an old school way of dealing with App Bridge, I do indeed get working code. For example, this code works:
import createApp from '@shopify/app-bridge';
window.app = createApp({
apiKey: data.apiKey,
shopOrigin: data.shopOrigin,
});
console.log("What is a window.app? ", window.app);
But this more modern code, supposedly in place, does not work. And that is what I am curious about.
import { Provider, TitleBar, useAppBridge } from '@shopify/app-bridge-react';
function MyApp() {
const app = useAppBridge();
console.log("And what is App from useAppBridge: ", app);
So in the one case, I get an App, in the other, errors.
Uncaught Error: No AppBridge context provided. Your component must be wrapped in an AppBridge <Context> component.
I would like to know why that is. Seems simple enough. I am frustrated because my App only works when I load it after installing it. The install flow is broken due to something internal at Shopify, and my App during install ends up OUTSIDE an iframe, likely because App Bridge.
This is an accepted solution.
Solved. Just had to ensure any call to useAppBridge() is in a component already a child of the Provider component, which instantiates App Bridge.
Pasting the updated code solution would be really helpful here.
AppBridge is now 2.0, and nothing I paste here would help. This issue is too old, and not relevant to the more modern App Bridge. That being said, I pointed out my error and how I fixed it.
thanks for your response, will open a new issue
@HunkyBill I still have an simular problem
I have this code for axios:
const instance = Axios.create();
instance.interceptors.request.use(function (config) {
return getSessionToken(window.app).then((token) => {
config.headers["Authorization"] = `Bearer ${token}`;
return config;
});
});
However that is thrwing the following error:
session-token.js?24e7:65 Uncaught (in promise) TypeError: Cannot read property 'subscribe' of undefined
at eval (session-token.js?24e7:65)
at new Promise (<anonymous>)
at eval (session-token.js?24e7:64)
at step (session-token.js?24e7:52)
at Object.eval [as next] (session-token.js?24e7:33)
at eval (session-token.js?24e7:27)
at new Promise (<anonymous>)
at __awaiter (session-token.js?24e7:23)
at getSessionToken (session-token.js?24e7:62)
at eval (install.js?9ca1:8)
On my _app I have component inside the Provider as you recommended.
Did you find any solution to this? Just want to create a reusable `axios` instance, but don't have `window.app` is undefined!
Sagar @ BullConvert - Modern Sales Booster | Find us on Shopify App Store
✓ Helping merchants increase sales with smarter conversion tools.
✓ Was this helpful? Hit Like or mark as Accepted Solution!