Conversation
Comprehensive migration plan for moving the Next.js blog and embedded Sanity Studio from Vercel to Cloudflare Workers using @opennextjs/cloudflare. Covers OpenNext adapter setup, image optimization, Sanity Studio compatibility, Workers VPC for private networking, bundle size management, CI/CD pipeline, DNS cutover, and rollback strategy. https://claude.ai/code/session_01BWiNneRSNTNqphGMqE16o4
- Install @opennextjs/cloudflare and wrangler - Remove @vercel/analytics, @vercel/speed-insights, and vercel CLI - Create wrangler.jsonc with nodejs_compat, R2 cache, and Images bindings - Create open-next.config.ts with R2 incremental cache - Remove output: 'standalone' from next.config.js (OpenNext handles bundling) - Replace Vercel analytics with Cloudflare Web Analytics beacon in layout - Add preview/deploy/upload scripts to package.json - Add .open-next to .gitignore https://claude.ai/code/session_01BWiNneRSNTNqphGMqE16o4
- Add deploy-cloudflare.yml GitHub Actions workflow with test, deploy, and preview jobs - Production deploys on push to main after tests pass - PR builds run OpenNext build for validation - Remove vercel.json (no longer needed for Cloudflare deployment) https://claude.ai/code/session_01BWiNneRSNTNqphGMqE16o4
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Code ReviewI've identified 4 issues that need attention before deploying this Cloudflare Workers migration: 1. CLAUDE.md Violation: Removed Standalone Output ModeFile: The removal of
While this change appears intentional for the Cloudflare Workers migration, CLAUDE.md should be updated to reflect this architectural change. 2. Empty Sanity Project IDFile:
Fix: Replace the empty string with your actual Sanity project ID. 3. Missing Environment Variables in GitHub WorkflowFile: The build steps in both Why this matters:
Missing variables:
Fix: Add these variables to the workflow env blocks, sourced from GitHub secrets and repository variables. 4. Empty Cloudflare Analytics TokenFile: The Cloudflare Web Analytics beacon token is hardcoded as an empty string. This means every visitor downloads Fix: Either add your actual Cloudflare Web Analytics token or remove the script block until you have one. SummaryThese issues will prevent the application from functioning correctly when deployed. The most critical are:
Please address these before merging. |
|
@claude review code |
|
Claude finished @BayPhillips's task in 55s —— View job Code Review
This PR migrates the deployment from Vercel to Cloudflare Workers using the 1. Critical: Empty Sanity Project IDFile: "NEXT_PUBLIC_SANITY_PROJECT_ID": "",
2. Critical: Missing Build-Time Environment Variables in CI WorkflowFile: The build commands in the env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}Missing (all required at
Without these, the CI build will fail or produce a bundle that can't fetch any CMS content. These need to be stored as GitHub Actions secrets/variables and referenced in the workflow env block. 3. Critical:
|
| # | Severity | Issue |
|---|---|---|
| 1 | 🔴 Critical | Empty NEXT_PUBLIC_SANITY_PROJECT_ID in wrangler.jsonc |
| 2 | 🔴 Critical | Missing build-time env vars in CI workflow |
| 3 | 🔴 Critical | previewDrafts perspective set in production config |
| 4 | ✅ Fixed | Cloudflare Analytics token is now populated |
| 5 | 🟡 Warning | global_fetch_strictly_public flag — verify no private fetches |
| 6 | 🟡 Warning | R2 bucket must be created before deploying |
| 7 | 🟡 Warning | Vercel integration still active, will keep failing |
| 8 | ⚪ Minor | CLAUDE.md not updated to reflect removed standalone output |
Issues 1–3 will prevent the app from functioning correctly in production. Please address these before merging.
|
@claude fix known issues |
|
Claude finished @BayPhillips's task in 2m 14s —— View job Fixed Known Issues
What was fixed (commit
|
…loyment - Fix NEXT_PUBLIC_SANITY_PERSPECTIVE from previewDrafts to published in wrangler.jsonc - Update CLAUDE.md to reflect Cloudflare Workers hosting (was Vercel) - Update CLAUDE.md build configuration to remove standalone mode reference Co-authored-by: Bay Phillips <BayPhillips@users.noreply.github.com>
|
@claude review |
|
Claude finished @BayPhillips's task in 52s —— View job Code Review
This PR migrates deployment from Vercel to Cloudflare Workers. Previous critical issues have been addressed. Here's the current state: Previously Fixed ✅
Remaining Issues1.
The 2.
The 3.
The config changed from: const config: Config = {
...createJestConfig(), // spreads Next.js defaults inlineto: export default createJestConfig(customConfig) // passes custom config to Next.jsThis is actually the correct approach per 4.
"exclude": ["node_modules", "jest.config.ts", "__tests__", "tests"]Excluding 5. R2 bucket must be provisioned manually
The R2 incremental cache is configured but wrangler r2 bucket create bayphillips-cachebefore the first deployment. A note in CLOUDFLARE_DEPLOYMENT_PLAN.md or README would help future deployments. 6. Cloudflare Images binding may not be provisioned
"images": { "binding": "IMAGES" }Cloudflare Images is a paid add-on (different from R2). If this account doesn't have Cloudflare Images enabled, the Worker will fail to bind and won't deploy. Verify the account has Cloudflare Images, or remove this binding if image optimization isn't actively used yet. 7.
The Sanity project ID is now in the Summary
Issues 5 and 6 are infrastructure prerequisites that will prevent the Worker from starting if not addressed. Everything else is either already fixed or low priority. |
Deploy PR-specific workers (bayphillips-blog-pr-{number}) and post
preview URLs as comments on pull requests. Automatically clean up
preview workers when PRs are closed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove app/(sanity)/ route group (studio now deployed separately via npx sanity deploy) - Fix R2 bucket binding name (INCREMENTAL_CACHE → NEXT_INC_CACHE_R2_BUCKET) - Add deployment.appId to sanity.cli.ts to avoid interactive prompts This reduces the Cloudflare Worker bundle from >3MB to ~7MB (under the limit), enabling deployment on the free tier without upgrading. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🚀 Preview Deployment
Worker:
|
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Preview workers are created with a unique name, so they don't inherit secrets from the main worker. This adds a step to set the secret after deploying the preview worker. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove legacyBehavior/passHref from Link, use NavigationMenuLink asChild pattern - Destructure arrowHidden from props to prevent it being spread to DOM Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
No description provided.