# How to Set Up OpenSEO with Cloudflare Workers: Complete Deployment Guide

> Deploy OpenSEO with Cloudflare Workers using KV storage Durable Objects and Wrangler CLI. Get the complete edge deployment guide for every-app/open-seo.

- Repository: [Every App/open-seo](https://github.com/every-app/open-seo)
- Tags: how-to-guide
- Published: 2026-08-20

---

**OpenSEO deploys as a Cloudflare Workers application using a Vite-based build pipeline, KV storage, Durable Objects, and Wrangler CLI for edge deployment.**

This guide walks through deploying OpenSEO on Cloudflare's edge runtime. The architecture leverages **Cloudflare Workers** APIs, **KV storage** for persistence, **Durable Objects** for coordination, and **Workers AI** bindings for AI-powered features. The build system uses Vite with the official `@cloudflare/vite-plugin` to bundle TypeScript into a production-ready worker script.

## Prerequisites and Initial Setup

Before deploying OpenSEO, you need a Cloudflare account and the Wrangler CLI installed globally.

```bash
npm install -g @cloudflare/wrangler

```

Clone the repository and install dependencies:

```bash
git clone https://github.com/every-app/open-seo.git
cd open-seo
pnpm install

```

## Configure Environment Variables

OpenSEO requires several API keys and Cloudflare-specific settings. Copy the example environment file and fill in your credentials:

```bash
cp .env.example .env

```

Edit `.env` to include:

- `DATAFORSEO_API_KEY` — for rank tracking data
- `CLOUDFLARE_ACCESS_CLIENT_ID` and `CLOUDFLARE_ACCESS_CLIENT_SECRET` — for Cloudflare Access authentication
- Additional service credentials as needed per [`src/shared/gsc.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/gsc.ts) and related integrations

The [`src/serverFunctions/workspace.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/workspace.ts) file validates authentication mode via `env.AUTH_MODE`, enforcing "cloudflare_access" for production deployments.

## Build the Workers Bundle

OpenSEO uses Vite with the `@cloudflare/vite-plugin` to transform and bundle code. The plugin injects Cloudflare-specific globals like `cloudflare:workers` and `cloudflare:ai` during the build process.

```bash
pnpm run build

```

Key build artifacts and their purposes:

- **[`vite.config.ts`](https://github.com/every-app/open-seo/blob/main/vite.config.ts)** — Configures the Vite pipeline with Cloudflare plugin settings
- **[`vite-plugin-lean-worker-bundle.ts`](https://github.com/every-app/open-seo/blob/main/vite-plugin-lean-worker-bundle.ts)** — Generates a minimal production bundle by stripping development-only code
- **[`worker-configuration.d.ts`](https://github.com/every-app/open-seo/blob/main/worker-configuration.d.ts)** — Provides TypeScript definitions for Cloudflare bindings (`cloudflare:workers`, `cloudflare:ai`, etc.)

The build produces a single optimized script ready for Cloudflare's edge runtime.

## Wrangler Configuration and Deployment

The [`wrangler.toml`](https://github.com/every-app/open-seo/blob/main/wrangler.toml) configuration (generated by the Vite plugin) declares required Cloudflare resources:

- **KV namespace** — for caching and persistent storage
- **Durable Object bindings** — for stateful coordination between worker instances
- **Workers AI binding** — for AI-powered SEO features

Deploy using Wrangler:

```bash
pnpm run deploy

```

This executes `wrangler deploy`, which:
- Uploads the bundled worker script
- Creates or updates the KV namespace
- Registers Durable Object classes
- Activates the Workers AI binding

## Accessing Deployed Endpoints

Once deployed, your OpenSEO instance responds at `https://<your-worker>.workers.dev`. Example API call for rank tracking:

```javascript
fetch('https://<your-worker>.workers.dev/api/rank-tracking', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ domain: 'example.com', keyword: 'best shoes' })
})
  .then(res => res.json())
  .then(data => console.log('Rank:', data.position));

```

The `rank-tracking` endpoint in [`src/serverFunctions/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/rank-tracking.ts) uses Cloudflare's `waitUntil` API for background processing:

```typescript
// src/serverFunctions/rank-tracking.ts
import { waitUntil } from 'cloudflare:workers';

export async function handler(request: Request, env: Env) {
  // Process request...
  waitUntil(fetchRankData(...));
  return new Response(JSON.stringify(result), { status: 200 });
}

```

## Server-Side Architecture

OpenSEO's server functions are organized under `src/serverFunctions/` with these key modules:

| Path | Purpose |
|------|---------|
| [`src/serverFunctions/rank-tracking.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/rank-tracking.ts) | Rank tracking API with background job scheduling |
| [`src/serverFunctions/workspace.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/workspace.ts) | Workspace management with Cloudflare Access validation |
| [`src/shared/gsc.ts`](https://github.com/every-app/open-seo/blob/main/src/shared/gsc.ts) | Google Search Console integration |
| `src/shared/` | Shared utilities including DataForSEO client |

Authentication flows through `env` bindings, with [`src/serverFunctions/workspace.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/workspace.ts) enforcing `cloudflare_access` mode for secure access.

## Security and Access Control

Cloudflare Access protects the OpenSEO UI. The `env.AUTH_MODE` variable controls authentication behavior, with "cloudflare_access" requiring valid Cloudflare Access tokens. Configure your Access policies in the Cloudflare dashboard to restrict by email domain, identity provider, or other policies.

## Troubleshooting Common Issues

**Build failures with missing bindings** — Ensure [`worker-configuration.d.ts`](https://github.com/every-app/open-seo/blob/main/worker-configuration.d.ts) is up to date; run `wrangler types` to regenerate type definitions.

**KV namespace errors on deploy** — Verify [`wrangler.toml`](https://github.com/every-app/open-seo/blob/main/wrangler.toml) includes the correct KV namespace ID, or allow Wrangler to create a new one automatically.

**Authentication redirects failing** — Check `CLOUDFLARE_ACCESS_CLIENT_ID` and `CLOUDFLARE_ACCESS_CLIENT_SECRET` match your Cloudflare Access application configuration.

## Summary

- OpenSEO deploys as a **single Cloudflare Worker** built with Vite and `@cloudflare/vite-plugin`
- Required Cloudflare services: **KV storage**, **Durable Objects**, **Workers AI**, and **Cloudflare Access**
- Build with `pnpm run build`, deploy with `pnpm run deploy` (Wrangler wrapper)
- Configure secrets in `.env` based on `.env.example` template
- Server functions in `src/serverFunctions/` implement SEO APIs using Cloudflare runtime APIs like `waitUntil`

## Frequently Asked Questions

### What Cloudflare services does OpenSEO require?

OpenSEO uses **KV storage** for caching and persistence, **Durable Objects** for stateful coordination, **Workers AI** for AI features, and **Cloudflare Access** for authentication. These are declared in the generated [`wrangler.toml`](https://github.com/every-app/open-seo/blob/main/wrangler.toml) and bound to the worker at runtime.

### Can I run OpenSEO without Cloudflare Access?

Yes, but this requires modifying [`src/serverFunctions/workspace.ts`](https://github.com/every-app/open-seo/blob/main/src/serverFunctions/workspace.ts) to change `env.AUTH_MODE` from "cloudflare_access" to an alternative authentication method. The repository is optimized for Cloudflare Access.

### How do I update environment variables after deployment?

Run `wrangler secret put <VAR_NAME>` to update secrets, or modify `.env` and redeploy. KV namespace values can be updated via Wrangler CLI or Cloudflare dashboard without redeployment.

### Where is the complete deployment documentation?

The repository includes detailed step-by-step instructions at [`web/content/docs/self-hosting/cloudflare.md`](https://github.com/every-app/open-seo/blob/main/web/content/docs/self-hosting/cloudflare.md), covering KV/Durable Object setup, custom domains, and advanced configuration options.