Bring your own app

Deploy your own Next.js, Astro, or Vite app on Webflow Cloud.

Webflow Cloud deploys your app using the Edge runtime, enabling fast, globally distributed hosting. Before deploying to Webflow Cloud, your app may require some configuration to ensure compatibility with the Edge environment.

These instructions guide you through deploying an existing Next.js or Astro app to Webflow Cloud.

Get Started with Webflow Cloud

To familiarize yourself with Webflow Cloud, try the walkthrough in Get started with Webflow Cloud first.

Time Estimate: 30 minutes

Prerequisites

  • A Webflow account
  • A GitHub account
  • One of the following applications in a GitHub repository:
    • An Astro app (version 6 or 7)
    • A Next.js app (version 15 or higher)
    • A Vite app (version 6.1 or higher) — React, Vue, Svelte, or vanilla JavaScript
  • Node.js 22 or later and npm installed
    • Note: Currently, Webflow Cloud supports only the npm package manager
    • Note: Astro 6 and Astro 7 require Node.js 22.12 or later

Fast path: one-click deploy

To deploy an application from a GitHub repository quickly, click this button and follow the steps to deploy it to Webflow Cloud:

Deploy to Webflow

The process prompts you to select a GitHub repository, install the GitHub app that gives Webflow access to the repository, and specify how to deploy it to Webflow Cloud.

To generate a one-click deploy button, see Deploy with one click.

Deploying an application from GitHub

Follow these steps to deploy an application from a GitHub repository:

  1. Log in to Webflow and go to your dashboard.

  2. From your Workspace, click New Project > App and authorize Webflow to access your GitHub account.

  3. Expand Import a GitHub repository, specify the GitHub organization and repository, and click the Import button next to the repository, as in this picture:

    Selecting the GitHub repository
  4. Give the app a name for Webflow Cloud and select the branch to deploy as in this picture:

    Selecting the branch to deploy
  5. Optional: Under Advanced settings, select the path to the root of the application and add any environment variables that the app needs.

  6. Click Deploy.

Webflow publishes the application and shows information about it.

  • To see information about applications that are part of a site, go to the site settings and click Webflow Cloud. The applications that are part of this site are listed. Then you can click an application to see information about its environments and deployments.

    Looking at the applications within a site
  • To see information about applications that are not within a site, go to the Workspace settings, where applications are listed next to sites. You can filter the list by clicking All projects > Apps.

    Looking at the applications within a workspace

    To get to its environments and deployments, open the application’s settings and then click Webflow Cloud.

Configuring applications for Webflow Cloud

These sections describe how to ensure that your application runs properly on Webflow Cloud.

Configure your app

In most cases, you don’t. Webflow Cloud reads your package.json, detects your framework, and generates the deployment configuration when it builds your app. You commit your app the way you’d normally write it.

Here’s what that means in practice — this is the complete next.config.ts from the Next.js starter, which deploys to Webflow Cloud as-is:

next.config.ts
1import type { NextConfig } from "next";
2
3const nextConfig: NextConfig = {
4 /* config options here */
5};
6
7export default nextConfig;

No adapter, no base path, no wrangler.json.

What the platform owns, and what you own

ConfigurationOwner
Framework and version detectionWebflow Cloud, from your package.json
Installing and wiring the Cloudflare adapterWebflow Cloud
Base path and asset prefixWebflow Cloud, from your environment’s mount path
Production deployment configurationWebflow Cloud
Your app code and framework optionsYou
Storage bindingsYou declare them, Webflow Cloud provisions them
Leave the base path unset

Don’t set basePath/assetPrefix (Next.js) or base/build.assetsPrefix (Astro) in your framework config. Webflow Cloud sets them at build time from your environment’s mount path, and overwrites whatever you commit.

Read the values at runtime instead of hard-coding them — see Mount path configuration. If you need your local server to match a non-root mount path, see Local development.

Optional: declare your framework explicitly

Detection is automatic. If you want to pin it — for example in a monorepo, or a repo where detection is ambiguous — add a webflow.json at your app root:

webflow.json
1{
2 "cloud": {
3 "framework": "nextjs"
4 }
5}

Supported values are nextjs, astro, vite, and static. For Astro, use astro — Webflow Cloud detects the major version from your package.json and selects the matching adapter.

Local development

You have two options, and which one you want depends on what you’re doing.

Use your framework’s own dev server. Nothing to install beyond your app’s own dependencies, and no Cloudflare or Webflow packages.

$next dev

This is the fastest feedback loop and the right default for building UI and business logic.

Two differences from production to be aware of:

  • Your app serves from /, not from your mount path. Webflow Cloud applies the base path at build time only. If your environment is mounted at the root, there’s no difference. If it’s mounted at a subpath like /app, your local URLs won’t carry that prefix — which is exactly why you should read the base path at runtime rather than hard-code it.
  • Storage bindings aren’t connected. Use the parity option below if your app reads from KV, D1, or R2.

Storage bindings

If your app uses KV, SQLite, or object storage, commit a wrangler.json that declares the bindings. Webflow Cloud reads it during deployment, provisions the resources for your environment, and injects the real IDs.

wrangler.json
1{
2 "$schema": "node_modules/wrangler/config-schema.json",
3 "name": "my-app",
4 "compatibility_date": "2025-04-15",
5 "d1_databases": [
6 { "binding": "DB", "database_name": "db", "database_id": "0", "migrations_dir": "drizzle" }
7 ],
8 "kv_namespaces": [{ "binding": "SESSIONS", "id": "local" }],
9 "r2_buckets": [{ "binding": "MEDIA", "bucket_name": "media" }]
10}
The ID values are placeholders

database_id and id are required, so local commands like wrangler types and wrangler d1 migrations apply --local work. The values you commit are never used in production — Webflow Cloud replaces them with the IDs of the resources it provisions for your environment. Use any placeholder you like.

What matters is the binding name (DB, SESSIONS, MEDIA). That’s what your code reads, and it’s preserved exactly.

Missing required fields are skipped silently

Webflow Cloud validates this file before reading your bindings. If a required field is missing, it logs an error to your build logs and continues without your bindings — the build succeeds and the app deploys, but your storage isn’t connected. If your bindings seem to vanish in production, check the build log for a validation error first.

Required fields are name and compatibility_date at the top level, plus:

BindingRequired fields
kv_namespacesbinding, id
d1_databasesbinding, database_name, database_id
r2_bucketsbinding, bucket_name

For a complete working example, see the starters with bindings wired up: Next.js and Astro.

Managing assets and APIs

1

Asset references

How you reference assets depends on which component you’re using:

Next.js Image component: Local images are automatically optimized and served through Webflow’s CDN.

src/app/components/Logo.tsx
1import Image from "next/image";
2
3export function Logo() {
4 return (
5 <Image
6 src="/images/logo.png" // No prefix needed - automatically optimized
7 alt="Logo"
8 width={180}
9 height={40}
10 priority
11 />
12 );
13}

Plain img tags: Must include the base path to load correctly and enable CDN caching.

src/app/components/Icon.tsx
1// Set NEXT_PUBLIC_BASE_PATH in your environment variables to your mount path
2const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? '';
3
4export function Icon() {
5 return (
6 <img
7 src={`${basePath}/icons/star.svg`} // Prefix required for CDN caching
8 alt="Star icon"
9 />
10 );
11}

Don't import your own next.config

Reading basePath by importing next.config doesn’t work on Webflow Cloud. The builder generates its own next.config at build time and moves yours aside, so the value you read locally isn’t the value used in production. Use an environment variable, as shown above.

2

APIs

When your app is served from a mount path, there’s an important distinction between API route definitions and client-side requests:

  1. Server-side API route handlers are automatically mounted at your base path by Next.js. To ensure your API routes run on the Edge runtime, add the export const runtime = 'edge'; directive to your API route.
  2. Client-side fetch calls must manually include the base path to correctly reach your endpoints

Without these adjustments, your client-side fetch calls will fail by targeting the wrong URL. Implement these patterns in all your APIs and client-side data fetching functions:

1// /src/pages/api/data.ts
2import { NextRequest, NextResponse } from 'next/server';
3
4export async function GET(request: NextRequest) {
5 return NextResponse.json({ message: 'Hello, world!' });
6}

Link and next/image handle this for you

Next.js applies the base path automatically to <Link>, useRouter(), redirect(), and the next/image component. You only need the prefix for plain <img> tags and manual fetch calls.

Edge Runtime: Use fetch API

The Edge runtime has limited API support. Stick to fetch for API calls and avoid third-party clients like axios which may not be compatible.

Configuring environment variables

1

Access environment variable settings

In Webflow Cloud, navigate to your app’s environment settings:

  • If the application is in your Workspace:

    1. Open the Dashboard, go to your Workspace settings, and click All projects > Apps.
    2. Click the application to open its settings and then click Webflow Cloud.
    3. In the table of apps, click the app.
    4. In the table of environments, click the environment.
    5. In the table, go to the Environment variables tab.
  • If the application is in a site:

    1. Open the site settings and click Webflow Cloud.
    2. In the table of apps, click the app.
    3. In the table of environments, click the environment.
    4. In the table, go to the Environment variables tab.
2

Add and configure environment variables

Add each environment variable that your application requires:

  1. Click Add Variable
  2. Enter a name for the variable, such as DATABASE_URL or API_KEY
  3. Enter the value for the variable
  4. Toggle Secret Variable for sensitive values that should be encrypted, such as API keys and tokens
  5. Click Add variable

Repeat this process for all required variables.

Environment variables are available during builds and at runtime

Both secret and non-secret environment variables are available to your application’s build process—for example, for auth-framework configuration—and remain available to the deployed application at runtime. Secret values are value-redacted from Webflow Cloud build logs. Even so, avoid intentionally printing secrets, since redaction is a safety mechanism rather than a recommended secret-handling workflow.

Because variables are available at build time, framework variables that get inlined during the build (such as NEXT_PUBLIC_* and Astro’s PUBLIC_*) work as expected. Anything inlined this way ends up in the JavaScript you ship to browsers, so don’t mark a value secret and then inline it.

3

Access environment variables in your code

Your environment variables are accessible in your code using the following methods.

Next.js provides environment variables through the process.env object.

Next.js
1process.env.VARIABLE_NAME

Deploying applications

After configuring your app:

1

Run your app locally

Before deploying, check your app with your framework’s dev server:

$npm run dev

For a run against the same runtime Webflow Cloud uses, including storage bindings, see Local development.

2

Authenticate with Webflow

In your terminal, run the following command to authenticate with Webflow:

$webflow auth login

This command opens a browser window to authenticate your Webflow account. After you grant access, the CLI saves a WEBFLOW_API_TOKEN to a .env file at the root of your app. The first time you run webflow cloud deploy, the CLI prompts you to choose the deploy target (site-attached or standalone) and the specific site or workspace — it does not pick one for you at login.

You can skip this step and let webflow cloud deploy trigger the OAuth flow on demand.

3

Deploy using the Webflow CLI

After authenticating, run the following command to deploy your app:

$webflow cloud deploy

On the first run, the CLI prompts you to identify the deploy target — choose Existing site to attach the app to a Webflow site (mounted at a path like /app), or New domain to deploy as a standalone app hosted on its own subdomain. To skip these prompts in CI/CD, pass --no-input together with --site-id (site-attached) or --workspace-id (standalone). See the webflow cloud deploy reference for all flags.

Additionally, when you commit your changes to your GitHub branch, Webflow Cloud will automatically detect the changes and deploy your app to your environment. Learn more about deployments in the documentation.

Your deployment may take up to 2 minutes to complete

View your deployment in the “Environment Details” dashboard. Review the status of your deployment by viewing the build logs.

4

View your app at your site's URL + mount path

Once your app has been successfully deployed, navigate to your site’s domain and mount path to see your newly deployed Webflow Cloud app!

Next steps

Now that you’ve successfully deployed your app on Webflow Cloud, here’s what you can do next.

Troubleshooting

For an app on its own domain, verify that the latest deployment succeeded.

For an app on a site, if you have never published your site before, publish it now. If you have already published your site, check your mount path, confirm the environment exists, and verify that the latest deployment succeeded.

The Webflow Cloud GitHub App may not have access to your repository. To check, go to the Webflow Cloud tab in your Webflow site settings and click “Install GitHub App.” Follow the prompts on GitHub to ensure Webflow has access to read from your repository. Once you grant access, try committing to the branch that Webflow Cloud should be monitoring for deployments in your app.

Check that you’re correctly using the base path in all asset and API references. Look for fixed paths that might be missing the base path prefix.

Verify that your callback URLs include the correct base path and that you’re not duplicating the base path in your code references.

Check your app’s build logs in the Webflow Cloud dashboard. Common issues include:

  • An incompatible Node.js version
  • Environment variables not configured correctly
  • A framework version Webflow Cloud doesn’t support yet — check the supported frameworks
  • A custom build script — Webflow Cloud runs the framework’s own build (opennextjs-cloudflare build or astro build) and ignores a custom build script in your package.json

Webflow Cloud overrides custom cache headers from your application. Once content is cached, you can’t control caching behavior through standard HTTP headers like Cache-Control. See more on header behavior limitations here.

This means traditional cache invalidation methods won’t work - you’ll need to work within Webflow Cloud’s caching behavior rather than trying to override it.