Skip to content

gruntlord5/cloudflare-rr7-shopify-durable-object

Repository files navigation

Shopify App Template - Cloudflare Workers

Deploy to Cloudflare

What is this?

A Shopify app starter, built on top of Cloudflare Workers. This template provides a foundation for building a Shopify app using the React Router 7 framework, deployed on Cloudflare's global network.

Why would I use this?

This lets you deploy an entire Shopify React Router 7 starter application to Cloudflare with a single click. It will setup a repo and a Cloudflare worker named after your project, along with Durable Objects for session storage and a D1 database binding for additional data storage needs.

Cloudflare Workers is flexible, scalable, and even has a free tier for those just getting started.

Requests Duration CPU time
Free 100,000 per day No charge for duration 10 milliseconds of CPU time per invocation
Standard 10 million included per month +$0.30 per additional million No charge or limit for duration 30 million CPU milliseconds included per month +$0.02 per additional million CPU milliseconds Max of 5 minutes of CPU time per invocation (default: 30 seconds) Max of 15 minutes of CPU time per Cron Trigger or Queue Consumer invocation

Session Storage and Data Architecture

This template uses Durable Objects for session storage, which provides excellent performance and consistency for store-specific data. Durable Objects are strongly consistent, geographically distributed, and perfect for storing any data that is specific to an individual Shopify store. When a store first uses your app, a Durable Object is created geographically close to that store, ensuring fast access times and strong consistency for all subsequent requests from that store. A D1 database is also included for cases where you need traditional SQL database functionality for data that spans across multiple stores or requires complex relational operations.

When to use Durable Objects:

  • Store-specific data that is unique to each individual Shopify store. Since each store gets its own Durable Object instance created near their geographic location, this is ideal for any data that belongs to a single store and needs fast, consistent access.

When to use a D1 Database:

  • Cross-store data, analytics that aggregate information from multiple stores, or any data that needs to be queried across your entire application rather than being specific to one store.

Prerequisites

Before you begin, you'll need the following:

  1. Cloudflare Account: Sign up if you don't have one.
  2. Shopify Partner Account: Create an account if you don't have one.
  3. Shopify App: Create an app in the Shopify partner dashboard.
  4. Test Store: Set up either a development store or a Shopify Plus sandbox store for testing your app.

Quick Start

  1. Click the "Deploy to Cloudflare" button at the top of this README.
  2. Configure your deployment settings including worker name and repository details.
  3. After deployment, update the wrangler.jsonc file in your new repository with the credentials from your Shopify app:
"vars": {
 "SHOPIFY_API_KEY": "your_api_key_here", // Don't use this in production, use secrets in the dashboard https://developers.cloudflare.com/workers/configuration/secrets/#adding-secrets-to-your-project
 "SHOPIFY_API_SECRET": "your_api_secret_here", // Don't use this in production, use secrets in the dashboard https://developers.cloudflare.com/workers/configuration/secrets/#adding-secrets-to-your-project
 "SHOPIFY_APP_URL": "https://your-worker-name.workers.dev",
 "SCOPES": "write_products,read_orders", // adjust scopes as needed
}

You should consider storing them as secrets in a production application.

Enabling Additional Databases

This template supports multiple D1 databases which can be useful for more complex applications. Two additional databases (DB2 and DB3) are included in the configuration but commented out by default. Here's how to enable them:

  1. Create the databases in Cloudflare Dashboard:
  • Go to your Cloudflare Dashboard
  • Navigate to Storage & Databases > D1 SQL Database
  • Click "Create"
  • Name your databases shop_auth_exampledb2 and shop_auth_exampledb3 (these names should match the database name in your wrangler.jsonc)
  • Note the generated database IDs for each
  1. Update your wrangler.jsonc file
{
  // ... other configuration
  "d1_databases": [
    {
      "binding": "DB",
      "database_name": "shop_auth",
      "database_id": "151f7d9b-365f-41d7-83ed-0bf4eeef5086"
    },
    {
      "binding": "DB2",
      "database_name": "shop_auth_exampledb2",
      "database_id": "your-actual-db2-id-from-dashboard"
    },
    {
      "binding": "DB3",
      "database_name": "shop_auth_exampledb3",
      "database_id": "your-actual-db3-id-from-dashboard"
    }
  ],
  // ... rest of configuration
  1. Commit and deploy your changes:
  • After deployment, your Worker will have access to all three databases. You can access them in your code using the bindings.
  • Visit the example page in the app to see how to interact with multiple databases.

Authenticating and querying data

To authenticate and query data you can use the shopify const that is exported from /app/shopify.server.ts:

export async function loader({ request }) {
  const { admin } = await shopify.authenticate.admin(request);

  const response = await admin.graphql(`
    {
      products(first: 25) {
        nodes {
          title
          description
        }
      }
    }`);

  const {
    data: {
      products: { nodes },
    },
  } = await response.json();

  return nodes;
}

This template comes preconfigured with examples of:

  1. Setting up your Shopify app in /app/shopify.server.ts
  2. Querying data using Graphql. Please see: /app/routes/app._index.tsx.
  3. Responding to mandatory webhooks in /app/routes/webhooks.tsx

Please read the documentation for @shopify/shopify-app-remix to understand what other API's are available.

Troubleshooting

Updating the URL for your App

You may get an error similar to this "Error: Invalid appUrl configuration 'example.workers.dev', please provide a valid URL." When trying to update the domain in wrangler.jsonc

Make sure you have the url formatted properly, in this example it would be "https://example.workers.dev/"

Navigating/redirecting breaks an embedded app

Embedded Shopify apps must maintain the user session, which can be tricky inside an iFrame. To avoid issues:

  1. Use Link from react-router or @shopify/polaris. Do not use <a>.
  2. Use the redirect helper returned from authenticate.admin. Do not use redirect from react-router
  3. Use useSubmit or <Form/> from react-router. Do not use a lowercase <form/>.

This only applies if your app is embedded, which it will be by default.

Non Embedded

Shopify apps are best when they are embedded in the Shopify Admin, which is how this template is configured. If you have a reason to not embed your app please make the following changes:

  1. Ensure embedded = false is set in shopify.app.toml`. Docs here.
  2. Pass isEmbeddedApp: false to shopifyApp() in ./app/shopify.server.js|ts.
  3. Change the isEmbeddedApp prop to isEmbeddedApp={false} for the AppProvider in /app/routes/app.jsx|tsx.
  4. Remove the @shopify/app-bridge-react dependency from package.json and vite.config.ts|js.
  5. Remove anything imported from @shopify/app-bridge-react. For example: NavMenu, TitleBar and useAppBridge.

OAuth goes into a loop when I change my app's scopes

If you change your app's scopes and authentication goes into a loop and fails with a message from Shopify that it tried too many times, you might have forgotten to update your scopes with Shopify. To do that, you can run the deploy CLI command.

My shop-specific webhook subscriptions aren't updated

If you are registering webhooks in the afterAuth hook, using shopify.registerWebhooks, you may find that your subscriptions aren't being updated.

Instead of using the afterAuth hook, the recommended approach is to declare app-specific webhooks in the shopify.app.toml file. This approach is easier since Shopify will automatically update changes to webhook subscriptions every time you run deploy. Please read these guides to understand more:

  1. app-specific vs shop-specific webhooks
  2. Create a subscription tutorial

Tech Stack

This template uses React Router 7 with Cloudflare Workers. The following Shopify tools are also included to ease app development:

  • Shopify App React Router 7 provides authentication and methods for interacting with Shopify APIs.
  • Shopify App Bridge allows your app to seamlessly integrate your app within Shopify's Admin.
  • Polaris React is a powerful design system and component library that helps developers build high quality, consistent experiences for Shopify merchants.
  • Webhooks: Callbacks sent by Shopify when certain events occur

Resources

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors