Skip to content

Migrate a Next.js app from Webflow Cloud to Vercel

Move your Next.js app from Webflow Cloud to Vercel: remove the OpenNext Cloudflare adapter, drop the base path, map storage bindings to Vercel Blob, Redis, and Postgres, and deploy with Git or the vercel CLI.

8 min read
Last updated June 9, 2026

Moving a Next.js app from Webflow Cloud to Vercel mostly means removing the deployment layer that adapts your app to the Cloudflare Workers runtime. On Webflow Cloud, your app runs as a Cloudflare Worker through the OpenNext Cloudflare adapter. On Vercel, the same app runs natively on Vercel Functions with Fluid compute enabled by default, in a full Node.js runtime, so it scales automatically and supports the framework's full feature set.

This guide walks you through the full migration. You'll remove the OpenNext Cloudflare adapter and Wrangler, delete the Webflow Cloud configuration files, and drop the base path your app used to mount under a Webflow site. It also covers replacing Cloudflare storage bindings with their Vercel equivalents (for example, Object Storage with Vercel Blob), recreating environment variables, and deploying with Git or the vercel CLI.

Before you begin, make sure you have:

  • A Next.js app deployed on Webflow Cloud
  • A Vercel account
  • Vercel CLI installed (npm i -g vercel)
  • Node.js 20 or later

If you use an AI coding agent like Claude Code or Cursor, you can have it handle most of the migration for you and provide expert guidance. Install the Vercel Plugin to provide your agent with Vercel-specific context, then add the companion skill for this guide.

Install the Vercel Plugin:

Terminal
npx plugins add vercel/vercel-plugin

Add the Next.js migration skill:

npx skills add vercel-labs/vercel-kb-skills --skill nextjs-webflow-to-vercel

With both in place, ask your agent to migrate your Next.js app from Webflow Cloud to Vercel. Your agent will follow the migration steps and apply Vercel's recommended patterns for Vercel Functions, storage solutions, environment variables, and more.

On Webflow Cloud, your Next.js app runs as a Cloudflare Worker. The OpenNext Cloudflare adapter compiles it for the workerd runtime, Webflow Cloud serves it from a mount path inside an environment (for example, /app), and your server code reads storage through bindings on the Cloudflare env object.

On Vercel, the same application runs on Vercel Functions in a full Node.js runtime. Vercel auto-detects Next.js on import, serves your app from the root, reads configuration from process.env, and connects to storage providers in the Vercel Marketplace through native integrations.

The table below maps each Webflow Cloud component to its Vercel counterpart.

Webflow CloudVercel
Cloudflare Workers runtime (workerd)Vercel Functions (Fluid compute)
OpenNext Cloudflare adapter (@opennextjs/cloudflare)Native Next.js support, no adapter
webflow.jsonNot needed, Next.js is auto-detected
wrangler.jsonvercel.json (optional)
open-next.config.tsNot needed
cloudflare-env.d.tsNot needed
basePath and assetPrefix (mount path)Served from the root; remove unless you want a base path
getCloudflareContext().envprocess.env
webflow cloud deploy or GitHub pushGit push or the vercel CLI
npm onlynpm, pnpm, Yarn, or Bun
Object Storage (R2 binding)Vercel Blob
Key Value Store (Workers KV binding)Redis from the Vercel Marketplace, or Edge Config for read-heavy config
SQLite (D1 binding)Postgres from the Vercel Marketplace
Edge runtime middleware onlyFull Next.js middleware support
export const runtime = 'edge' on routesRemove it to run on Node.js (recommended)
No scheduled jobs, queues, or workflowsCron Jobs, Queues, and Workflows

Vercel runs Next.js natively, so you no longer need an OpenNext adapter.

Uninstall OpenNext and Wrangler:

Terminal
npm uninstall @opennextjs/cloudflare wrangler

Then remove the OpenNext dev hook from next.config.ts. The create-cloudflare setup adds these lines so getCloudflareContext() works in next dev, and they no longer apply on Vercel:

next.config.ts
// Remove these lines
import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
initOpenNextCloudflareForDev();

Delete the Cloudflare- and Webflow-specific files that no longer apply on Vercel:

  • webflow.json, which told Webflow Cloud your framework. Vercel detects Next.js automatically.
  • wrangler.json, including its compatibility_date, nodejs_compat flag, assets binding, and storage bindings. Vercel Functions run on Node.js, so the compatibility flags have no equivalent.
  • open-next.config.ts, the adapter configuration.
  • cloudflare-env.d.ts (sometimes cloudflare.env.ts), the generated binding types.

Your storage bindings live in wrangler.json. Before deleting the file, note which bindings your app uses (Object Storage, Key Value Store, or SQLite) so you can recreate them on Vercel in step five.

On Webflow Cloud, your app is served from a mount path such as /app, so you set basePath and assetPrefix in next.config.ts to match.

On Vercel, your app is served from the root, so remove both options unless you intend to keep serving the app under a subpath:

next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
// Remove basePath and assetPrefix when serving from the root
// basePath: "/app",
// assetPrefix: "/app",
};
export default nextConfig;

Because the base path is gone, remove the manual prefixing Webflow Cloud required in client-side fetch calls and asset references. For example, change fetch(${basePath}/api/users) back to fetch("/api/users"), and drop the asset prefix from plain <img> tags.

Webflow Cloud also runs API routes and middleware on the Edge runtime. On Vercel, remove the export const runtime = 'edge' directive so those routes run on the default Node.js runtime. We recommend migrating from the Edge runtime to Node.js for improved performance and reliability, and both runtimes run on Fluid compute with Active CPU pricing. Running on Node.js also gives your routes access to the full Node.js API surface and to npm packages that depend on Node.js built-ins.

Replace the Webflow Cloud preview script in package.json with the standard Next.js commands. Vercel runs the build for you, so you no longer need the opennextjs-cloudflare preview command:

package.json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}

Vercel auto-detects Next.js on import and sets the build command and output directory, so these scripts mainly support local development.

This is the core code change.

On Webflow Cloud, you read storage through bindings on the Cloudflare env, which you access in a Route Handler with getCloudflareContext().

On Vercel, you read connection details from process.env and talk to each store through its SDK or client. Remove every getCloudflareContext() call and replace the binding operations.

For example, an Object Storage upload on Webflow Cloud looks like this:

app/api/upload/route.ts
// Before (Webflow Cloud Object Storage, R2 binding)
import { getCloudflareContext } from "@opennextjs/cloudflare";
export async function POST(request: Request) {
const { key, content } = await request.json();
const { env } = getCloudflareContext();
await env.MEDIA_BUCKET.put(key, content);
return Response.json({ success: true });
}

On Vercel, the same upload uses Vercel Blob:

app/api/upload/route.ts
// After (Vercel Blob)
import { put } from "@vercel/blob";
export async function POST(request: Request) {
const { key, content } = await request.json();
const blob = await put(key, content, { access: "public" });
return Response.json({ url: blob.url });
}

Install the Blob SDK with npm i @vercel/blob, then create a Blob store from the Storage page in your Vercel dashboard and connect it to your project. Vercel adds the store's environment variables, and the SDK uses them automatically, so the put() call above needs no token in your code. This OIDC approach is recommended over the long-lived BLOB_READ_WRITE_TOKEN, which you'd use only for code that runs outside Vercel.

Map your other Webflow Cloud storage the same way:

  • Key Value Store becomes a Redis integration (e.g., Upstash Redis) from the Vercel Marketplace for caching and session data, or Edge Config for small, read-heavy configuration.
  • SQLite becomes a Postgres database (e.g., Neon) from the Vercel Marketplace.

When you provision storage from the Marketplace, Vercel adds the connection string and credentials as environment variables, which your code reads from process.env.

Recreate your Webflow Cloud environment variables as Vercel environment variables. Webflow Cloud stores these per environment in your app's settings and injects them at runtime only. Vercel stores them per environment (production, preview, and development) in project settings and makes them available at both build time and runtime.

Add each variable to your project's environment variables, or from the CLI:

Terminal
vercel env add DATABASE_URL production

To run your app locally with the same values, link the project and pull the variables into a local .env file:

Terminal
vercel link
vercel env pull

Because Vercel exposes environment variables during the build, you can re-enable any build-time validation you had to disable on Webflow Cloud, where variables aren't available at build time.

You have two deployment options. Both run your app on Vercel Functions.

Deploy with Git (recommended):

  1. Push your project to GitHub, GitLab, or Bitbucket.
  2. In the Vercel dashboard, select Add New > Project, then import your repository.
  3. Vercel detects Next.js and sets the build command and output directory. Confirm the framework preset, add your environment variables, and select Deploy.

After the first import, every push to your main branch creates a production deployment, and every pull request gets its own preview URL.

Deploy with the CLI:

vercel

Run vercel from your project root to create a preview deployment, or vercel --prod to deploy to production.

Once deployed, your app runs on Vercel Functions with Fluid compute, with preview deployments, observability, and the Vercel Firewall available.

Server code still imports the adapter or calls getCloudflareContext(). Search your project for @opennextjs/cloudflare and getCloudflareContext, and replace each binding call with its Vercel equivalent from step five. The adapter module is only resolved within the build that targets Cloudflare Workers.

A leftover base path is usually the cause. Confirm you removed basePath and assetPrefix from next.config.ts, and remove any manual base-path prefixing from client-side fetch calls and <img> tags. On Vercel, your app is served from the root, so paths like /api/users and /logo.png resolve without a prefix.

Confirm each variable exists in the correct environment under your project's environment variables, then redeploy. Variables added to production aren't available in preview or development unless you add them there too. For local runs, re-run vercel env pull after changing variables.

  • Tune function resources per route. If specific routes need more memory or a longer timeout than the default, set maxDuration in the route's segment config (for example, export const maxDuration = 60), or configure memory and regions in vercel.json.
  • Place functions near your data. Set the function region close to your database region to reduce latency.
  • Take advantage of features that were limited on Webflow Cloud. Incremental Static Regeneration, on-demand and tag-based revalidation, the use cache directive, and Node.js middleware all work on Vercel without extra configuration.

Was this helpful?

supported.