Skip to content

Instantly share code, notes, and snippets.

@adamndev
Last active June 5, 2021 14:47
Show Gist options
  • Save adamndev/8d35066ad479f60ea0c231a5943cb568 to your computer and use it in GitHub Desktop.
Save adamndev/8d35066ad479f60ea0c231a5943cb568 to your computer and use it in GitHub Desktop.
Shopify Apps

Create a Shopify app with Apollo

Create /components/ClientRouter.js

import { withRouter } from 'next/router';
import { ClientRouter as AppBridgeClientRouter } from '@shopify/app-bridge-react';

function ClientRouter(props) {
  const { router } = props;

  return <AppBridgeClientRouter history={router} />;
}

export default withRouter(ClientRouter);

Create /components/RoutePropagator.js

import { useEffect, useContext } from 'react';
import Router, { useRouter } from 'next/router';
import { Context as AppBridgeContext, useRoutePropagation } from '@shopify/app-bridge-react';
import { Redirect } from '@shopify/app-bridge/actions';
import { RoutePropagator as AppBridgeRoutePropagator } from '@shopify/app-bridge-react';

const RoutePropagator = ({ path }) => {
  const router = useRouter();
  const { route } = router;
  const appBridge = useContext(AppBridgeContext);

  useEffect(() => {
    appBridge.subscribe(Redirect.Action.APP, ({ path }) => {
      Router.push(path);
    });
  }, []);

  return appBridge && route ? <AppBridgeRoutePropagator location={route} /> : null;
};

export default RoutePropagator;

Add provider to app:

import ClientRouter from '../components/ClientRouter';
import RoutePropagator from '../components/RoutePropagator';
<React.Fragment>
    <ApolloClientProvider>
        <AppBridgeProvider config={config}>
            <ClientRouter />
            <RoutePropagator />
            ...
        </AppBridgeProvider>
    </ApolloClientProvider>
</React.Fragment>

Create a Shopify app with Apollo

Remove default apollo-boost:

npm remove apollo-boost graphql react-apollo

and remove anything referencing these packages.

Install the Apollo client:

npm i @apollo/client apollo-cache-inmemory apollo-link-http

Add Apollo to _app.js:

import { HttpLink } from 'apollo-link-http';
import { ApolloProvider, ApolloClient } from '@apollo/client';
import { InMemoryCache } from 'apollo-cache-inmemory';

function userLoggedInFetch(app) {
  const fetchFunction = authenticatedFetch(app);

  return async (uri, options) => {
    const response = await fetchFunction(uri, options);

    if (
      response.headers.get("X-Shopify-API-Request-Failure-Reauthorize") === "1"
    ) {
      const authUrlHeader = response.headers.get(
        "X-Shopify-API-Request-Failure-Reauthorize-Url"
      );

      const redirect = Redirect.create(app);
      redirect.dispatch(Redirect.Action.APP, authUrlHeader || `/auth`);
      return null;
    }

    return response;
  };
}

function MyProvider(props) {
  const app = useAppBridge();

  const client = new ApolloClient({
    fetch: userLoggedInFetch(app),
    fetchOptions: {
      credentials: "include",
    },
  });

  const Component = props.Component;

  return (
    <ApolloProvider client={client}>
      <Component {...props} />
    </ApolloProvider>
  );
}

Access the Apollo client and send queries like this:

import { Heading, Page } from '@shopify/polaris';
import { gql, useQuery } from '@apollo/client';

const GET_SHOP_NAME = gql`
  {
    shop {
      name
    }
  }
`;

const Index = () => {
  const { loading, error, data } = useQuery(GET_SHOP_NAME);
  if (loading) return <p>Loading ...</p>;
  if (error) return <p>Error ...</p>;

  return (
    <Page>
      <Heading>Hello {data.shop.name}! 🎉</Heading>
    </Page>
  );
};

export default Index;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment