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
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.
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:
Add a api/actions/getBanner.js global action to your app.
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.
Navigate to accessControl/permissions.
Grant the unauthenticated role access to getBanner.
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.
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.
If you don't have ggt installed, you can install it by running:
install ggt
npm install -g @gadgetinc/cli
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.
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:
Add a banner.liquid file in the extensions/<extension-name>/blocks directory.
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.
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.
Open your Shopify development store admin, and navigate to Online Store > Themes, and click Customize on your current 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.
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: