← Home
HIFP · POC Hosting Runbook · v1

Operations reference for the Cloudflare Pages deployment.

Date: 2026-09-11 · Owner: Brandon
Purpose: Reference when you forget where something is or need to make a change without re-deriving the full setup.
Related: Ledger §3.49 · §3.50 · §4.4 · hifp-session-state-2026-09-11

§1 · Quick reference

At-a-glance — the ~15 things worth knowing off the top.

Production URLhttps://hifp-poc.pages.dev
Preview URL patternhttps://<7-char-hash>.hifp-poc.pages.dev
GitHub repohttps://github.com/brandonstauber/hifp-poc (private)
Local repo path~/Desktop/HIFP/poc/
Cloudflare project namehifp-poc (Pages, not Workers)
Cloudflare accountbrandonstauber@gmail.com
Zero Trust team domainhifp.cloudflareaccess.com
Access application nameHIFP POC
Access policy nameHIFP allowlist
Access allowlistBrandon · Sindhu · Fatima (emails)
Access identity providerOne-time PIN (email OTP)
Access session duration24 hours
Production branchmain (auto-deploy on push)

§2 · Current stack

Runtime · adapter · Cloudflare project type · files · env vars · build config.

Runtime

  • Framework: Next.js 14.2.35 (App Router)
  • React: 18.3.1
  • Styling: Tailwind CSS 3.4.10
  • TypeScript: 5.5.4
  • Build system: Cloudflare Pages Build System Version 3
  • Node in build: Node 20 (via NODE_VERSION env var)
  • npm behavior: legacy peer deps (via NPM_CONFIG_LEGACY_PEER_DEPS=true env var)

Cloudflare deployment adapter

@cloudflare/next-on-pages@1 — the older stable adapter for Next.js on Cloudflare Pages. NOT @opennextjs/cloudflare (Cloudflare's newer preferred path — requires Next 15+; see §10 migration path).

Cloudflare project type

  • Cloudflare Pages (not Workers-with-Static-Assets)
  • Custom domains supported natively via Pages project (not currently used; using default pages.dev)
  • Preview deployments available for non-main branches

Files in repo relevant to Cloudflare

  • package.json — deps + build scripts (kept minimal: dev, build, start, lint)
  • next.config.js — Next config (only reactStrictMode: true — clean; no OpenNext bootstrap)
  • .gitignore — includes .vercel/ (next-on-pages build output; do NOT commit)
  • No wrangler.jsonc or open-next.config.ts — those are for the Workers-with-OpenNext path we abandoned

Environment variables (Cloudflare Pages Production)

VariableValueWhy
NODE_VERSION20Ensures build uses modern Node
NPM_CONFIG_LEGACY_PEER_DEPStrueBypasses peer-dep conflict between next-on-pages@1 and current wrangler — required or npm install fails

Cloudflare Pages Build Configuration (in dashboard)

FieldValue
Framework presetNext.js
Build commandnpx @cloudflare/next-on-pages@1
Build output directory.vercel/output/static
Root directory/
Build watch paths*
Build cacheDisabled (Beta feature)

§3 · How to add a user

Two steps required — account invite AND allowlist entry. Skip either and they can't get in.

Both steps are required. A user needs (a) an accepted account invite to Brandon's Cloudflare account AND (b) an email entry on the Access policy allowlist. Steps can happen in either order, but both must complete before the user can reach the POC.

Step 1 · Invite them to the Cloudflare account

  1. Cloudflare dashboard → Manage Account (top-left account switcher) → Members
  2. Click Invite
  3. Enter the new user's email
  4. Role: Analytics (read-only) or Administrator Read Only (safer default for trio access; pick Administrator Read Only if they need to see build logs / Zero Trust config). Do NOT grant full Administrator unless they need to edit config.
  5. Send invite → user receives Cloudflare email with acceptance link
  6. User must accept by clicking the link and either signing in or creating a Cloudflare account with that email

Step 2 · Add them to the Access allowlist

  1. Cloudflare dashboard → Zero Trust (left sidebar)
  2. Access → Applications
  3. Click into HIFP POC
  4. Policies tab → click into HIFP allowlist
  5. Under Include rules → find the Emails entry → click Edit
  6. Add the new email address(es)
  7. Save

Test: the new user should immediately be able to load https://hifp-poc.pages.dev, enter their email at the Access prompt, receive an OTP in their inbox, and land in the POC.

Removing access: reverse both steps — remove from the Access allowlist AND remove from account members. Session invalidation is not immediate — existing sessions can persist up to 24 hours (the session duration). To force immediate revocation, log the user out from the Access "Users" tab in Zero Trust.

§4 · How to trigger a deploy

Three ways, in order of cleanliness.

Option A · Git push (preferred, auto-deploy)

  1. Make code changes locally at ~/Desktop/HIFP/poc/
  2. Test locally: npm run dev → open http://localhost:3000
  3. Commit: git add . && git commit -m "your message"
  4. Push: git push
  5. Cloudflare detects the push on main, auto-triggers a build
  6. Watch build log at Cloudflare dashboard → hifp-poc → Deployments

Option B · Retry existing deployment

If the latest deploy has an issue and you want to rebuild without pushing new code:

  1. Cloudflare dashboard → hifp-poc → Deployments
  2. Find the most recent deployment → ⋯ menuRetry deployment

Option C · Empty commit (force fresh build against latest main)

If Cloudflare seems out-of-sync with what's on main:

cd ~/Desktop/HIFP/poc
git commit --allow-empty -m "trigger rebuild"
git push

§5 · How to view build logs

  1. Cloudflare dashboard → Workers & Pages → click hifp-poc
  2. Deployments tab
  3. Click the deployment you want to inspect
  4. Scroll to the Build log panel — shows the full log with timestamps

For failed builds: focus on the last 30–50 lines. Errors are usually in the tail.

Downloading logs: there's a download button on the deployment detail page. Useful for archiving or troubleshooting.

§6 · How to modify the POC

Edit → test → deploy cycle.

Local dev cycle

cd ~/Desktop/HIFP/poc
npm run dev          # starts http://localhost:3000

Live-reloads on file changes. Test in local browser.

Verify build works before pushing

npm run build        # runs `next build` — fast smoke test

If this fails locally, the Cloudflare build will fail too. Fix first.

Optional: full Cloudflare-equivalent build test

NPM_CONFIG_LEGACY_PEER_DEPS=true npx @cloudflare/next-on-pages@1

Produces .vercel/output/static/_worker.js/index.js — the exact bundle Cloudflare uploads. Slower but catches Cloudflare-specific issues before push.

Push

git add .
git commit -m "your message"
git push

Auto-deploy kicks off. Expect ~3–5 min build + deploy time.

§7 · Environment variables — where + how to modify

Location: Cloudflare dashboard → hifp-poc → SettingsEnvironment variables and secrets (or "Variables and Secrets" — Cloudflare's UI naming shifts).

Current values:

  • NODE_VERSION = 20 (Production)
  • NPM_CONFIG_LEGACY_PEER_DEPS = true (Production)

To add: click + Add → variable name + value → choose Production or Preview scope → Save.

Preview environment currently has no variables set. If you want preview deploys to have the same env, add them under Preview scope too. Not currently required.

Warning: removing NPM_CONFIG_LEGACY_PEER_DEPS=true will break the next build — npm install fails on peer-dep conflict between next-on-pages@1 and current wrangler.

§8 · Cloudflare Access details

Auth layer configuration.

Application configuration

  • Application type: Private destinations (Cloudflare's rebrand of "self-hosted" in the new Zero Trust UI)
  • Application domain: hifp-poc.pages.dev
  • Session duration: 24 hours (user re-authenticates every 24 hours by default)

Policy configuration

  • Policy name: HIFP allowlist
  • Action: Allow
  • Rule type: Include → Emails
  • Included emails: Brandon + Sindhu + Fatima

Identity providers enabled

  • One-time PIN (email OTP) — user enters email → Cloudflare sends a 6-digit PIN → user pastes PIN → session begins

No OAuth (Google/GitHub/etc) is configured. If you want to add SSO later, Zero Trust → Settings → Authentication → Login methods.

Team domain

hifp.cloudflareaccess.com — this is the team's identifier in Zero Trust. Shows up in the URL bar during auth (users see hifp.cloudflareaccess.com/... briefly during login).

Cloudflare Access pricing

  • Free tier — up to 50 seats. Currently using 3. No upgrade required for foreseeable HIFP scale.

§9 · Known constraints + gotchas

What will bite you.

Cloudflare has effectively deprecated Pages

  • wrangler pages project create now silently delegates to Workers-with-OpenNext
  • Cloudflare's "Create application" UI auto-detects Next.js and routes to Workers, not Pages
  • The Pages project we're on was created via a specific legacy UI pathway that still exists but may sunset
  • Impact: if we ever need to recreate the project, may require CLI tricks or fall back to the Workers migration (§10)

next-on-pages has peer-dep fragility

  • @cloudflare/next-on-pages@1 declares peers against wrangler@^3.28 || ^4.0.0
  • Current wrangler transitively pulls workers-types@5, but next-on-pages@1 declares workers-types@4
  • Fix: NPM_CONFIG_LEGACY_PEER_DEPS=true env var (already set)

Edge runtime declaration

  • Any non-static route (currently just /share/preview/[id]) requires export const runtime = "edge" in the page file
  • next-on-pages requirement. Opposite of OpenNext-Cloudflare (which forbids inline edge-runtime)
  • If you add new dynamic routes, add the export or the build fails with "not configured to run with the Edge Runtime"

Cloudflare Warp / 1.1.1.1 on iPad

  • If Warp is enabled on iPad, .pages.dev URLs sometimes fail to resolve or hit double-hop routing issues
  • Symptom: iPad Safari shows "server can't be found"
  • Fix: disable Warp temporarily, or add exception in Warp's private destinations settings

Framework auto-detection can override manual config

  • Selecting "Next.js" as Framework preset sometimes locks other fields (Build command, Build output directory) to defaults and hides them
  • Fix: if a field disappears when you set Framework preset, set preset to None — that unlocks other fields

Preview URLs

  • Every deployment gets a permanent preview URL like https://<7-char-hash>.hifp-poc.pages.dev
  • Access protection covers both production and preview URLs (verified 2026-09-11)

.vercel/ in gitignore

  • next-on-pages writes build output to .vercel/output/
  • Should be gitignored (already is). If accidentally committed: git rm -r --cached .vercel/

§10 · Migration path — Next 15 + OpenNext-Workers

Ledger §3.50. Well-scoped, ~2–4 hours when triggered.

When to migrate

  • Not urgent today. next-on-pages works, will continue working for 12–18 months per Cloudflare's slow-deprecation timeline.
  • Trigger before: external investor traffic on POC becomes load-bearing (pre-Series A pitch cycle · Q4 2026 – Q1 2027)
  • No-action risk: eventual Cloudflare sunset of Pages forces migration under time pressure

Migration checklist

  1. Bump next 14.2.35 → 15.x (latest stable)
  2. Bump react + react-dom 18.3.1 → 19.x
  3. Bump @types/react + @types/react-dom to 19.x
  4. Update /share/preview/[id]/page.tsx: params becomes Promise<{id: string}>, function becomes async, add await params
  5. Remove export const runtime = "edge" from /share/preview/[id]/page.tsx (OpenNext requires the opposite)
  6. Add @opennextjs/cloudflare as devDep
  7. Add wrangler as devDep
  8. Add open-next.config.ts at repo root: import { defineCloudflareConfig } from "@opennextjs/cloudflare"; export default defineCloudflareConfig({});
  9. Add wrangler.jsonc at repo root with nodejs_compat compatibility flag + Workers Assets binding to .open-next/assets
  10. Update package.json scripts: add deploy: "opennextjs-cloudflare build && opennextjs-cloudflare deploy" + preview: "opennextjs-cloudflare build && opennextjs-cloudflare preview"
  11. In Cloudflare dashboard: either (a) update Build command from npx @cloudflare/next-on-pages@1 to npx opennextjs-cloudflare build, OR (b) delete the Pages project and recreate as Workers. (a) simpler.
  12. Test locally: npx opennextjs-cloudflare build → should produce .open-next/worker.js
  13. Push → verify Cloudflare build succeeds → verify URL still resolves

What breaks in Next 15

  • params and searchParams in dynamic routes become Promises — must await them
  • cookies(), headers(), draftMode() become async
  • Default fetch caching is off — may affect fetch-based data patterns (POC has none currently)
  • React 19 required — check any React-dependent package for compatibility

Rollback path

If migration hits unexpected issues, git revert to the last pre-migration commit and push. Cloudflare auto-redeploys the older version.

§11 · Recovery procedures

When things break.

Build failing on Cloudflare, unclear why

  1. View the full build log (§5) — read the last 30–50 lines carefully
  2. Reproduce locally:
    cd ~/Desktop/HIFP/poc
    NPM_CONFIG_LEGACY_PEER_DEPS=true npx @cloudflare/next-on-pages@1
  3. If local reproduces the error, fix locally + push
  4. If local succeeds but Cloudflare fails, check env vars (§7) — most common cause

URL loads 404 or blank

  1. Check Deployments tab — is the latest deploy status green?
  2. If green but URL blank: browser cache issue — hard-refresh (Cmd-Shift-R) or try incognito
  3. If red: build failed — see previous item
  4. If neither: check DNS with dig hifp-poc.pages.dev from your terminal — should return Cloudflare IPs

Cloudflare Access prompt not appearing

  • The Access application may have been disabled or the policy detached
  • Zero Trust → Access → Applications → HIFP POC → confirm the application is Enabled + policy attached

Access prompt appearing but OTP not arriving

  • Check spam folder for no-reply@notify.cloudflare.com (sender name varies)
  • Zero Trust → Access → Users → find your session → check for any error
  • Confirm email is in the policy allowlist (§3)

Someone can't get in even though they're on the allowlist

  • Check they're typing the email exactly as configured (case-insensitive, but typos matter)
  • Confirm the policy's Action is set to Allow (not Bypass or Block)
  • Zero Trust → Access → Logs → filter by their email — will show any block reasons

Total site outage

  • Check status.cloudflare.com for Pages/Workers incidents
  • curl -I https://hifp-poc.pages.dev from terminal — 200/302 = up, 5xx = Cloudflare-side, DNS failure = Cloudflare account issue
  • Fallback direct deploy:
    cd ~/Desktop/HIFP/poc
    NPM_CONFIG_LEGACY_PEER_DEPS=true npx @cloudflare/next-on-pages@1
    npx wrangler pages deploy .vercel/output/static --project-name=hifp-poc
    Bypasses git-connect and pushes a fresh deployment directly.

§12 · Path history — why this setup

Included so we don't re-litigate hosting choice under time pressure.

2026-09-11 debug marathon (~3.5 hours) explored 8 configurations:

  1. Initial Pages deploy — Next 14.2.15 too old for next-on-pages floor (needs 14.2.35+)
  2. Bump to Next 14.2.35 + edge runtime — Cloudflare actually created a Worker (not Pages), hit OpenNext version-check block
  3. Added open-next.config.ts — missing @opennextjs/cloudflare + wrangler as devDeps
  4. Added devDeps + wrangler.jsonc — OpenNext hard peer-dep requires Next 15+
  5. Migrated Next 14 → 15 + React 18 → 19 — build ran but OpenNext wrap step never happened
  6. Aliased npm run build to opennextjs-cloudflare build — infinite recursion (OpenNext internally calls npm run build)
  7. Reverted alias, set Cloudflare UI Build command to npx opennextjs-cloudflare build — Cloudflare's wrangler pages project create command revealed itself as effectively deprecated
  8. Pivoted to Cloudflare Pages via next-on-pages with Next 14 + React 18 — verified locally clean end-to-end — used legacy UI pathway to create Pages project — succeeded on first deploy after configuring env vars + build config correctly
Root cause of the pain: Cloudflare is actively consolidating Pages into Workers-with-OpenNext. Their UI, CLI, and framework auto-detection all route new Next.js projects to Workers by default. OpenNext-Cloudflare has real rough edges (Next 15+ hard requirement, sequencing bugs, recursion patterns) that made every attempt reveal a new layer.

Why we ended up on the older next-on-pages + Pages stack: it works today, no version blocks, no sequencing bugs. Cloudflare's slow-deprecation timeline gives 12–18 months of runway before real migration pressure.

The trade-off we accepted: we're on the deprecated path. Migration to Next 15 + OpenNext-Workers is queued as Ledger §3.50 pre-Series-A. See §10 for the migration checklist.

Strategic signal noted in Ledger §3.49: Cloudflare Pages deprecation is worth capturing as an eventual technology-stack risk in v4-kit thinking (currently not surfaced in Investment Memo v4 §5 tailwinds or §12 risks — arguably belongs there when memo hits v4-draft-03).

§13 · Reference commands cheat-sheet

Local development

cd ~/Desktop/HIFP/poc
npm run dev                    # http://localhost:3000
npm run build                  # smoke test
npm run lint                   # linting

Cloudflare-equivalent build (local)

NPM_CONFIG_LEGACY_PEER_DEPS=true npx @cloudflare/next-on-pages@1
# produces .vercel/output/static/_worker.js/index.js

Git ops

git status --short
git add .
git commit -m "message"
git push
git log --oneline -10

Cloudflare CLI (wrangler)

npx wrangler login             # browser auth
npx wrangler pages project list
npx wrangler pages deployment list --project-name=hifp-poc
npx wrangler pages deployment tail --project-name=hifp-poc   # live log stream

Direct deploy fallback (bypasses git-connect)

cd ~/Desktop/HIFP/poc
NPM_CONFIG_LEGACY_PEER_DEPS=true npx @cloudflare/next-on-pages@1
npx wrangler pages deploy .vercel/output/static --project-name=hifp-poc

DNS check

dig hifp-poc.pages.dev
curl -I https://hifp-poc.pages.dev

§14 · Contacts + escalation

  • Cloudflare support: dashboard → Support → for Pages/Workers issues; free plan gets community support only, so most issues get faster resolution via Cloudflare Discord #pages channel
  • next-on-pages: GitHub issues at github.com/cloudflare/next-on-pages — active but slow-response
  • Repo owner: brandonstauber@gmail.com (single-owner for POC)