Shopify App Proxy Tutorial

The Shopify App proxy allows you to use Shopify as the middleman and route requests from the storefront to your API in a secure manner. This in turn allows you to display dynamic data that is returned from your API on the Shopify Storefront.

Shopify App Proxy Tutorial
Photo by Thomas Tastet / Unsplash

Continuing on with my "Learn Shopify App Development with Me" (I need to think of a better & cooler name). Here's the link to the first post.

Let me set the scene. I got my app deployed with its production configuration and thought I was all set! Wrong. When I tried to use my app in my test store I kept getting everyones favorite error: cors or Cross Origin Resource Sharing . I suppose that this error did make sense because I was calling my deployed api: https://www.example.com/api/posts from the Shopify Storefront using Javascript and the fetch() API. Then I started thinking, do I really want to expose my API directly? Didn't I see something in the Shopify Documentation about some sort of Proxy?

What is Shopify App Proxy?

The Shopify App proxy allows you to use Shopify as the middleman and route requests from the storefront to your API in a secure manner. This in turn allows you to display dynamic data that is returned from your API on the Shopify Storefront.

Example Diagram of Shopify App Proxy

Why use the Shopify App Proxy?

There are a couple of great reasons why you would want to use this.

  • Security
    • You don't have to worry about handling CORS errors on your own.
    • Shopify validate the requests on your behalf & add a context that allows you to use the Shopify API to query data.
const {storefront, liquid} = await authenticate.public.appProxy(request);
  • Simplified Development Workflow
    • Since you are not hitting your API directly you don't need to worry about setting the correct API url for each of your environments. You can simply just hit the store proxy endpoint.
const base = "{{  shop.url }}"
const baseUrl = `${base}/apps/store-pickup`;

fetch(`${baseUrl}?).then(res => res.json()).then(x => console.log(x));

storefront liquid code

  • Recommended Approach by Shopify

Example Utilizing an App Proxy

From the Shopify Documentation they tell you to go into your App in your Shopify Partner Dashboard and add the proxy manually to the app configuration. This will work, however when you are working in a development environment every time that you restart your app you will need to manually go in and update your Proxy URL to point to the new URL that Shopify gives you. I don't know about you but that sounds annoying to me.

An easier way to add an app proxy is to specify it in your config.toml file. If you selected the option to auto update your app urls then AND you have an entry in your .toml configuration file, Shopify will automatically update your App proxy as well. See Github Issue.

[app_proxy]
url = "https://app.example.com/api/proxy"
subpath = "store-pickup"
prefix = "apps"

url is the url of your API that you want Shopify to send the proxied requests to. prefix & subpath are added onto the store url and where you need to make the request to from your Storefront liquid code. The example in the documentation is: https://johns-apparel.myshopify.com/apps/store-pickup`. Any requests that are made to this URL will be proxied through Shopify to your url that you have set in your configuration file.

Remix Implementation

If you want to implement an app proxy with remix you will need to create a new endpoint in remix ex: app/routes/api.proxy.ts . You will want to use a loader function for /GET requests and a action function for all other requests.

import { json, type ActionFunction } from "@remix-run/node";
import { authenticate } from "~/shopify.server";

export const loader = async ({ request }: any) => {
  const { session, storefront } = await authenticate.public.appProxy(request);

  if (!session || !storefront) {
    return new Response("Unauthorized", { status: 401 });
  }

  return json({ message: "Hello from loader proxy!" });
};

export const action: ActionFunction = async ({ request, params }) => {
  const { session } = await authenticate.public.appProxy(request);

  if (!session) {
    return new Response("Unauthorized", { status: 401 });
  }

  return json({ message: "Hello from action proxy!" });
};

Resources

App proxy
[App proxies](/docs/apps/online-store/app-proxies) take requests to Shopify links, and redirect them to external links. The `authenticate.public.appProxy` function validates requests made to app proxies, and returns a context to enable querying Shopify APIs. > Note: If the store has not installed the app, store-related properties such as `admin` or `storefront` will be `undefined`
Display dynamic store data with app proxies
Use app proxies to fetch and display data on the online store from an outside location.