Connecting to Shopify
There are 3 different ways to connect Gadget to your Shopify store.
The Shopify Partners dashboard allows you to manually create a custom or public application that can then be linked to Gadget. If this is your first time trying Gadget, we recommend you follow the Partners dashboard documentation to set up your first connection. A Partners account also allows you to make development stores for testing.
The Shopify CLI is a powerful tool that automatically generates a template for an application that will be embedded in the Shopify Admin. Follow the CLI connection docs to learn how to connect an embedded app, generated with the CLI, to Gadget.
The Shopify store Admin allows you to develop an app right inside a Shopify store environment. You can develop on a live store, or use a Partners account to create a development store.
Public apps can only be created in the Partners Dashboard (Partners and CLI Connection). More information can be found in the Shopify documentation.
Connect to Shopify through the Partners dashboard
To complete this connection, you will need a Shopify Partners account as well as a store or development store
Our first step is going to be setting up a custom Shopify application in the Partners dashboard.
- Go to the Shopify Partners dashboard
- Click on the link to the Apps page
Both the Shopify store Admin and the Shopify Partner Dashboard have an Apps section. Ensure that you are on the Shopify Partner Dashboard before continuing.

- Click the Create App button

- Click the Create app manually button and enter a name for your Shopify app

- Go to the Connections page in your Gadget app

- Copy the Client ID and Client secret from your newly created Shopify app and paste the values into the Gadget Connections page
- Click Connect on the Gadget Connections page to move to scope and model selection

Now we get to select what Shopify scopes we give our application access to, while also picking what Shopify data models we want to import into our Gadget app.
- Select the Read and Write scopes you need for your application
- Select what Shopify models you want to import into your Gadget app
- Click Confirm to connect to the custom Shopify app


We have successfully created our connection!
Now we want to connect our Gadget app to our custom app in the Partners dashboard.
- In your Shopify app in the Partners dashboard, click on App setup in the side nav bar so you can edit the App URL and Allowed redirection URL(s) fields
- Copy the App URL and Allowed redirection URL from the Gadget Connections page and paste them into your custom Shopify App

Now we need to install our Shopify app on a store, and sync data.
Note: If you are using an Event subscriptions version later than 2022-07, you will need to request access permissions in the Protected customer data access section on the App Setup page of your Shopify app. Clicking on Request access will bring you to the access request page. Once there, add requests to any data under Protected customer data.


After completing the required sections in Protected customer access data, return to your Gadget app and navigate to your Shopify connection on the Connections tab. Click on Shop Installs under the Shopify Apps section and register the webhooks.

- Go back to the Shopify Partners dashboard
- Click on Apps to go to the Apps page again
- Click on your custom app
- Click on Select store
- Click on the store we want to use to develop our app
- You may be prompted about Store transfer being disabled. This is okay, click Install anyway
- Click Install app to install your Gadget app on your Shopify store


We will see a success message if our app was successfully installed.

Set up is complete! We are now ready to build our Gadget application.
If we have created at least one product in our store we can test out the connection:
- Go back to our Gadget Connections page and click on the Shop Installs button for the added app in the Shopify Apps section
- Click the Sync button for the installed store
- We should see that the Sync action was a success



That's it! We have successfully set up a store and custom app in Shopify, connected our Gadget app to this store, and synced our store data with our Gadget app.
Connect to an embedded Shopify CLI app
The Shopify CLI requires a Shopify Partners account. It also helps to have a development store on which you can install your custom application.
The first step when using the Shopify CLI (v3.0) to set up a new Gadget app is to follow Steps 1 and 2 from the instructions on Shopify's Create an app page. This will create an application for you and help set up a custom app on the Partners Dashboard.
Do not move to Step 3 yet!
You should also stop your app that is running locally, we need to make some changes to set up the connection to a Gadget backend.
Now we can set up the Shopify connection in Gadget.
- Go to the Connections page in your Gadget app

- Select CLI for your app Connection type

Click on Overiew on the side nav bar for your custom app in the Partners dashboard
Copy the Client ID and Client secret from your newly created Shopify app and paste the values into the Gadget connections page
Now we get to select what Shopify scopes we give our application access to, while also picking what Shopify data models we want to import into our Gadget app.
- Select the Read and Write scopes you need for your application
- Select what Shopify models you want to import into your Gadget app
- Click Confirm to connect to the custom Shopify app


We have successfully created our connection!
- Navigate to your app's App setup page in the Partners Dashboard
- Copy and paste the App URL from the Gadget Connections page into the App URL for your custom app in the Partners Dashboard
- Copy and paste the Allowed redirection URL from the Gadget Connections page into the Allowed redirection URL(s) for your custom app in the Partners Dashboard.


The App URL for your connection is by default set to https://localhost
(for local development). If you already have a deployed frontend, you want to set this App URL to the URL of your deployed app, for example https://my-app.vercel.app.

Now that we have a connection set up, we can finish setting up our Shopify CLI app.
- Update the
dev
script inpackage.json
at the top level to always run with the--no-update
flag
1{2 // ...3 "scripts": {4 "shopify": "shopify",5 "build": "shopify app build",6 "dev": "shopify app dev --no-update",7 "info": "shopify app info",8 "scaffold": "shopify app scaffold",9 "deploy": "shopify app deploy"10 }11}
This prevents the npm run dev
script from replacing your app's App URL and Allowed Redirect URLs in the Partners dashboard with unneeded ngrok tunnel URLs. With Gadget, your backend is already hosted at a real URL, and no tunnel is required.
- Update
web/index.js
to not implement Shopify OAuth, as Gadget handles OAuth and syncing data from the Shopify API. Instead,web/index.js
just needs to serve the frontend application with the correct security headers for Shopify.
Replace the contents of web/index.js
with the following:
web/index.jsJavaScript1// @ts-check2import { join } from "path";3import * as fs from "fs";4import express from "express";5import serveStatic from "serve-static";67const __dirname = new URL(".", import.meta.url).pathname;89const PORT = parseInt(process.env["BACKEND_PORT"] || process.env["PORT"], 10);10const STATIC_PATH =11 process.env["NODE_ENV"] === "production"12 ? `${__dirname}/frontend/dist`13 : `${__dirname}/frontend/`;1415const app = express();1617// return Shopify's required iframe embedding headers for all requests18app.use((req, res, next) => {19 const shop = req.query.shop;20 if (shop) {21 res.setHeader(22 "Content-Security-Policy",23 `frame-ancestors https://${shop} https://admin.shopify.com;`24 );25 }26 next();27});2829// serve any static assets built by vite in the frontend folder30app.use(serveStatic(STATIC_PATH, { index: false }));3132// serve the client side app for all routes, allowing it to pick which page to render33app.use("/*", async (_req, res, _next) => {34 return res35 .status(200)36 .set("Content-Type", "text/html")37 .send(fs.readFileSync(join(STATIC_PATH, "index.html")));38});3940app.listen(PORT);
- You can then delete the other example code that
@shopify/cli
created in theweb/
directory when it created your app if you like by running the following command in your app's root directory
Shellrm -f web/shopify.js web/product-creator.js web/gdpr.js
Finally, we can set up our Gadget Client and use the Provider to handle OAuth for our embedded app.
You need to install your Gadget dependencies in the web/frontend
directory of your Shopify CLI application! Change into this directory before running the next commands:
Shellcd web/frontend
- Install
local-ssl-proxy
in theweb/frontend
directory
npm install local-ssl-proxy
yarn add local-ssl-proxy
- Update the
dev
script inweb/frontend/package.json
tovite & local-ssl-proxy --source 443 --target 3005
.
1{2 // ...3 "scripts": {4 "build": "vite build",5 "dev": "vite & local-ssl-proxy --source 443 --target 3005",6 "coverage": "vitest run --coverage"7 }8}
This allows us to use our local front-end when doing development inside Shopify's admin, which uses HTTPS.
- Replace your
web/frontend/vite.config
file with the following code:
web/frontend/vite.config.jsJavaScript1import { defineConfig } from "vite";2import { dirname } from "path";3import { fileURLToPath } from "url";4import react from "@vitejs/plugin-react";56if (7 process.env["npm_lifecycle_event"] === "build" &&8 !process.env["CI"] &&9 !process.env["SHOPIFY_API_KEY"]10) {11 console.warn(12 "\nBuilding the frontend app without an API key. The frontend build will not run without an API key. Set the SHOPIFY_API_KEY environment variable when running the build command.\n"13 );14}1516const host = "localhost";17const port = 3005;1819export default defineConfig({20 root: dirname(fileURLToPath(import.meta.url)),21 plugins: [react()],22 define: {23 "process.env": JSON.stringify({24 SHOPIFY_API_KEY: process.env["SHOPIFY_API_KEY"],25 }),26 },27 resolve: {28 preserveSymlinks: true,29 },30 server: {31 host: host,32 port: port,33 hmr: {34 protocol: "ws",35 host: host,36 port: port,37 clientPort: port,38 },39 },40});
If you wish to change the port for your local server, make sure to modify both the port variable in web/frontend/vite.config
and the
target at the end of the dev
script in the web/frontend/package.json
. Note that the ports must be the same for the proxy to function
correctly.
Shopify CLI apps using Gadget don't need to use ngrok and instead run at https://localhost
. This vite config keeps vite's hot module reloading functionality working quickly without using ngrok which is faster and more reliable.
- You need to register the Gadget NPM registry for the
@gadget-client
package scope:
web/frontendShellnpm config set @gadget-client:registry https://registry.gadget.dev/npm
- The following npm modules are required when creating an app that will be embedded in the Shopify Admin:
npm install @gadgetinc/react @gadgetinc/react-shopify-app-bridge @gadget-client/example-app
yarn add @gadgetinc/react @gadgetinc/react-shopify-app-bridge @gadget-client/example-app
Make sure to replace `example-app` with your app's package name!
- To deploy your frontend using hosting platforms such as Vercel, Heroku or Netlify, you will need to add a new file
web/frontend/.npmrc
to help point to the Gadget registry.
@gadget-client:registry=https://registry.gadget.dev/npm
- The next step is to set up your Gadget client in the application. You can use this client to make requests to your Gadget application. You can create a new file in your project, and add the following code:
import { Client } from "@gadget-client/example-app";export const api = new Client();
- Now you need to set up the Provider in
web/frontend/App.jsx
. We can also use theuseGadget
hook to ensure we are authenticated before we make requests using the API. Here is a small snippet as an example:
web/frontend/App.jsxJavaScript1import {2 AppType,3 Provider as GadgetProvider,4 useGadget,5} from "@gadgetinc/react-shopify-app-bridge";6import { api } from "./api";78import { PolarisProvider } from "./components";910/**11 Gadget's Provider takes care of App Bridge authentication, you do not need Shopify's default AppBridgeProvider.12*/13export default function App() {14 return (15 <GadgetProvider16 type={AppType.Embedded}17 shopifyApiKey={process.env["SHOPIFY_API_KEY"]}18 api={api}19 >20 <PolarisProvider>21 <EmbeddedApp />22 </PolarisProvider>23 </GadgetProvider>24 );25}2627// This is where we make sure we have auth'd with AppBridge28// Once we have authenticated, we can render our app!29// Feel free to use the default page navigation that Shopify's CLI sets up for you30// example here - https://github.com/gadget-inc/examples/blob/main/packages/shopify-cli-embedded/web/frontend/App.jsx31function EmbeddedApp() {32 // we use `isAuthenticated` to render pages once the OAuth flow is complete!33 const { isAuthenticated } = useGadget();34 return isAuthenticated ? (35 <span>Hello, world!</span>36 ) : (37 <span>Authenticating...</span>38 );39}
If you are looking for examples of how to use our API client, visit our examples repository.
To use App Bridge components from Shopify you will need the useGadget
React hook. More information about the hook can be found in the
useGadget React hook docs.
You can now install your app on a development store from the Partners dashboard. Shopify will redirect you to the embedded app once the installation is complete. You now have an embedded app set up using a Shopify CLI application for your front-end and Gadget as your back-end.
Note: If you are using an Event subscriptions version later than 2022-07, you will need to request access permissions in the Protected customer data access section on the App Setup page of your Shopify app. Clicking on Request access will bring you to the access request page. Once there, add requests to any data under Protected customer data.


After completing the required sections in Protected customer access data, return to your Gadget app and navigate to your Shopify connection on the Connections tab. Click on Shop Installs under the Shopify Apps section and register the webhooks.

To do this:
- Start your local app from the app's root directory
npm run dev
yarn dev
- Go to your app's Overview page in the Partners dashboard
- Click Select store in the Test your app card and follow the installation instructions
We use the local-ssl-proxy
package to create an https proxy so that your local app can be embedded in the Shopify admin. This package
uses a self-signed certificate that Chrome and other browsers may block.
If you're having an issue viewing your embedded app locally, try logging in at https://localhost
. If you see a
NET::ERR_CERT_AUTHORITY_INVALID
message for localhost you will need to click Advanced and then Proceed to localhost.

If you change the credentials of your Shopify application in Gadget, you may encounter an error while trying to install it on your dev store.

To avoid this problem, always make sure your local Shopify CLI app is configured to use the same Shopify app credentials.
To change the app credentials of a local Shopify CLI app, run npm run dev -- --reset
in the root of your project. When prompted to create a new app or connect to an existing app, choose No, connect it to an existing app and select the app with the same credentials set in your Gadget application.
Your local Shopify CLI app credentials now match the expected ones in Gadget, and you can install your app to your development store.
Check out some of our example apps on GitHub, including:
Connect to Shopify through the Store Admin
To complete this connection, you will need a Shopify account and store.
Note: If you want to create a Development Store that is free beyond Shopify's 14-day free trial, you can also sign up for a Shopify Partners account and create a free store there.
- In your Shopify Store Admin, click on Settings, at the bottom left of the screen, to open the Settings window
- Click on the Apps and sales channels option

- Click on Develop apps for your store

- Click Allow custom app development and accept the terms of use (after reading them, of course)
- Click Create an app and enter a name for your custom application

- Click Configure Admin API scopes to select the scopes required by your application

- Select the scopes your application requires and click Save
- Click on the API credentials tab

- Install the app on your store

- In your Gadget app, click on Connections in the nav bar
- Click on the Shopify Admin connection type in your Gadget app

- Enter your store domain
Do not include https://
when copying over your domain, it must be of the store-name.myshopify.com
format!
- Copy credentials (Access Token, API Key, API Secret) over from your Shopify Admin to Gadget

- Select the same scopes that you selected in the Shopify Admin scope selection
- Select the models that you want to import from Shopify

- Click Sync to sync data from Shopify

Congrats! You have set up your Admin Connection!