@gadgetinc/react-shopify-app-bridge 

This package provides React hooks and components for use with Shopify embedded app development with Gadget.

Features 

For Shopify app development, setting up and understanding the Shopify App Bridge is essential.

This package significantly simplifies this process by automating the OAuth authentication and App Bridge initialization.

The Provider takes charge of these complex steps, enabling developers to focus on developing their app's core functionalities. By handling the OAuth flow and initializing the App Bridge, this package removes the intricate setup tasks from the developer's workload. Once the setup is complete, developers can access the initialized App Bridge instance through the appBridge key provided by the useGadget hook, facilitating seamless integration and utilization of the App Bridge's comprehensive features within their Shopify apps.

  • Automatically starts the OAuth process with new users of the application using Gadget, escaping Shopify's iframe if necessary.
  • Establishes an iframe-safe secure session with the Gadget backend using Gadget OAuth PKCE.
  • Sets up the correct React context for making backend calls to Gadget using @gadgetinc/react.

Installation 

If you select the Shopify template upon app creation in Gadget, @gadgetinc/react-shopify-app-bridge is already installed.

This is a companion package to the JavaScript client package generated for your Gadget app. You must first install the JS client for your app, and then install this package.

To install the JS client for your app, you must set up the Gadget NPM registry, and then install the client:

terminal
npm config set @gadget-client:registry https://registry.gadget.dev/npm
yarn add @gadget-client/my-app-slug
# or
npm install @gadget-client/my-app-slug

Once you have your JS client installed, you can install the React hooks library and the Shopify App bridge library with yarn or npm:

terminal
yarn add @gadgetinc/react-shopify-app-bridge @gadgetinc/react @shopify/app-bridge-react react
# or
npm install --save @gadgetinc/react-shopify-app-bridge @gadgetinc/react @shopify/app-bridge-react react

Example usage 

src/api.ts 

JavaScript
1// replace `my-app-slug` with your app slug from your Gadget app's domain
2import { Client, BrowserSessionStorageType } from "@gadget-client/my-app-slug";
3
4export const api = new Client({
5 authenticationMode: {
6 browserSession: {
7 storageType: BrowserSessionStorageType.Temporary,
8 },
9 },
10});

src/app.tsx 

JavaScript
1// import Gadget's react hooks for accessing data from your Gadget app
2import { useAction, useFindMany } from "@gadgetinc/react";
3// import the Gadget<->Shopify bindings that manage the auth process with Shopify
4import {
5 AppType,
6 Provider as GadgetProvider,
7 useGadget,
8} from "@gadgetinc/react-shopify-app-bridge";
9import { TitleBar } from "@shopify/app-bridge-react";
10import React from "react";
11// import the instance of the Gadget API client for this app constructed in the other file
12import { api } from "./api";
13
14export default function App() {
15 return (
16 // Wrap our main application's react components in the `<GadgetProvider/>` component to interface with Shopify
17 // This wrapper sets up the Shopify App Bridge, and will automatically redirect to perform the OAuth authentication if the shopify shop doesn't yet have the store installed.
18 <GadgetProvider
19 type={AppType.Embedded}
20 shopifyApiKey="REPLACE ME with api key from Shopify partners dashboard"
21 api={api}
22 >
23 <ProductManager />
24 </GadgetProvider>
25 );
26}
27
28// An example component that uses the Gadget React hooks to work with data in the Shopify backend
29function ProductManager() {
30 const { loading, appBridge, isRootFrameRequest, isAuthenticated } = useGadget();
31 const [, deleteProduct] = useAction(api.shopifyProduct.delete);
32 const [{ data, fetching, error }, refresh] = useFindMany(api.shopifyProduct);
33
34 if (error) return <>Error: {error.toString()}</>;
35 if (fetching) return <>Fetching...</>;
36 if (!data) return <>No products found</>;
37
38 // Set up a title bar for my embedded app
39 const breadcrumb = Button.create(appBridge, { label: "My breadcrumb" });
40 breadcrumb.subscribe(Button.Action.CLICK, () => {
41 appBridge.dispatch(Redirect.toApp({ path: "/breadcrumb-link" }));
42 });
43
44 const titleBarOptions = {
45 title: "My page title",
46 breadcrumbs: breadcrumb,
47 };
48 TitleBar.create(appBridge, titleBarOptions);
49
50 return (
51 <>
52 {loading && <span>Loading...</span>}
53 {/* A user is viewing this page from a direct link so show them the home page! */}
54 {!loading && isRootFrameRequest && (
55 <div>Welcome to my cool app's webpage!</div>
56 )}
57 {!loading &&
58 isAuthenticated &&
59 data.map((product) => (
60 <button
61 onClick={(event) => {
62 event.preventDefault();
63 void deleteProduct({ id: product.id }).then(() => refresh());
64 }}
65 >
66 Delete {product.name}
67 </button>
68 ))}
69 </>
70 );
71}

Custom router 

@shopify/app-bridge-react allows you to specify a custom router configuration to manage client-side routing. Similarly, the Gadget provider will allow you to specify a custom router which will be forwarded to the App Bridge.

JavaScript
1// import Gadget's react hooks for accessing data from your Gadget app
2import { useAction, useFindMany } from "@gadgetinc/react";
3// import the Gadget<->Shopify bindings that manage the auth process with Shopify
4import {
5 AppType,
6 Provider as GadgetProvider,
7 useGadget,
8} from "@gadgetinc/react-shopify-app-bridge";
9// import and use Shopify's react components like you might in other Shopify app
10import { TitleBar } from "@shopify/app-bridge-react";
11import React, { useMemo } from "react";
12// import the instance of the Gadget API client for this app constructed in the other file
13import { api } from "./api";
14import { useLocation, useNavigate, BrowserRouter } from "react-router-dom";
15// import your app's custom routes
16import Routes from "./api/routes";
17
18function App() {
19 const router = createBrowserRouter(
20 createRoutesFromElements(
21 <Route path="/" element={<Layout />}>
22 <Route index element={<Index />} />
23 <Route path="/about" element={<AboutPage />} />
24 <Route path="*" element={<Error404 />} />
25 </Route>
26 )
27 );
28
29 return (
30 <>
31 <RouterProvider router={router} />
32 </>
33 );
34}
35
36function Layout() {
37 return (
38 // Wrap our main application's react components in the `<GadgetProvider/>` component to interface with Shopify
39 // This wrapper sets up the Shopify App Bridge, and will automatically redirect to perform the OAuth authentication if the Shopify shop doesn't yet have the store installed.
40 <GadgetProvider
41 type={AppType.Embedded}
42 shopifyApiKey="REPLACE ME with api key from Shopify partners dashboard"
43 api={api}
44 >
45 <AuthenticatedApp />
46 </GadgetProvider>
47 );
48}
49
50export default function AppWrapper() {
51 return (
52 <BrowserRouter>
53 <App />
54 </BrowserRouter>
55 );
56}

Breaking changes when upgrading to version 0.14.0 

Because @gadgetinc/react-shopify-app-bridge version 0.14.0 supports App Bridge V4, this requires you to migrate to your app from App Bridge V3.

Otherwise, you will experience many breaking changes to your app, this also means you will have to update any hooks or components that aren't supported by V4. To upgrade your Gadget application to support App Bridge V4, check out our guide here.