Skip to content

[BLOCKED on upstream] chore(cloudflare): add OpenNext Cloudflare Workers adapter scaffolding - #56

Open
SaharPak wants to merge 2 commits into
mainfrom
feat/cloudflare-adapter
Open

[BLOCKED on upstream] chore(cloudflare): add OpenNext Cloudflare Workers adapter scaffolding#56
SaharPak wants to merge 2 commits into
mainfrom
feat/cloudflare-adapter

Conversation

@SaharPak

@SaharPak SaharPak commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

Focused PR that wires up the OpenNext Cloudflare adapter so the project can build, preview, and deploy to Cloudflare Workers once the upstream adapter ships Next.js 16 proxy.ts support (see "Known blocker" below). No auth logic, no Supabase changes, no production secret changes.

What's in this PR

File Why
package.json (devDependencies + scripts) Adds @opennextjs/cloudflare@1.20.1 and wrangler@4.106.0. Adds cf:build, preview, deploy, cf-typegen scripts. Existing dev, build, start, lint are unchanged.
wrangler.jsonc (new) Workers config: main: .open-next/worker.js, assets binding, WORKER_SELF_REFERENCE services self-binding, nodejs_compat. Public vars only — secrets stay out of this file.
open-next.config.ts (new) Minimal defineCloudflareConfig({}) — no R2 incremental cache, no queues, no image overrides. Owner can extend later if those become requirements.
.dev.vars.example (new) Local-only template for wrangler dev / npm run preview. The real .dev.vars is gitignored.
next.config.ts Calls initOpenNextCloudflareForDev() when NODE_ENV === "development" so next dev picks up Cloudflare bindings locally. Gated, so next build is unaffected.
.gitignore Adds .wrangler/ and .dev.vars. (.open-next/ and .env* were already covered.)
README.md, OPERATIONS.md Update deployment target from "Cloudflare Pages" (incorrect) to "Cloudflare Workers" (what OpenNext actually targets). Document the cron-trigger workaround and the upstream blocker.

vercel.json is intentionally left in place — it is dead config on Cloudflare Workers (Wrangler ignores it) and removing it is deferred until the deploy is verified end-to-end.

Known blocker

npm run cf:build currently fails with:

ERROR Node.js middleware is not currently supported. Consider switching to Edge Middleware.

This project uses Next.js 16's src/proxy.ts convention (Next 16 renamed middleware.tsproxy.ts). The OpenNext Cloudflare adapter (1.20.1) doesn't yet recognize that convention — it still expects middleware.ts. The fix is upstream:

Until that PR lands, npm run deploy will not produce a deployable Worker. The scaffolding in this PR is ready for the day it does.

Cron trigger workaround

Because there is no Workers scheduled export wired up, the demo-day cron cannot be triggered by wrangler.toml's [triggers].crons yet. Today the cron runs via:

  1. Admin panel "Take snapshot now" button (HTTP call to /api/cron/demo-day)
  2. Manual curl with CRON_SECRET bearer token
  3. External HTTP cron service pointing at the route (recommended long-term: cron-job.org / EasyCron / GitHub Actions)
  4. Supabase SQL (already documented in OPERATIONS.md)

This is documented in OPERATIONS.md and README.md so the owner can pick a path without reading the OpenNext issue tracker.

Validation run on this branch

Command Result
npm run lint clean
npm run build clean (14 routes, Proxy compiled)
npm run cf:build fails with the upstream blocker described above (expected)
BASE_URL=http://localhost:3000 bash ./scripts/auth-smoke.sh 16 passed, 0 failed

wrangler dev was not run end-to-end here because no Cloudflare account is connected to this environment — that's a dashboard action for the owner.

Owner dashboard actions (after merge, when upstream lands)

  1. Create a Cloudflare Workers project named productbuilders-app.
  2. wrangler.jsonc already pins the name. Adjust compatibility_date if you want a newer runtime date.
  3. Set public vars in the Cloudflare dashboard or via wrangler vars set <NAME>. Set secrets via wrangler secret put <NAME> (SUPABASE_SERVICE_ROLE_KEY, CRON_SECRET).
  4. Set NEXT_PUBLIC_SITE_URL to https://productbuilders.app for the production env.
  5. Once the upstream blocker is fixed, npm run deploy will work. Re-run the smoke test against the Cloudflare preview URL.
  6. Optional follow-up: write a separate PR that adds a Workers scheduled export and replaces the external HTTP cron with [triggers].crons in wrangler.jsonc.

Risk / assumptions

  • The OpenNext adapter on Cloudflare Workers is the supported path per OpenNext docs. I did not attempt the Cloudflare Pages path because OpenNext does not support it.
  • next.config.ts adds a require()-based side effect that only fires when NODE_ENV === "development". This is the recommended OpenNext pattern. next build (CI / production sanity) is unaffected.
  • I did not provision an R2 bucket or any Cloudflare binding beyond what defineCloudflareConfig({}) gives by default. If the owner later wants incremental caching at the edge, that's a separate PR that adds the bucket, the binding, and the R2 incremental cache override.
  • The two commits in this PR are split intentionally (config vs. docs) for easier review. Both authored to the repo owner; no AI attribution in commits, code, comments, or PR body.

Sahar Pakseresht added 2 commits July 2, 2026 15:43
Wire up @opennextjs/cloudflare + wrangler so the project can build and
preview via Workers once the upstream adapter supports Next.js 16
proxy.ts (opennextjs-cloudflare#1277 / PR #1280).

What this PR ships:

- package.json (devDependencies): @opennextjs/cloudflare 1.20.1, wrangler 4.x
- package.json scripts:
    cf:build   -> opennextjs-cloudflare build
    preview    -> opennextjs-cloudflare build && opennextjs-cloudflare preview
    deploy     -> opennextjs-cloudflare build && opennextjs-cloudflare deploy
    cf-typegen -> wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts
  (npm run build / npm run dev / npm run lint / npm run start are
  unchanged.)
- wrangler.jsonc at the project root (Workers config; vars for
  NEXT_PUBLIC_* only; secrets for SUPABASE_SERVICE_ROLE_KEY +
  CRON_SECRET stay out of the file and are set via wrangler secret
  put / Cloudflare dashboard).
- open-next.config.ts with a minimal defineCloudflareConfig({})
  (no R2 incremental cache, no queues, no image overrides).
- .dev.vars.example as a local-only template (the real .dev.vars
  file stays gitignored alongside .env*).
- next.config.ts: call initOpenNextCloudflareForDev() under
  process.env.NODE_ENV === 'development' so 'next dev' picks up
  Cloudflare bindings locally. npm run build is unaffected.
- .gitignore: ignore .wrangler/ and .dev.vars.

vercel.json is left in place — it is dead config on Cloudflare
Workers (Wrangler ignores it) and there is no strong reason to
remove it in this PR.

Auth logic is untouched. Supabase settings, migrations, and
production secrets are untouched.
… blocker

- Correct the target from 'Cloudflare Pages via OpenNext' to
  'Cloudflare Workers via OpenNext'. The adapter compiles the
  Next.js app to a single Worker entry (.open-next/worker.js),
  not a Pages project. pages_build_output_dir and the Pages
  concepts are removed; wrangler.jsonc (Workers-style: main,
  assets binding, services self-reference) is used instead.

- Document the deploy blocker: 'npm run cf:build' fails with
  'Node.js middleware is not currently supported. Consider
  switching to Edge Middleware.' because @opennextjs/cloudflare
  1.20.1 does not recognize Next.js 16's proxy.ts convention.
  Upstream issue opennextjs-cloudflare#1277 / PR #1280 is open
  but not merged. Add a follow-up plan: external HTTP cron
  service / admin panel / Supabase SQL until a Workers
  'scheduled' export can be wired in.

- Add NEXT_PUBLIC_SITE_URL to the production env-var table
  (already in .env.example from the auth PR; this just keeps
  the docs in sync).

- vercel.json is left in place. It is inert on Cloudflare
  Workers. Removing it is deferred until the deploy is
  verified end-to-end.
@SaharPak SaharPak changed the title chore(cloudflare): add OpenNext Cloudflare Workers adapter scaffolding [BLOCKED on upstream] chore(cloudflare): add OpenNext Cloudflare Workers adapter scaffolding Jul 2, 2026
@SaharPak

SaharPak commented Jul 2, 2026

Copy link
Copy Markdown
Owner Author

Status: intentionally blocked on upstream

This PR is not ready to merge as long as npm run cf:build fails. The failure is not in this PR — it is an upstream support gap.

What's blocking the deploy

@opennextjs/cloudflare@1.20.1 does not recognize Next.js 16's src/proxy.ts convention. The build emits:

ERROR Node.js middleware is not currently supported. Consider switching to Edge Middleware.

This project uses src/proxy.ts (Next.js 16 replaced middleware.ts with proxy.ts). OpenNext's adapter still expects the older convention.

Upstream status (as of 2026-07-02)

Until #1280 lands and is published, npm run cf:build will not produce a deployable Worker and npm run deploy will not succeed.

Why I'm shipping this anyway

The config in this PR (wrangler.jsonc, open-next.config.ts, .dev.vars.example, next.config.ts dev hook, package scripts) is wired so that the moment a fixed adapter is published, the deploy command will work end-to-end with no further code changes. Catching the upstream gap while the auth fixes from PR #55 are fresh saves us a re-setup pass later.

What I deliberately did not do

  • I did not rename src/proxy.ts to src/middleware.ts. Next.js 16 does not support the old middleware.ts convention, so that is not a real workaround — it is the opposite of "use Next.js 16" and would require going back to Next 15 or pretending to. If we want to experimentally try the rename on a side branch, that needs a separate decision.
  • I did not add [triggers].crons to wrangler.jsonc. The OpenNext worker entry has no scheduled export, so a cron trigger would be a no-op. Demo-day snapshots still run via the admin panel / manual curl / external HTTP cron / Supabase SQL — see OPERATIONS.md.
  • I did not touch vercel.json. It's inert on Cloudflare Workers (Wrangler ignores it).
  • I did not change auth logic in this PR.

What to do next

  1. Watch opennextjs-cloudflare#1277 and PR #1280.
  2. When a fixed @opennextjs/cloudflare is released, run npm install @opennextjs/cloudflare@latest on this branch and re-run npm run cf:build. If it passes, this PR becomes mergeable.
  3. Meanwhile, owner-side work can continue independently: Supabase dashboard setup, migrations 001–003, Google OAuth provider, the product-images storage bucket, and the manual end-to-end auth verification against the deployed app. None of that is gated on this PR.

Validation run on this branch

  • npm run lint — clean
  • npm run build — clean (14 routes)
  • npm run cf:build — fails as documented above
  • BASE_URL=http://localhost:3000 bash ./scripts/auth-smoke.sh — 16 passed, 0 failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant