Your safety is important to us. If you notice any suspicious emails that appear to come from Shopify, please forward them to safety@shopify.com. Visit the Help Center page on phishing for more information.

Application proxies - front end development

You can use an application proxy to fetch data from an outside location and display it on the page of an Online Store. For app developers, this means that the content on these proxy pages can be dynamic, or capable of being updated as much as you want. Application proxies are useful for displaying image galleries, statistics, custom forms, and other kinds of dynamic content.

You do not need to set up application proxies before you publish your app. If you add an application proxy to an app after you've published it, then its existing install base will be updated automatically.

Application proxies also support responses from the Proxy URL using Liquid, Shopify's theme customization engine. You can use Liquid to display your proxy page as if it were a part of an Online Store's theme.

Add a proxy to your app

To add a proxy to your app:

  1. From your Partner Dashboard, click Apps.
  2. Click on the name of the app that you want to change.
  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 as well, then enter one in the Sub path field:

    App proxy settings
    These settings determine which HTTP requests to Shopify are proxied to the Proxy URL that you enter 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 will be proxied to the Proxy URL that you enter in the next step.

  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.

    Note

    Shopify does not recognize localhost or example.com as the Proxy URL. If your app proxy contains those values, then it will return an error.

  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 will be forwarded to the Proxy URL at https://my-app-proxy.com/app_proxy/app_path.

What the store owner sees

After a merchant installs an app with a proxy, they can change the sub path. The sub path is where the application proxy will be accessed from a merchant's own shop. Merchants may choose to change the sub path so that the URL in a browser's location bar makes the proxy page look like it's hosted in their store instead of externally. Ultimately, the sub path doesn't affect the actual location of the proxy URL (if the merchant edits a sub-path, then it will still be forwarded to the proxy URL).

Issue a proxy request

When Shopify receives an HTTP request for a proxied path, it will forward that request to the specified Proxy URL. For example, when the following HTTP request is sent from the client user agent:

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

Shopify will forward the request using the specified Proxy URL.

Given that the Proxy URL is set to https://proxy-domain.com/proxy, the client's IP address is 123.123.123.123 and the applications shared secret is hush, the forwarded request will look 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 application proxy, since the application is accessed through the shop's domain. Shopify will strip 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: Verifies that the request was sent by Shopify. A hexadecimal encoded SHA-256 HMAC of the other parameters, split on the "&" character, unencoded, sorted, concatenated and using the applications Shared Secret as the HMAC key.

Security: Calculate a digital signature

Just like our webhooks, we sign all our proxy requests.

In Ruby, the algorithm for calculating the signature looks like this using the ruby-hmac gem:

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::Digest.new('sha256'), SHARED_SECRET, sorted_params)
raise 'Invalid signature' unless ActiveSupport::SecurityUtils.secure_compare(signature, calculated_signature)

The request method and request body will be forwarded, so content from form submission and AJAX requests can be used in the proxy application. In this case, the URL will still contain the query parameters added by the proxy (i.e. shop, path_prefix, timestamp, and signature) even when the body also contains URL encoded parameters.

Proxy response

If the HTTP response from the Proxy URL has Content-Type: application/liquid set in its headers, Shopify will evaluate and render any Liquid code in the request's body in the context of the shop using the shop's theme. When used the right way, it can automatically make your app look like it belongs as part of the shop without any manual intervention.

Otherwise, the response will be returned directly to the client. 30* redirects will be followed in case you need that sort of thing.