Setting up an app proxy for storefront requests 

Time to build: ~10 minutes

You may need to make requests to your Gadget backend to display dynamic content when building Shopify theme extensions. You can use Shopify app proxies to enable secure communication between a Shopify storefront and an external server, like your Gadget backend.

This tutorial will walk you through setting up a Shopify app proxy to power a banner in a Shopify theme app extension.

This tutorial is teaching proxy setup. To actually build a storefront banner, we recommend you use Shopify metafields and/or configurable Shopify theme extension settings.

Prerequisites 

Before starting this tutorial you need the following:

Step 1: Create a new Gadget app and connect to Shopify 

  1. Start by creating a new Gadget app and connecting to a Shopify development store. You can follow the steps in the Shopify connection quickstart to do this. Select the read_themes scope when prompted to select API scopes. No models are needed for this tutorial.
  2. Install your app on a Shopify development store.

Step 2: Add a global action 

Your Gadget app's API client can be used to make requests to your actions and HTTP routes from the Shopify storefront.

Add a new global action to your app that returns a JSON response:

  1. Add a api/actions/getBanner.js global action to your app.
  2. Paste the following code into api/actions/getBanner.js:
api/actions/getBanner.js
JavaScript
export const run: ActionRun = async ({ logger, connections, session }) => { logger.info( { shopId: connections.shopify.currentShopId, proxy: connections.shopify.currentAppProxy, role: session?.get("roles") || "no role detected", }, "logging proxy context" ); return { body: "This is my banner. How exciting." }; };
export const run: ActionRun = async ({ logger, connections, session }) => { logger.info( { shopId: connections.shopify.currentShopId, proxy: connections.shopify.currentAppProxy, role: session?.get("roles") || "no role detected", }, "logging proxy context" ); return { body: "This is my banner. How exciting." }; };

When building a real app, modify this payload to return dynamic content from your Gadget backend. A logger statement is included so you can see

Gadget handles HMAC validation on proxied requests under the hood.

Permit unauthenticated access to getBanner() 

Requests made from the Shopify storefront are made with the unauthenticated access control role. You need to grant unauthenticated users permission to call getBanner so the action can be called from a theme app extension.

  1. Navigate to accessControl/permissions.
  2. Grant the unauthenticated role access to getBanner.

Gadget also supports customer account authentication in app proxy requests. Read our docs to learn more.

Step 3: Define and deploy your Shopify app proxy 

Now that you have an HTTP route set up, you need to define and deploy your Shopify app proxy.

  1. Add the following to your shopify.app.development.toml file, replacing <APP-NAME> with your Gadget app name:
shopify.app.development.toml
toml
[app_proxy] url = "https://<APP-NAME>--development.gadget.app/api/graphql" subpath = "gadget-banner-tutorial" prefix = "apps"

This assumes you are using the default development environment. If you are using a different environment, replace development in the URL with your environment name and use your environment's TOML file.

  1. Deploy your app configuration changes by running yarn shopify:deploy:development in the Gadget terminal. This will select the development environment TOML and deploy your app proxy definition to Shopify. Make sure to release a new version of your app when prompted.
terminal
yarn shopify:deploy:development

Your Gadget backend is set up, time to build and configure a Shopify theme app extension.

Step 4: Add a theme extension and call the proxy route 

You need to use ggt, Gadget's CLI, to pull down your Gadget project to your local machine to add Shopify extensions to your workspace.

  1. If you don't have ggt installed, you can install it by running:
install ggt
npm install -g @gadgetinc/cli
  1. Use ggt dev to pull down your Gadget project to your local machine. Select your app and environment when prompted. You may need to authenticate first.
pull down your Gadget project
ggt dev

ggt will pull down your Gadget project files to your local machine, and continue to run and sync changes you make to your project.

  1. Install the Shopify CLI, if you haven't already done so.
  2. Create a new theme extension by running the following command in your Gadget project directory:
create a new theme extension
shopify app generate extension

Select the same Shopify organization and app you created earlier during connection, and create a theme app extension. This will add an extensions folder to your Gadget project directory.

Call the proxy route from your theme extension 

Now that you have a theme extension, you can call your proxy route from the theme extension's Liquid code:

  1. Add a banner.liquid file in the extensions/<extension-name>/blocks directory.
  2. Paste the following code into banner.liquid. Replace <APP-NAME> with the name of your app in the script tag and <AppName> with a PascalCase copy of your app name. For example, the app my-banner.gadget.app would use https://my-banner--development.gadget.app/api/client/web.min.js and MyBannerClient.
extensions/<extension-name>/blocks/banner.liquid
<script defer src="https://<APP-NAME>--development.gadget.app/api/client/web.min.js"></script> <script> // Wait for the HTML document to be fully loaded and parsed // This ensures both the DOM is ready and our deferred Gadget script is loaded document.addEventListener("DOMContentLoaded", () => { window.bannerTutorialApi = new <AppName>Client({ browserSession: { shopId: {{ shop.id }} }, // the proxy path defined in your shopify.app.toml file, format: /<prefix>/<subpath> endpoint: "/apps/gadget-banner-tutorial" }); // call global action window.bannerTutorialApi.getBanner() .then((banner) => { document.getElementById("product-banner").innerHTML = banner.body; }); }); </script> <span id="product-banner"></span> {% schema %} { "name": "Gadget Tutorial Banner", "target": "section", "settings": [] } {% endschema %}

This code fetches the banner content from your Gadget backend via the app proxy and displays it in the theme extension.

App proxy URL

The app proxy URL is constructed using the prefix and subpath defined in your shopify.app.development.toml file. In this tutorial, apps is the proxy prefix and gadget-banner-tutorial is the subpath.

Step 5: Testing your app 

Time to test your app! You need to serve your theme extension and add it to your Shopify theme.

  1. Start the Shopify CLI in your Gadget project directory to serve your theme extension. You can either use your local terminal, or the terminal in the Gadget editor:
start your dev server
// in your local terminal shopify app dev // in the Gadget terminal yarn shopify:dev

Select the same development store you installed your app on earlier. You may be prompted for a store password. It can be found in the Shopify admin under Online Store > Preferences.

  1. Open your Shopify development store admin, and navigate to Online Store > Themes, and click Customize on your current theme.
  2. In the theme editor, click on Add section, and select your theme extension from the list. Place the Gadget Tutorial Banner in your theme.

When you navigate to your store's frontend, you should see the banner text "This is my banner" displayed where you placed the theme extension.

If you inspect the network requests in your browser's developer tools, you should see a request to your Gadget backend's proxy route. Your Gadget logs should also show the log message "Received request to /proxy/banner".

Congrats! You have successfully set up a Shopify app proxy to serve dynamic content from your Gadget backend to a Shopify theme extension.

Next steps 

Read our docs on Shopify app proxies here.

If you have any questions about this tutorial, feel free to reach out to Gadget's developer Discord.

Now that you have a working app proxy, you can explore more advanced features and capabilities:

  • Serve dynamic content: Modify the HTTP route to return dynamic content based on query parameters or data from your Gadget models. For example, you could return different banner messages based on the time of day, the user's location, the product being viewed, ...
  • Use the logged_in_customer_id from proxy requests: Serve personalized content to customers, using the shopifyCustomer model in Gadget. See the route HMAC validation guide for more details.

Some of our Shopify templates use app proxies to power dynamic content. You can fork them and explore how they work:

Was this page helpful?