npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@gadgetinc/react-shopify-app-bridge

v0.16.5

Published

<div align="center"> <p> <img alt="Gadget logo" src="https://raw.githubusercontent.com/gadget-inc/js-clients/main/docs/assets/gadget-logo.png" /> </p> <p> <a href=""> <img alt="GitHub CI status" src="https://badgen.net/github/checks/ga

Downloads

22,461

Readme

Features

This library implements the following features:

  • 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

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:

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

Full installation instructions can be found in the Gadget docs at https://docs.gadget.dev/api/<my-app-slug>/external-api-calls/installing.

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

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

Purpose

While exploring Shopify embedded app development, you may have come across documentation on how to set up Shopify App Bridge. This package will take care of all steps involving OAuth and initializing the Shopify app bridge. The OAuth steps as well as initializing the Shopify app bridge is handled by the Provider. The initialized instance of App Bridge is accessible via the appBridge key returned from useGadget.

Example usage

NOTE: This example is very similar to that found in @gadgetinc/react, however, this example should be followed if you're using the @gadgetinc/react-shopify-app-bridge package.

src/api.ts

// replace `my-app-slug` with your app slug from your Gadget app's domain
import { Client, BrowserSessionStorageType } from "@gadget-client/my-app-slug";

export const api = new Client({
  authenticationMode: {
    browserSession: {
      storageType: BrowserSessionStorageType.Temporary,
    },
  },
});

src/app.tsx

// import Gadget's react hooks for accessing data from your Gadget app
import { useAction, useFindMany } from "@gadgetinc/react";
// import the Gadget<->Shopify bindings that manage the auth process with Shopify
import { AppType, Provider as GadgetProvider, useGadget } from "@gadgetinc/react-shopify-app-bridge";
// import and use Shopify's react components like you might in other Shopify app
import { Button, Redirect, TitleBar } from "@shopify/app-bridge/actions";
// import the instance of the Gadget API client for this app constructed in the other file
import { api } from "./api";

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, and will automatically redirect to perform the OAuth authentication if the shopify shop doesn't yet have the store installed.
    <GadgetProvider type={AppType.Embedded} shopifyApiKey="REPLACE ME with api key from Shopify partners dashboard" api={api}>
      <ProductManager />
    </GadgetProvider>
  );
}

// An example component that uses the Gadget React hooks to work with data in the Shopify backend
function ProductManager() {
  const { loading, appBridge, isRootFrameRequest, isAuthenticated } = useGadget();
  const [, deleteProduct] = useAction(api.shopifyProduct.delete);
  const [{ data, fetching, error }, refresh] = useFindMany(api.shopifyProduct);

  if (error) return <>Error: {error.toString()}</>;
  if (fetching) return <>Fetching...</>;
  if (!data) return <>No products found</>;

  // Set up a title bar for my embedded app
  const breadcrumb = Button.create(appBridge, { label: "My breadcrumb" });
  breadcrumb.subscribe(Button.Action.CLICK, () => {
    appBridge.dispatch(Redirect.toApp({ path: "/breadcrumb-link" }));
  });

  const titleBarOptions = {
    title: "My page title",
    breadcrumbs: breadcrumb,
  };
  TitleBar.create(appBridge, titleBarOptions);

  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>}
      {!loading &&
        isAuthenticated &&
        data.map((product) => (
          <button
            onClick={(event) => {
              event.preventDefault();
              void deleteProduct({ id: product.id }).then(() => refresh());
            }}
          >
            Delete {product.name}
          </button>
        ))}
    </>
  );
}

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.

// import Gadget's react hooks for accessing data from your Gadget app
// import the Gadget<->Shopify bindings that manage the auth process with Shopify
import { AppType, Provider as GadgetProvider } from "@gadgetinc/react-shopify-app-bridge";
// import and use Shopify's react components like you might in other Shopify app
import { useMemo } from "react";
// import the instance of the Gadget API client for this app constructed in the other file
import { BrowserRouter, useLocation, useNavigate } from "react-router-dom";
import { api } from "./api";
// import your app's custom routes
import Routes from "./Routes";

function App() {
  const navigate = useNavigate();
  const location = useLocation();
  const history = useMemo(() => ({ replace: (path) => navigate(path, { replace: true }) }), [navigate]);

  const router = useMemo(
    () => ({
      location,
      history,
    }),
    [location, history]
  );

  return (
    // Wrap our main application's react components in the `<GadgetProvider/>` component to interface with Shopify
    // 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.
    <GadgetProvider
      type={AppType.Embedded}
      shopifyApiKey="REPLACE ME with api key from Shopify partners dashboard"
      api={api}
      router={router}
    >
      <Routes />
    </GadgetProvider>
  );
}

export default function AppWrapper() {
  return (
    <BrowserRouter>
      <App />
    </BrowserRouter>
  );
}