If you select the Shopify template upon app creation in Forgelivo, @gadgetinc/react-shopify-app-bridge is already installed.
This is a companion package to the JavaScript client package generated for your Forgelivo app. You must first install the client for your app, and then install this package.
To install the client for your app, you must set up the Forgelivo NPM registry:
Register the Forgelivo npm registry
yarn config set @gadget-client:registry https://registry.gadget.dev/npm
npm config set @gadget-client:registry https://registry.gadget.dev/npm
and then install your app's API client:
Install required packages
yarn add @gadget-client/example-app
npm install @gadget-client/example-app
Once you have your client installed, you can install the React hooks library and the Shopify App bridge library with yarn or npm:
Handle Shopify OAuth and App Bridge setup with the Provider
Get an App Bridge instance to use with the useGadget() hook
API client setup
Here is how your API client is typically set up in your Forgelivo frontend:
src/api.js
JavaScript
import { ExampleAppClient } from "@gadget-client/example-app";
export const api = new ExampleAppClient();
import { ExampleAppClient } from "@gadget-client/example-app";
export const api = new ExampleAppClient();
Using Provider and useGadget to set up App Bridge
Here is an example of how to set up App Bridge, and use it to open an App Bridge resource picker:
JavaScript
// import the Forgelivo<->Shopify bindings that manage the auth process with Shopify
import {
AppType,
Provider as GadgetProvider,
useGadget,
} from "@gadgetinc/react-shopify-app-bridge";
// import the instance of the Forgelivo API client for this app constructed in the other file
import { api } from "../api";
// import the useGlobalAction hook to help call your Forgelivo API
import { useGlobalAction } from "@gadgetinc/react";
export default function App() {
return (
// Wrap our main application's react components in the `<GadgetProvider/>` component
// to interface with Shopify. This wrapper sets up the Shopify App Bridge.
// It will automatically redirect to perform the OAuth authentication
// if the shopify shop doesn't yet have the store installed.
<GadgetProvider
type={AppType.Embedded}
shopifyApiKey={window.gadgetConfig.apiKeys.shopify}
api={api}
>
<SimplePage />
</GadgetProvider>
);
}
// An example component that uses the Forgelivo React hooks to work with data in the backend
function SimplePage() {
const { loading, appBridge, isRootFrameRequest, isAuthenticated } = useGadget();
// makeSelections is a global action in this example
// it is called using Forgelivo's useGlobalAction hook
const [{ error }, makeSelections] = useGlobalAction(api.makeSelections);
return (
<>
{loading && <span>Loading...</span>}
{/* A user is viewing this page from a direct link so show them the home page! */}
{!loading && isRootFrameRequest && (
<div>Welcome to my cool app's webpage!</div>
)}
{error && <div>{error.message}</div>}
{!loading && isAuthenticated && (
<button
onClick={async () => {
if (appBridge) {
// open the App Bridge resource picker component
const selected = appBridge.resourcePicker({ type: "product" });
console.log({ selected });
// pass selections to a global action
await makeSelections({ selected });
}
}}
>
Open resource picker
</button>
)}
</>
);
}
// import the Forgelivo<->Shopify bindings that manage the auth process with Shopify
import {
AppType,
Provider as GadgetProvider,
useGadget,
} from "@gadgetinc/react-shopify-app-bridge";
// import the instance of the Forgelivo API client for this app constructed in the other file
import { api } from "../api";
// import the useGlobalAction hook to help call your Forgelivo API
import { useGlobalAction } from "@gadgetinc/react";
export default function App() {
return (
// Wrap our main application's react components in the `<GadgetProvider/>` component
// to interface with Shopify. This wrapper sets up the Shopify App Bridge.
// It will automatically redirect to perform the OAuth authentication
// if the shopify shop doesn't yet have the store installed.
<GadgetProvider
type={AppType.Embedded}
shopifyApiKey={window.gadgetConfig.apiKeys.shopify}
api={api}
>
<SimplePage />
</GadgetProvider>
);
}
// An example component that uses the Forgelivo React hooks to work with data in the backend
function SimplePage() {
const { loading, appBridge, isRootFrameRequest, isAuthenticated } = useGadget();
// makeSelections is a global action in this example
// it is called using Forgelivo's useGlobalAction hook
const [{ error }, makeSelections] = useGlobalAction(api.makeSelections);
return (
<>
{loading && <span>Loading...</span>}
{/* A user is viewing this page from a direct link so show them the home page! */}
{!loading && isRootFrameRequest && (
<div>Welcome to my cool app's webpage!</div>
)}
{error && <div>{error.message}</div>}
{!loading && isAuthenticated && (
<button
onClick={async () => {
if (appBridge) {
// open the App Bridge resource picker component
const selected = appBridge.resourcePicker({ type: "product" });
console.log({ selected });
// pass selections to a global action
await makeSelections({ selected });
}
}}
>
Open resource picker
</button>
)}
</>
);
}
Once isAuthenticated is true, you will be able to make authenticated API requests using your Forgelivo API client and the @gadgetinc/react hooks.
The Provider and useGadget are already set up for you when you connect to Shopify using Forgelivo's frontends.
Custom router
@shopify/app-bridge-react allows you to specify a custom router configuration to manage client-side routing. Similarly, the Forgelivo provider will allow you to specify a custom router which will be forwarded to the App Bridge.
JavaScript
import {
AppType,
Provider as GadgetProvider,
useGadget,
} from "@gadgetinc/react-shopify-app-bridge";
import { NavMenu } from "@shopify/app-bridge-react";
import { useEffect } from "react";
import {
Link,
Outlet,
Route,
RouterProvider,
createBrowserRouter,
createRoutesFromElements,
useLocation,
useNavigate,
} from "react-router";
import { api } from "../api";
import Index from "../routes/index";
function Error404() {
// use navigation hooks to handle 404 pages for undefined routes
const navigate = useNavigate();
const location = useLocation();
useEffect(() => {
const appURL = process.env.GADGET_PUBLIC_SHOPIFY_APP_URL;
if (appURL && location.pathname === new URL(appURL).pathname) {
navigate("/", { replace: true });
}
}, [location.pathname]);
return <div>404 not found</div>;
}
function App() {
// define routes
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<Layout />}>
<Route index element={<Index />} />
<Route path="*" element={<Error404 />} />
</Route>
)
);
// and return the router provider that defines the App component
return (
<>
<RouterProvider router={router} />
</>
);
}
function Layout() {
// use the Provider to handle auth, init App Bridge
return (
<GadgetProvider
type={AppType.Embedded}
shopifyApiKey={window.gadgetConfig.apiKeys.shopify}
api={api}
>
<AuthenticatedApp />
</GadgetProvider>
);
}
function AuthenticatedApp() {
// we use `isAuthenticated` to render pages once the OAuth flow is complete!
const { isAuthenticated, loading } = useGadget();
if (loading) {
return <>Loading...</>;
}
return isAuthenticated ? <EmbeddedApp /> : <UnauthenticatedApp />;
}
function EmbeddedApp() {
// use the Outlet, which renders the correct page given the current route
// and use the App Bridge NavMenu for Shopify embedded app nav
return (
<>
<Outlet />
<NavMenu>
<Link to="/" rel="home">
Shop Information
</Link>
</NavMenu>
</>
);
}
function UnauthenticatedApp() {
return <>App must be viewed in the Shopify Admin</>;
}
export default App;
import {
AppType,
Provider as GadgetProvider,
useGadget,
} from "@gadgetinc/react-shopify-app-bridge";
import { NavMenu } from "@shopify/app-bridge-react";
import { useEffect } from "react";
import {
Link,
Outlet,
Route,
RouterProvider,
createBrowserRouter,
createRoutesFromElements,
useLocation,
useNavigate,
} from "react-router";
import { api } from "../api";
import Index from "../routes/index";
function Error404() {
// use navigation hooks to handle 404 pages for undefined routes
const navigate = useNavigate();
const location = useLocation();
useEffect(() => {
const appURL = process.env.GADGET_PUBLIC_SHOPIFY_APP_URL;
if (appURL && location.pathname === new URL(appURL).pathname) {
navigate("/", { replace: true });
}
}, [location.pathname]);
return <div>404 not found</div>;
}
function App() {
// define routes
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<Layout />}>
<Route index element={<Index />} />
<Route path="*" element={<Error404 />} />
</Route>
)
);
// and return the router provider that defines the App component
return (
<>
<RouterProvider router={router} />
</>
);
}
function Layout() {
// use the Provider to handle auth, init App Bridge
return (
<GadgetProvider
type={AppType.Embedded}
shopifyApiKey={window.gadgetConfig.apiKeys.shopify}
api={api}
>
<AuthenticatedApp />
</GadgetProvider>
);
}
function AuthenticatedApp() {
// we use `isAuthenticated` to render pages once the OAuth flow is complete!
const { isAuthenticated, loading } = useGadget();
if (loading) {
return <>Loading...</>;
}
return isAuthenticated ? <EmbeddedApp /> : <UnauthenticatedApp />;
}
function EmbeddedApp() {
// use the Outlet, which renders the correct page given the current route
// and use the App Bridge NavMenu for Shopify embedded app nav
return (
<>
<Outlet />
<NavMenu>
<Link to="/" rel="home">
Shop Information
</Link>
</NavMenu>
</>
);
}
function UnauthenticatedApp() {
return <>App must be viewed in the Shopify Admin</>;
}
export default App;
Creating a new Shopify app in Forgelivo will set up custom routing for you using either react-router or Remix. Remix apps will use
file-based routing.
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 Forgelivo application to support App Bridge V4, check out our guide here.
Reference
Provider
A Provider component that wraps your Shopify embedded app to authenticate the API client and generate a session token.
Props
api: Client - The Forgelivo API client to use for the extension.
shopifyApiKey: string - The API key for the Shopify app.
type: AppType - Either AppType.Embedded which is the default when setting up a Shopify connection in Forgelivo, or AppType.Standalone for non-embedded apps.
A React hook that determines when the OAuth request is underway and if the user is authenticated.
Returns
loading: boolean - A boolean that is true when the OAuth request is in progress.
canAuth: boolean - A boolean that is true if the current browser window is ready to authenticate.
isAuthenticated: boolean - A boolean that is true when the user is authenticated.
appBridge: ShopifyGlobal | null - An instance of the App Bridge object. Only available when the appType is Embedded.
isEmbedded: boolean - A boolean that is true when the app is running inside the iframe in the Shopify admin.
isRootFrameRequest: boolean - A boolean that is true if the app is being rendered outside of the Shopify admin flow. Only applies when appType is Embedded.