How to run Shopify apps locally (ngrok vs. Serveo comparison)
Captain's log, stardate d237.y38/AB
One of the requirements when building a Shopify application is that it has to be accessible from the public internet.
Here's how we do it to deploy Shopify apps locally to build our e-commerce projects. Keep reading!
Photo by Lance Anderson on Unsplash
Because Shopify uses an application callback to provide authorization credentials, it needs to be constantly accesible from the internet. That is, of course, all good until you're developing your app and want to run it locally.
To simulate localhost being accessible from the internet, you need to create an HTTP tunnel using a proxy server. But worry not! There are several tools to setup this scenario in an easy way.
Shopify, in their official documentation, recommend to use ngrok.com, a webhook development and debugging tool, which generates secure introspectable tunnels to localhost.
However, using ngrok has an important downside: every time you make a tunnel on their free version, it uses a random generated subdomain. That can be, of course, avoided on the paid version of ngrok.
This means that every time you start a tunnel, you have to edit the Shopify configuration to change the callback URL.
In my research for an alternative, I've discovered serveo.net, another tool to expose local servers to the internet, that has a couple of advantages over the free plan of ngrok:
- You can request fixed subdomains in the free plan.
- There's no need to install anything since it uses just SSH (with ngrok you have to install their client)
Unfortunately, sometimes the SSH stops working and I can't seem to kill it using Ctrl+C, so I've created these scripts at
package.json to start, stop and restart:
"tunnel:start": "ssh -R shopify-postal-codes:80:localhost:3000 serveo.net", "tunnel:stop": "ps -A| grep 'serveo.net' | cut -d' ' -f1 | xargs kill -9", "tunnel:restart": "npm run tunnel:stop && npm run tunnel:start",
When I want to start a tunnel I run
"yarn tunnel:start" and when it stops working I run
"yarn tunnel:restart" to force restart it. To stop it manually, I use the
"tunnel:stop". Pretty straightforward, isn't it?
Hope you found this useful!