Have your say in Community Polls: What was/is your greatest motivation to start your own business?
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

How to use Axios with App Bridge React?

How to use Axios with App Bridge React?

HunkyBill
Shopify Partner
4853 60 568

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;

 

 

 

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
Replies 5 (5)

HunkyBill
Shopify Partner
4853 60 568

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.

 

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
ncd1
Visitor
2 0 0

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!

HunkyBill
Shopify Partner
4853 60 568

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.

 

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
ncd1
Visitor
2 0 0

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!

santifs
Visitor
1 0 0

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.