Questions and discussions about using the Shopify CLI and Shopify-built libraries.
In my Rails App, running Polaris, I want to call my API with Axios, via axios.get('/api/shop') to get some good JSON.
I want that to be an authenticated call, so I will let the JWT business do its thing. To that end I see I can use Axios and App Bridge, but it is using a different way of dealing with App Bridge. I use React, so typically I get the Context of App Bridge from the package.
import { Provider, Context, TitleBar, Loading } from '@shopify/app-bridge-react';
And then when I want an App Bridge I just use
const appBridge = useContext(Context);
The Axios code from Shopify is a little different. It attaches some App Bridge object to the window... as window.app, and then the Axios code uses an interceptor to inject a token into my Axios calls from the getSessionToken call. Long story short, how do I use this Axios hack using the interceptor AND the Context? React complains I cannot use Context in this interceptor as it is not a React Component. So am I supposed to use React Axios and that la-dee-da, or is there another way to leverage App Bridge here?
import axios from 'axios';
import { getSessionToken } from '@shopify/app-bridge-utils';
const instance = axios.create();
instance.interceptors.request.use(
function (config) {
const appBridge = useContext(Context); // this is verboten!!
return getSessionToken(appBridge) // requires an App Bridge instance
.then((token) => {
config.headers['Authorization'] = `Bearer ${token}`;
return config;
});
}
);
export default instance;
I solved this by adding the window.app version of App Bridge to my code and that worked. Probably the most clunky use of JS ever, but it works.
Hey @HunkyBill would you be so kind to post an example snippet showing how you make a axios call (ideally to the REST Api if you have it). I am getting all sorts of errors... been at it for a couple of hours now.
If I try to do a get request to the `api/2020-04/themes.json` endpoint using my shop url I get a CORS error even though I am sending the Authorization header
Thank you very much!
A CORS error? How did you manage that? It means you are running your code on domain A but calling domain B? How did you manage that?
The code I posted works fine. I set up an interceptor... and then I call it when I need it.
const app = useAppBridge();
instance.interceptors.request.use(
function (config) {
//console.log(`${req.method} ${req.url}`);
return getSessionToken(app) // requires an App Bridge instance
.then((token) => {
// append your request headers with an authenticated token
config.headers['Authorization'] = `Bearer ${token}`;
config.headers['X-CSRF-Token'] = document.querySelector("meta[name='csrf-token']").content
return config;
});
}
);
const useDataApi = (initialUrl, initialData) => {
const [url, setUrl] = useState(initialUrl);
const [state, dispatch] = useReducer(dataFetchReducer, {
isLoading: true,
isError: false,
data: initialData,
});
useEffect(() => {
let didCancel = false;
const fetchData = async () => {
dispatch({ type: 'FETCH_INIT' });
try {
const result = await instance.get(url);
if (!didCancel) {
dispatch({ type: 'FETCH_SUCCESS', payload: result.data });
}
} catch (error) {
if (!didCancel) {
dispatch({ type: 'FETCH_FAILURE' });
}
}
};
fetchData();
return () => {
didCancel = true;
};
}, [url]);
return [state, setUrl];
};
So this sends the correct header. For me anyway, Axios works. I mean hey, overall, using the React system sucks right, but in the end, for the the crap you put up with, it does work. I know there are a million better ways to do things, but since this is the trendy way to do it today, I go with it. You could for example be even weirder and do all this in Typescript if you like those kinds of things.
Hallo @HunkyBill thank you for your reply. To be honest I am struggling to make a call to the admin REST API theme endpoint. As simple as that... It is my first time developing a Shopify app and I am having trouble doing the most basic things.
The endpoint is located at this URI /admin/api/2020-04/themes.json So what would be the full URL to call it? `<MY_STORE_URL>/admin/api/2020-04/themes.json` generates the CORS error, since I am trying to call it from inside the app iframe. How would you call it?
Thank you!
Hey I'm having the same issue, attempting a simple fetch request in the app front-end gives me a CORS Error policy, haven't found a solution to it yet.