Shopify Behind an Nginx Reverse Proxy

For SEO Purposes and a general move away from the Shopify platform, we at Grove have finally implemented a reverse proxy via Nginx.

Previously, our DNS records for pointed directly at, while pointed to our VPS. The problem with this approach is SEO – search engines rank subdomains as separate entities. is competing with

Let’s face it – at the end of the day, Shopify is an amazingly useful platform. It does as well as a general solution can. We used the best of both worlds: Shopify would serve the e-commerce pages, and Linode would serve our custom django project.

The solution to our problem? Enter the proxy server.

Set the DNS records to point all traffic to to our nginx server at linode, and have the nginx server proxy specific URLs to Shopify and the rest to our linode servers.

That means when you access, nginx proxies the request to and returns the data to your browser seamlessly.

When you access, nginx proxies the request to a local apache server hosting our django project.

Nginx proxy configuration

Here’s the configuration. It was pretty painless once I realized I could proxy to a subdomain already mapped to Shopify.

Note that if you do not proxy_pass to a domain Shopify knows about via the Shopify admin DNS settings you must manually set the Host parameter via nginx `proxy_set_header Host`

# index url
# ---------
location = / {

    client_max_body_size    10m;
    client_body_buffer_size     128k;
    proxy_connect_timeout 90;

# grove urls
# ----------
location / {
    proxy_redirect off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    client_max_body_size       10m;
    client_body_buffer_size    128k;

    proxy_connect_timeout      90; # time to connect to upstream server
    proxy_send_timeout         120; # time to wait for upstream to accept data
    proxy_read_timeout         120; # time to wait for upstream to return data

    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;

# shopify urls
# ------------
location ~ ^/(collections|cart|products|shopify|pages|blogs|checkout|admin)/? {

    client_max_body_size    10m;
    client_body_buffer_size     128k;
    proxy_connect_timeout 90;

Restart your nginx server and watch your traffic proxied!

Extra useful stuff you can do when you share the same domain

When your django servers and Shopify share the same domain name, you get more than just SEO. You get access to the Shopify cookies… which means we can programmatically make requests to Shopify to enter checkout, or read the contents of the cart.

I’ve just started to mess around with this, but it appears that Shopify sets a `cart` cookie with an ID string that you can easily read in django via `request.COOKIES.get(‘cart’)` .

Add this to the headers when you make a GET request or POST request, and you can manually enter checkout, use the “js” API from python, etc. We’ll be using this to literally only use their checkout page for our site.


  1. We have a magento enterprise site and I a hating the fact that most connectors won’t work out of the box and template customizations can be a pain. So we are considering moving to Shopify but just as you mention. SEO part would be hurt because of the cname redirection and URL structure is not optimal.

    Any ways, Ive configure reverse proxies with Litespeed webserver and use their cache engine to avoid re-request back and fwd, specially since the reverse proxy and shopify will be in different places.

    Did you manage to cache on your reverse proxy? or you are going live on each request?

    thanks a lot for sharing

  2. It’s really a great and useful piece of info. I am glad that you just shared this
    useful information with us. Please keep us informed like this.
    Thanks for sharing.

  3. Eric says:

    Great post… this is exactly what i was looking for! i’m trying to accomplish the same thing! A++


  4. Ariel Perez says:

    Great post. I’m thinking of going down the same route as we have our own Private App that integrates with Shopify and I’m trying to access the cookies, user session, etc… and it’s turning out to be very difficult.

    Thanks for sharing.

  5. Nikola says:

    Great post! I am interested in the number of concurrent/daily users you can hit with this setup, before Shopify starts making temporary bans.


Leave a Comment

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s