App proxies

You can use an app proxy to fetch data from an app proxy server for display on a page of the online store. This means that you can use app proxies for dynamic content that needs to be updated regularly. App proxies are useful for displaying image galleries, statistics, or custom forms. You don't need to set up app proxies before publishing an app. If you add an app proxy to an app after you've published it, then existing installations of the app are updated automatically. App proxies support Liquid, Shopify's template language. You can use Liquid within your proxy page as if the page is a part of the online store's theme.

Add an app proxy

To add a proxy to your app, you need to make sure the app is set up for the online store area of Shopify. Then you can continue with adding the proxy:

  1. From your Partner Dashboard, click Apps.
  2. Click the name of your app.
  3. Click Extensions.
  4. In the App proxy section, click Add proxy.
  5. Select a prefix from the Sub path prefix drop-down list. If you want to add a sub path, then enter it in the Sub path field:

    These settings determine which HTTP requests to Shopify are proxied to the proxy URL entered in the next step. For example, if the sub path prefix is apps, and the sub path is store-pickup, then any path in your shop after https://your-store.myshopify.com/apps/store-pickup is proxied to the provided proxy URL.

  6. Enter the URL of your proxy server in the Proxy URL field. This is the URL that will be proxied from the path that you entered in the previous step.

  7. When you're done, click Save.

Example

Consider the following app proxy configuration:

  • Sub path prefix: apps
  • Sub path: my-app-proxy
  • Proxy URL: https://my-app-proxy.com/app_proxy

In this example, https://example-store.myshopify.com/apps/my-app-proxy/app_path forwards to the proxy URL at https://my-app-proxy.com/app_proxy/app_path.

The merchant experience of an app proxy

Merchants can change the sub path or sub path prefix of app proxies. Merchants change the sub path prefix by toggling between a set of values provided by Shopify (/apps,/a,/community, or /tools). The combination of sub path prefix and sub path defines where the app proxy is accessed from a merchant's shop. Merchants can change this information to get a friendlier URL that appears to originate from the merchant's domain. The sub path doesn't affect the location of the proxy URL that you provide in the Proxy URL field.

Handling proxy requests

The following examples show an app proxy definition:

  • proxy URL: https://proxy-domain.com/proxy
  • client IP: 123.123.123.123
  • shared secret: hush

When the following HTTP request is sent from the client, Shopify forwards the request using the specified proxy URL:

GET /apps/awesome_reviews/extra/path/components?extra=1&extra=2 HTTP/1.1
  Host: shop-domain.com
  Cookie: csrftoken=01234456789abcdef0123456789abcde;
  _session_id=1234456789abcdef0123456789abcdef;
  _secure_session_id=234456789abcdef0123456789abcdef0

The forwarded request looks like the following:

GET /proxy/extra/path/components?extra=1&extra=2&shop=shop-name.myshopify.com&path_prefix=%2Fapps%2Fawesome_reviews&timestamp=1317327555&signature=a9718877bea71c2484f91608a7eaea1532bdf71f5c56825065fa4ccabe549ef3 HTTP/1.1
  Host: proxy-domain.com
  X-Forwarded-For: 123.123.123.123

Cookies are not supported for the app proxy, since the app is accessed through the shop's domain. Shopify strips the Cookie header from the request and Set-Cookie from the response.

The forwarded request adds the following parameters:

  • shop: The myshopify.com domain for the shop.
  • path_prefix: The proxy sub-path prefix at which the shop was accessed. In this case, it's /apps/awesome_reviews, which was replaced in the forwarded request URL with the proxy application's Proxy URL.
  • timestamp: The time in seconds since midnight of January 1, 1970 UTC.
  • signature: A hexadecimal encoded SHA-256 HMAC of the other parameters, split on the "&" character, that is used to verify that the request was sent by Shopify. The signature is unencoded, sorted, concatenated and uses the application's shared secret as the HMAC key.

Both the request method and request body are forwarded, meaning that content from form submission and AJAX requests can be used in the proxy application. If this is the case, then the URL still contains the query parameters added by the proxy (shop, path_prefix, timestamp, and signature), even when the body also contains URL encoded parameters.

Calculate a digital signature

To verify that the request came from Shopify, you need to compute the HMAC digest according to the SHA-256 hash function and compare it to the value in the X-Shopify-Hmac-SHA256 header. If the values match, the webhook was sent from Shopify.

Below is an example in Ruby using the ruby-hmac gem to calculate the digital signature:

require 'rubygems'
require 'openssl'
require 'rack/utils'
SHARED_SECRET = 'hush'

# Use request.query_string in rails
query_string = "extra=1&extra=2&shop=shop-name.myshopify.com&path_prefix=%2Fapps%2Fawesome_reviews&timestamp=1317327555&signature=a9718877bea71c2484f91608a7eaea1532bdf71f5c56825065fa4ccabe549ef3"

query_hash = Rack::Utils.parse_query(query_string)
# => {
#   "extra" => ["1", "2"],
#   "shop" => "shop-name.myshopify.com",
#   "path_prefix" => "/apps/awesome_reviews",
#   "timestamp" => "1317327555",
#   "signature" => "a9718877bea71c2484f91608a7eaea1532bdf71f5c56825065fa4ccabe549ef3",
# }

# Remove and save the "signature" entry
signature = query_hash.delete("signature")

sorted_params = query_hash.collect{ |k, v| "#{k}=#{Array(v).join(',')}" }.sort.join
# => "extra=1,2path_prefix=/apps/awesome_reviewsshop=shop-name.myshopify.comtimestamp=1317327555"

calculated_signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), SHARED_SECRET, sorted_params)
raise 'Invalid signature' unless ActiveSupport::SecurityUtils.secure_compare(signature, calculated_signature)

Proxy response

If the HTTP response from the proxy URL has Content-Type: application/liquid set in its headers, then Shopify renders any Liquid code in the request body in the context of the shop using the shop's theme. Otherwise, the response is returned directly to the client. Also, any 30x redirects are followed.

Sign up for a Partner account to get started.

Sign up