Key Environment Variables in Open‑SEO: A Complete Configuration Guide

Open‑SEO uses environment variables defined in process.env across more than a dozen files to configure site URLs, database connections, third‑party APIs, telemetry settings, and CI/test behavior.

The open‑source Open‑SEO repository (every-app/open-seo on GitHub) relies heavily on environment variables to remain flexible across self‑hosted, cloud, and development deployments. This guide catalogs every significant variable, where it appears in the source code, and how to set it correctly.


Core Site and Application Settings

These variables control the base identity of your Open‑SEO instance.

SITE_URL and VITE_SITE_URL

In web/src/lib/seo.ts, the SEO utilities resolve the canonical site address from two possible sources:

// web/src/lib/seo.ts (lines 6‑7)
const siteUrl = process.env.SITE_URL ?? process.env.VITE_SITE_URL;
  • SITE_URL – Standard Node.js environment variable used in production.
  • VITE_SITE_URL – Vite‑prefixed variant exposed to the client bundle during development.

If neither is set, the application falls back to http://localhost:3000.

PORT

The Vite development server port is configured in vite.config.ts:

// vite.config.ts (lines 12‑13)
export default defineConfig({
  server: {
    port: parseInt(process.env.PORT || "5173"),
  },
});

NODE_ENV

In src/lib/auth.ts, the authentication logic branches based on environment:

// src/lib/auth.ts (line 184)
if (process.env.NODE_ENV !== "production") {
  // Development‑only auth bypasses
}

Database and Cloudflare Infrastructure

Open‑SEO supports both Cloudflare D1 and PostgreSQL backends. Migration and ORM configuration require these credentials.

CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN, CLOUDFLARE_DATABASE_ID

The D1‑to‑Postgres migration script in scripts/migrate-d1-to-postgres.ts reads:

// scripts/migrate-d1-to-postgres.ts (line 90)
const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
const apiToken = process.env.CLOUDFLARE_API_TOKEN;

Additionally, drizzle-prod.config.ts uses:

// drizzle-prod.config.ts
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
databaseId: process.env.CLOUDFLARE_DATABASE_ID,
apiToken: process.env.CLOUDFLARE_API_TOKEN,

POSTGRES_DATABASE_URL

PostgreSQL deployments require a connection string:

// drizzle-pg.config.ts (line 13)
export default defineConfig({
  dbCredentials: {
    url: process.env.POSTGRES_DATABASE_URL!,
  },
});

// scripts/migrate-d1-to-postgres.ts
const pgClient = new Client(process.env.POSTGRES_DATABASE_URL);

CLOUDFLARE_D1_DATABASE_ID

Optional override for the source D1 database during migrations:

// scripts/migrate-d1-to-postgres.ts
const d1DatabaseId = process.env.CLOUDFLARE_D1_DATABASE_ID ?? defaultId;

Third‑Party API Integrations

DATAFORSEO_API_KEY

Multiple scripts consume this key for SEO data services:

AUTUMN_SECRET_KEY

The data erasure utility in scripts/erase-user-data.ts uses:

// scripts/erase-user-data.ts (line 411)
const autumnKey = process.env.AUTUMN_SECRET_KEY;
if (!autumnKey) throw new Error("AUTUMN_SECRET_KEY required for secure deletion");

Telemetry and Privacy Controls

OPENSEO_TELEMETRY_DISABLED and DO_NOT_TRACK

The self‑host preflight script respects user privacy preferences:

// scripts/selfhost-preflight.ts (lines 23‑24)
const telemetryDisabled =
  process.env.OPENSEO_TELEMETRY_DISABLED === "true" ||
  process.env.DO_NOT_TRACK === "1" ||
  process.env.DO_NOT_TRACK === "true";

CLI Authentication

BETTER_AUTH_URL and BETTER_AUTH_SECRET

The CLI tool in cli-auth.ts configures its auth provider:

// cli-auth.ts (lines 7‑13)
const authUrl = process.env.BETTER_AUTH_URL ?? "http://localhost:4000";
const authSecret = process.env.BETTER_AUTH_SECRET ?? crypto.randomUUID();

Testing and Performance Configuration

PLAYWRIGHT_CHANNEL

End‑to‑end test browser selection:

// playwright.config.ts (line 16)
channel: process.env.PLAYWRIGHT_CHANNEL ?? "chrome",

DOMAIN_FILTER_* Performance Knobs

The domain overview filter performance spec in e2e/domain-overview-filters.perf.spec.ts exposes fine‑grained controls:

  • DOMAIN_FILTER_CPU_THROTTLE – CPU throttling rate for simulated devices
  • DOMAIN_FILTER_ACTION_MS – Maximum acceptable interaction time
  • DOMAIN_FILTER_MAX_LONG_TASK_MS – Per‑task duration threshold
  • DOMAIN_FILTER_MAX_RAF_GAP_MS – RequestAnimationFrame gap limit
  • DOMAIN_FILTER_MAX_INPUT_MS – Input delay ceiling
  • DOMAIN_FILTER_TOTAL_LONG_TASK_MS – Cumulative long‑task budget

These allow CI pipelines to enforce strict performance budgets across different hardware.


CI and Debugging Flags

CI

When set to "true", cost‑profile scripts (brand-lookup-cost-profile.ts, backlinks-cost-profile.ts) enforce stricter validation and reporting formats suitable for automated pipelines.

DEBUG_DEPTH

The BadSEO audit runner supports verbose logging:

// badseo/scripts/run-audit.ts (line 248)
const debugDepth = parseInt(process.env.DEBUG_DEPTH || "0");
if (debugDepth > 2) console.log(extendedDiagnostics);

Summary

  • Site identity: SITE_URL, VITE_SITE_URL, PORT define how Open‑SEO presents itself and listens for traffic.
  • Infrastructure: CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN, CLOUDFLARE_DATABASE_ID, and POSTGRES_DATABASE_URL enable database connectivity and migrations.
  • External data: DATAFORSEO_API_KEY powers SEO analytics; AUTUMN_SECRET_KEY secures data deletion.
  • Privacy: OPENSEO_TELEMETRY_DISABLED and DO_NOT_TRACK let operators opt out of usage reporting.
  • CLI and auth: BETTER_AUTH_URL and BETTER_AUTH_SECRET support command‑line authentication flows.
  • Testing: PLAYWRIGHT_CHANNEL and the six DOMAIN_FILTER_* variables provide deterministic, measurable test environments.
  • Debugging: DEBUG_DEPTH and CI control output verbosity and pipeline behavior.

Frequently Asked Questions

What is the minimum set of environment variables to run Open‑SEO locally?

For local development, you need VITE_SITE_URL (or SITE_URL), PORT if you want a custom port, and NODE_ENV=development. Database functionality requires either POSTGRES_DATABASE_URL for PostgreSQL or Cloudflare credentials for D1. See .env.example in the repository root for a complete template.

How do I disable telemetry when self‑hosting Open‑SEO?

Set OPENSEO_TELEMETRY_DISABLED=true or DO_NOT_TRACK=1 before running the preflight script in scripts/selfhost-preflight.ts. The script checks both variables and skips telemetry initialization if either is set.

Can I use Open‑SEO without DataForSEO?

Yes, but brand lookup, backlink analysis, and cost profiling features require DATAFORSEO_API_KEY. Core site auditing and local SEO tools function without it.

Why does the migration script need both Cloudflare and Postgres credentials?

scripts/migrate-d1-to-postgres.ts reads from Cloudflare D1 (source) and writes to PostgreSQL (target). It requires CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN, and POSTGRES_DATABASE_URL to establish both connections simultaneously.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →