A much better DX for Shopify apps
Tags: shopify
Published: 2021-06-06 17:54:35

When creating a shopify app, you often have to use ngrok because the shopify embed requires https. But using ngrok when you just got used to the speed of vitejs will feel very slow. and will give you a bad developer experience.

Fortunately, there is a better way.

The solution is to enable https on localhost by ourselves using mkcert.

This method will use docker but it's not completely necessary as you can still install nginx or apache directly on your OS and the method would still work.

## mkcert: generate the ssl certificates

To start, we install [mkcert](https://github.com/FiloSottile/mkcert#installation), then we install a CA (Certificate authority) using

```shell
mkcert -install
```

Then we generate our self-signed certificate like this
```shell
mkcert local.dev localhost 127.0.0.1 ::1
```
You can replace `local.dev` with any domain of your choice

## Editing the hosts file

Finally, add this line to your hosts file
```txt
127.0.0.1 local.dev
```

## Using the certificates

The next step depends on what you use to develop your app, but the tool you use certainly supports configuring a certificate that will be used when serving the app in dev mode, here are some examples
[WebPack Dev Server](https://webpack.js.org/configuration/dev-server/#devserverhttps)
[ViteJs](https://vitejs.dev/config/#server-https)
[Apache](https://www.thesslstore.com/knowledgebase/ssl-install/apache-openssl-installation/)
[Nginx](http://nginx.org/en/docs/http/configuring_https_servers.html)

## Creating a reverse proxy (it's easier than it sounds)

Since you are probably serving your app over a specific port that is different than port 80, then shopify embed won't accept that, i.e. something like this https://local.dev:8081 won't be accepted.

There is probably a simpler solution but the method that worked for me was to create a reverse proxy using apache or nginx.

Here's a working solution that uses docker and nginx
https://github.com/unlocomqx/nginx-docker-ssl-proxy

Now, I can access SvelteKit using https://local.dev
![Dev app served through https](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8wlvu6vgdmni1qo3hy4e.png)

If you use apache, here's a config that you can add to your virtual hosts file
```conf
<VirtualHost *:80>
    ProxyPreserveHost On

    ProxyPass / "http://host.docker.internal:8081/" retry=0
    ProxyPassReverse / "http://host.docker.internal:8081/" retry=0

    ServerName local.dev
</VirtualHost>

<VirtualHost *:443>
    ProxyPreserveHost On

    SSLEngine on

    SSLCertificateFile      /etc/ssl/certs/cert.pem
    SSLCertificateKeyFile   /etc/ssl/certs/key.pem

    ProxyPass / "http://host.docker.internal:8081/" retry=0
    ProxyPassReverse / "http://host.docker.internal:8081/" retry=0

    ServerName local.dev
</VirtualHost>
```

Feel free to share other tools configs in the comments

## Reconfiguring our Shopify app
To tell shopify to load the app through local.dev, we need to change our app url in the partner dashboard
![Partner Dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ov6i7wssg9qn0hgxcftr.png)
 
![App URLs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/osk3o1t00hceteudfepp.jpg)

Also don't forget to edit your `.env` file by setting the host var
```env
HOST=https://local.dev
```

Now you can access your start your app using this url
```txt
https://local.dev/?shop=shopname.myshopify.com
```
Or you can install it to your test shop from the partner dashboard

If you would like to use SvelteKit to develop your Shopify app, check this template
https://github.com/unlocomqx/shopify-app-sveltekit

Here's how the end result looks
![Shopify Embed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xjkxku4i28mzdnbwg82v.png)

## Comparison with ngrok
I compared the SvelteKit demo app load and found a big difference

ngrok load time: 21s (but maybe I have a slow internet 12Down/1Up)
ngrok vite hmr: 450ms

localhost load time: under 1s (as you might expect)
localhost vite hmr: 30ms

## Finally
I hope this give you a better developer experience and make developing shopify apps a lot more enjoyable