doitalldev / Shopify-RemixJS-Cloudflare-Workers-Template

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

A template for developing Shopify Apps using RemixJS and Cloudflare Workers

Why?

I'm a glutton for performance and I love the idea of using Cloudflare Workers to serve my Shopify App from their global CDN. I also really enjoy working with RemixJS and especially with Shopify apps.

This template is a starting point for building a Shopify App using RemixJS and Cloudflare Workers. It's not a complete app, but it does provide a good starting point for building a Shopify App and I will be continuing to implement Cloudflare technologies into it. (Like KV, D1, etc.)

Getting Started

1. Clone this repo

git clone git@github.com:refactor-this/Shopify-RemixJS-Cloudflare-Workers-Template.git

2. Install dependencies

I'm using pnpm to manage dependencies. You can install it with npm or yarn if you prefer.

pnpm install

3. Create your environment variables

Copy the example.wrangler.toml to your own wrangler.toml file and fill in the environment variables. (You should have a Shopify app created already on their partner dashboard so you can get the client id and secret.)

For the app url, I set up a free tunnel service using Cloudflare. You can follow how I set that up here: https://innovonics.com/creating-a-free-tunnel-service-for-developing-shopify-apps/

As an alternative, you can use http://localhost:8002

You will also need to copy the .example.vars to .dev.vars and fill out the required values.

The reason we use the local .{environment}.vars file is because we want to keep the sensitive information out of the wrangler.toml file and out of git history.

When adding the productions values, you would add them using the Cloudflare CLI with the encrypted flag set to true. This would keep the values secret but have no effect on the worker.

4. Start the dev server

pnpm dev

5. Happy coding!

Creating the D1 Database

Creating the D1 database is fairly straightforward, run the next command to create one.

wrangler d1 create d1-example

You will receive an output in the terminal that looks like this:

[[d1_databases]]
binding = "DB" # i.e. available in your Worker on env.DB
database_name = "your-database-name"
database_id = "your-generated-database-id"

copy and paste it to your wrangler.toml file.

Now that we have our DB created, let's generate and apply migrations:

Generate migrations

pnpm db:generate

Apply migrations

pnpm dev:db:apply

You can also list pending migrations with

pnpm dev:db:list

Viewing data in your current database

You can view the data in your current database by running the following command:

pnpm db:studio:preview

This will open a Drizzle preview connection which you can view on your browser.

Or if you are like me an use a 3rd party tool you can access the D1 SQLite database directly. It is located at the top of your project folder.

.wrangler/state/v3/d1/miniflare-D1DatabaseObject/[some-random-string].sqlite

Webhooks

The webhooks file is set up with the standard app/uninstall solution (delete the session in your database).

It continues with the stadard switch/case solution. This is not necessarily how I would handle it when the application grows and will be subject to change.

It would make more sense to me to use the routing to define webhook handling and set up a config file when registering webhooks.

I ended up just implementing both for you to choose which you like.

Route-based webhooks

In ~/routes/webhooks/carts/create.tsx You can see how I would handle the route-based approach. The webhook logic is defined by the route and used as the endpoint shown in ~/routes/webhooks/config.tsx which is used as a global webhook endpoint definition file.

Standard Switch/Case webhooks

You can view this method in ~/routes/webhooks/route.tsx. This is the standard switch/case solution. It uses the topic to determine the logic to handle the webhook. It works for small solutions but personally the route-based approach is a long term optimiation that makes more sense.

About


Languages

Language:TypeScript 83.6%Language:JavaScript 16.4%