Skill Store 33

Webflow Cli:Cloud

Create, build, and deploy Webflow Cloud apps from the CLI (site-attached or project apps), and ma…

by webflow · MIT

The skill

Create, build, and deploy Webflow Cloud apps from the CLI (site-attached or project apps), and manage existing ones — apps, domains, environments, deployments, build/runtime logs, and environment variables including secrets. Use when initializing or deploying a Cloud app, importing an existing GitHub repository, setting up CI/CD (GitHub Actions or GitHub-linked deploys), setting or importing secrets, retrying or rolling back a deployment, diagnosing a failed build, or resolving app/environment/workspace IDs from webflow.json or env vars.

Webflow Cloud

Initialize new projects from templates or an existing GitHub repository, deploy to Webflow Cloud, and manage existing apps (list, inspect, logs, deployments, environments, environment variables). Deploys support two modes: site-attached (deploy to an existing Webflow site) and project app (deploy as an independent app, no existing site required).

Namespaces: apps (canonical) vs cloud (deprecated alias)

webflow apps <command> is the canonical namespace for Webflow Cloud. webflow cloud <command> still works — its init / deploy forms are aliases of the same handler — but is deprecated in favor of apps.

Canonical Deprecated cloud alias Notes
webflow apps init webflow cloud init Same options + handler — except --import and its repo-intake flags, which attach to apps init only.
webflow apps deploy webflow cloud deploy Same handler — except --json and --dry-run, which attach to apps deploy only.
— webflow cloud create <name> Deprecated ahead of removal; prefer apps init (or cloud init if staying on the legacy namespace).
— webflow cloud list Lists scaffold templates, not apps. Stays under cloud; there is no apps equivalent. Do not confuse with apps list, which lists workspace apps.
webflow apps list / get / domains / link / update / delete / environments … / deployments … / logs … / env-vars … — No cloud equivalent. Canonical-only.

Running a command through cloud init / cloud deploy prints a one-time deprecation notice on stderr pointing at the apps form (suppressed with --json).

Prefer the apps forms in all new work. This skill shows apps commands throughout; every apps init / apps deploy invocation can be run as cloud init / cloud deploy with identical flags, apart from --import (init) and --json/--dry-run (deploy).

Instructions

Step 0: Verify CLI is installed

webflow --version

If the command is not found, install it:

npm install -g @webflow/webflow-cli@latest
# or yarn global add @webflow/webflow-cli@latest
# or pnpm add -g @webflow/webflow-cli@latest

Then proceed to state detection.

Step 1: Detect project state

Run both checks before deciding which path to follow:

# Is this project already set up on Webflow Cloud?
cat webflow.json

# Is there a git remote?
git remote get-url origin 2>/dev/null

Quick reference (the CLI now writes cloud.app_id; older manifests may carry the legacy cloud.project_id, which is still read as a fallback):

cloud.app_id in webflow.json (or legacy cloud.project_id) git remote → Path
No — A — new project
Yes No B — existing project, no git
Yes Yes C — ideal state

You are running without a TTY. The CLI's interactive prompts only fire when process.stdin.isTTY is true. As an agent invoking the CLI through a subprocess, you do not have a TTY — every prompt is silently skipped, and any required value that wasn't passed as a flag triggers a hard error like --app-name cannot be empty.

Rule for every command in this skill: pass all required flags explicitly. Never rely on prompts. Pass --no-input when the CLI accepts it to make this contract explicit. The required flag set per command:

Command Always pass
apps init (site-attached) --no-input --app-name <3–39 chars> --framework <astro|nextjs|vite> --mount <path> --site-id <id>
apps init --new (app) --no-input --app-name <3–39 chars> --framework <astro|nextjs|vite|static> --workspace-id <id>
apps init --import (site-attached) --no-input --import <repo-url> --site-id <id> --mount <non-root path> --idempotency-key <key>
apps init --import --new (project app) --no-input --import <repo-url> --new --idempotency-key <key> — no --mount
apps deploy (site-attached) --no-input --mount <path> --environment <env> --site-id <id> plus --app-name on first deploy
apps deploy (project app, first deploy) --no-input --mount <path> --environment <env> --workspace-id <id> --app-name <name>

--site-id, --app-id, --framework, and --workspace-id on apps deploy let agents override what's in webflow.json at deploy time.

Multi-workspace tokens used to be an agent-fatal hang because workspace selection had no non-TTY path. Now pass --workspace-id to skip the picker. The workspace ID is not surfaced anywhere in the Webflow dashboard UI — users can't look it up by hand. If the agent doesn't have it, ask the user to run webflow apps deploy interactively once from inside their project. The preflight prompts for workspace selection and writes cloud.workspace_id to webflow.json; from that point the agent can read it from the manifest and pass --workspace-id on subsequent runs. Do not suggest apps init --new for ID discovery — on an existing project it creates a discarded scratch directory. Exception: in Path A2 (empty directory) it is safe to try apps init --new without --workspace-id to auto-resolve a single-workspace token — see Path A2.

Site IDs are visible in the dashboard. When --site-id is needed but unknown, do not ask the user for a raw site_XXXX value — use webflow sites list to fetch their sites and present a picker keyed by display name. Users can still check their dashboard to fetch it.

Read/manage commands don't need --workspace-id. The apps list / get / domains / environments / deployments / logs / env-vars commands derive the workspace server-side from the OAuth token — they have no --workspace-id flag and never prompt for a workspace. See Managing apps.


Path A: No app_id — new project

The project has not been deployed yet. Before doing anything else, ask the user two questions:

  1. "Do you already have source code for this project (an existing Next.js or Astro codebase), or are you starting from an empty directory and want a Webflow starter scaffold?"
  2. If they have code: "Is it already pushed to a GitHub repository, and do you want Webflow to build from that repo (rather than from your local files)?"

Those answers choose the branch — and the three are meaningfully different:

User has... Branch Init step
Existing code, deploying from local files Path A1 Skip apps init. It would create a ./<app-name>/ subfolder with a hello-world scaffold inside their repo, which they don't want.
Empty directory or wants a Webflow starter Path A2 Run apps init to scaffold from Webflow-Examples/hello-world-*.
Existing code already on GitHub, wants Webflow to build from the repository Path A3 Run apps init --import <repo-url> — creates a GitHub-connected app bound to the repo. apps-only; there is no cloud init --import.

The A1 vs A3 choice is not cosmetic — it decides what the app can do later. A GitHub-connected app (A3) can use apps deployments trigger / redeploy, and is the only kind eligible for dashboard push-to-deploy. An app first created by a local apps deploy (A1) is not GitHub-connected, so trigger / redeploy refuse it. If the user's code is already on GitHub and they say anything about CI, automatic deploys, rollbacks, or "deploy when I push", route to A3, not A1.

Recoverable either way: an A1 app can be pointed at a repo afterwards with apps update --github-source <repo-url> (see apps update) — but choosing A3 up front avoids the extra step.

After the branch decision, also ask site-attached vs app (only relevant before the first deploy):

User says... Mode Outcome
"deploy to my Webflow site <name>", "site-attached", references an existing site Site-attached App is bound to an existing Webflow site; site URL hosts the app at the chosen mount path. Requires --site-id.
"project app", "just an app", "no site", or no existing site mentioned Project app First deploy provisions a brand-new Webflow site (<app-name>-<hash>.webflow.io).

If the user is ambiguous on either question, ask. Do not default.


Path A1: existing codebase, deploying from local files

Check A3 first if the code is on GitHub. This path uploads and builds local files, producing an app that is not GitHub-connected — apps deployments trigger / redeploy and dashboard push-to-deploy will all refuse it. If the repo is on GitHub and the user wants Webflow to build from it, use Path A3 instead.

The user has working source. apps deploy handles everything — framework detection runs against package.json, and the preflight phase resolves identity from flags or prompts the user. No apps init needed, no webflow.json to hand-write up front.

Step 1: One-time auth (human-only). Tell the user to run this locally; agents cannot drive the browser flow:

webflow auth login

Step 2: Deploy. The exact form depends on what the agent knows.

A1-a — Site-attached, --site-id is known:

webflow apps deploy --no-input \
  --site-id site_abc123 \
  --app-name my-app \
  --framework nextjs \
  --mount /app \
  --environment main \
  --skip-mount-path-check \
  --skip-update-check

--framework is optional if package.json has a detectable signal: the Cloudflare adapter for nextjs/astro (@opennextjs/cloudflare, @astrojs/cloudflare), or the vite package itself for vite. Pass it explicitly for monorepos or when auto-detection is unreliable.

If the agent doesn't know the user's --site-id, do not ask for a raw site_XXXX value — use webflow sites list to fetch the user's sites and present readable display names to pick from.

A1-b — Project app, --workspace-id is known:

webflow apps deploy --no-input \
  --workspace-id ws_abc123 \
  --app-name my-app \
  --framework nextjs \
  --mount / \
  --environment main \
  --skip-mount-path-check \
  --skip-update-check

A1-c — Project app, workspace ID is unknown (the common gap):

The workspace ID is not visible anywhere in the Webflow dashboard UI. Users cannot look it up by hand — the only way to discover it is to run the CLI. So the path is:

Ask the user to run one interactive deploy locally. From inside their project directory:

webflow apps deploy

With no --no-input and no identity flags, the preflight prompts: "This project isn't initialized for Webflow Cloud. How would you like to deploy?" → user picks "Create a new app" → workspace picker → done. After this one human-driven deploy, cloud.workspace_id and siteId are written to webflow.json and WEBFLOW_SITE_ID to .env. The agent can then run all subsequent deploys with --site-id (the newly provisioned site).

Do not ask the user to run apps init --new to "discover" their workspace ID. On an existing project that creates a discarded ./<app-name>/ scratch directory with a hello-world scaffold inside the user's repo. Use the interactive apps deploy path above — it discovers the workspace ID and completes the first deploy in the same step.

Step 3: Set up git (if not already) — same as Path A2 step 3 below.


Path A2: empty directory, scaffold from scratch
  1. Scaffold the project — pick the form that matches the user's intent:

    # Project app (no site attachment). --workspace-id avoids the multi-workspace hang.
    webflow apps init --new --no-input \
      --app-name my-app \
      --framework astro \
      --workspace-id ws_abc123
    
    # Site-attached (connect to an existing Webflow site). Requires --site-id.
    webflow apps init --no-input \
      --app-name my-app \
      --framework astro \
      --mount /app \
      --site-id site_abc123
    

    See apps init for all flags.

    Workspace ID discovery for project apps in Path A2 only: because Path A2 starts from an empty directory, apps init --new creates a fresh scaffold either way — there's nothing to pollute. So if the agent doesn't have --workspace-id, it's safe to try apps init --new without it first:

    # Try this first if --workspace-id is unknown (Path A2 only — empty dir)
    webflow apps init --new --no-input \
      --app-name my-app \
      --framework astro
    
    • Single-workspace tokens: the CLI auto-selects the only workspace, writes cloud.workspace_id to webflow.json, and exits 0. Read it back from the manifest and pass it as --workspace-id to apps deploy in step 2.
    • Multi-workspace tokens: the workspace picker fires and the command hangs (no TTY). Set a 30-second timeout on the Bash call (or wrap the command in timeout 30s ...) — a successful single-workspace init completes in 10–20 seconds (OAuth check + GET /v2/workspaces + scaffold download from GitHub), so anything past 30s with no output is the picker hanging. Once the timeout fires, ask the user for the workspace ID directly and re-run with --workspace-id.

    For site-attached in Path A2, there is no equivalent auto-discovery — --site-id is always required up front. Use the site picker pattern below to help the user pick.

    Path A1 (existing codebase) does not get this trick. Running apps init --new in an existing project creates a discarded scratch subdirectory. The Path A1 workspace-ID discovery path stays as documented in Path A1-c.


Path A3: existing GitHub repository, GitHub-connected app

The user's code is already on GitHub and they want Webflow to build from the repository rather than from local files. apps init --import <repo-url> creates the app bound to that repo and clones it locally.

apps-only. --import exists only under apps init — there is deliberately no cloud init --import. If the user is on the cloud namespace for another reason, fall back to Path A1 and attach the repo later with apps update --github-source.

Step 0: Prerequisite — the Webflow GitHub App. It must be installed on the repository owner and connected to the workspace. The CLI cannot do this; it's dashboard/GitHub-side setup. If the import fails on permissions, this is the first thing to check.

Step 1: One-time auth (human-only). Same as A1 — agents cannot drive the browser flow:

webflow auth login

Step 2: Import. Exactly one of --site-id or --new is required — the CLI will not infer the target from anything inside the repo.

A3-a — Site-attached (--mount is required and must be non-root):

webflow apps init --import https://github.com/acme/site \
  --site-id 6234abc --mount /app --dry-run

webflow apps init --import https://github.com/acme/site \
  --site-id 6234abc --mount /app

A3-b — Project app (--mount is not allowed — a project app owns the root of its own domain):

webflow apps init --import https://github.com/acme/site --new

A3-c — Non-interactive / CI. --idempotency-key is required here. Use a retry-stable key unique to this repo + target (e.g. $GITHUB_RUN_ID-$REPOSITORY-$SITE_ID) so a retry replays the original app instead of creating a second one:

webflow apps init --import https://github.com/acme/site --new --no-input \
  --idempotency-key "$GITHUB_RUN_ID-acme-site" \
  --branch main --json

Add --skip-clone to register the app without writing anything to the filesystem — the app and environment IDs are printed instead. Useful when the repo is already checked out, or when running somewhere you don't want a clone.

--branch picks which branch builds; it defaults to the repository's default branch.

Step 3: Enable push-to-deploy (dashboard, manual). The import connects the app to the repo, but pushing does not deploy until the dashboard wiring is done — see the full workflow example, steps 3 onward. Until then, build on demand:

webflow apps deployments trigger --json

Do not run apps deploy on an A3 app to "push an update". That uploads local files and is the A1 model; for a GitHub-connected app the equivalents are deployments trigger (build current HEAD) and deployments redeploy <depId> (re-run a past commit, i.e. roll back).

Picking a --site-id from a list

When --site-id is needed (Path A1 site-attached, Path A2 site-attached, or anywhere else) and the user hasn't given one, use webflow sites list --json to enumerate sites the token can see, then present a short list of readable names for the user to choose from. The site ID is visible in the Webflow dashboard URL config, but a numeric-ID prompt is bad UX; surface display names instead unless asked for IDs.

# Returns a JSON array of sites with id, displayName, lastPublished, etc.
webflow sites list --json

Workflow:

  1. Run webflow sites list --json. The CLI exits 0 with a JSON array.

  2. Parse the output. Show the user a short list keyed by displayName (and lastPublished if the user has many sites). Example:

    Which site should this project deploy to?
    
    1. Acme Marketing  (last published 2 days ago)
    2. Acme Docs       (last published 3 weeks ago)
    3. Acme Internal   (never published)
    
  3. Map the user's pick back to its id field. Pass that as --site-id.

If webflow sites list errors (auth missing / expired), surface the error and ask the user to run webflow auth login locally; do not try to drive it from the agent.

  1. Deploy: pick the form matching the init form above. Pass --site-id (or --workspace-id for project-app first deploy) so the deploy can't misread the manifest if something is half-written.

    # Project-app first deploy — provisions the Cloud site/app/env
    webflow apps deploy \
      --no-input \
      --app-name my-app \
      --workspace-id ws_abc123 \
      --mount / \
      --environment main \
      --skip-mount-path-check \
      --skip-update-check
    
    # Site-attached first deploy — uses the existing Webflow site
    webflow apps deploy \
      --no-input \
      --app-name my-app \
      --site-id site_abc123 \
      --mount /app \
      --environment main \
      --skip-mount-path-check \
      --skip-update-check
    

    This creates the app on Webflow Cloud and sets cloud.app_id in webflow.json. Commit the updated webflow.json.

  2. Set up git (if not already):

    git init && git add . && git commit -m "init"
    git remote add origin https://github.com/your-org/my-app.git
    git push -u origin main
    
  3. (Optional) Enable push-to-deploy via the Webflow dashboard. Pushing to GitHub alone does not trigger deploys — that wiring lives in the Webflow dashboard, not in the CLI or the repo. Tell the user:

    1. Open the Webflow dashboard → their Cloud app → Settings → Git
    2. Connect their GitHub account, then select the repository and branch
    3. Confirm — the dashboard runs one initial deploy automatically to verify the connection
    4. From that moment on, every push to the connected branch triggers a deploy

    The CLI cannot perform any of these steps. If the user skips this, every deploy must be a manual webflow apps deploy invocation (Path B–style) or a CI/CD pipeline.

If a deploy auth error occurs in step 2: run webflow auth login, complete the browser flow, then retry.


Path B: app_id exists, no git remote — existing project, no git

The project is already on Webflow Cloud but has no git repo. Deploy directly and nudge toward git setup.

  1. Deploy: read webflow.json first. If siteId is set, pass --site-id matching it. If only cloud.workspace_id is set, pass --workspace-id matching it.

    webflow apps deploy \
      --no-input \
      --site-id site_abc123 \
      --mount / \
      --environment main \
      --skip-mount-path-check \
      --skip-update-check
    
  2. Nudge toward push-to-deploy: suggest the user initialize a git repo, push to GitHub, and then connect the repo in the Webflow dashboard (app → Settings → Git). The dashboard step is what activates push-to-deploy — the CLI can't do this. See Path A, steps 3–4.

If a deploy auth error occurs: run webflow auth login, complete the browser flow, then retry step 1.


Path C: app_id exists + git remote — possibly ideal

The project is deployed and has a git remote, but the existence of a remote is not proof that push-to-deploy is wired up. That wiring is a dashboard-side connection that the CLI can't introspect. Confirm before suggesting anything.

Always ask the user: "Is this repo connected to your Webflow Cloud app in the dashboard (app → Settings → Git, with a branch selected)?" The answer changes the recommendation:

  • Yes, connected — push-to-deploy is active. The only action needed is git push. Do not suggest re-linking or re-deploying.
  • No, not connected — git push does nothing on the Webflow side. Either run a manual deploy now, or have the user connect the repo in the dashboard first to activate push-to-deploy for future commits.
  • Don't know — assume not connected and recommend the dashboard connection (one-time setup, then push-to-deploy is permanent).
  1. If connected — just commit and push:

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

    Webflow Cloud picks up the push and deploys automatically. The first deploy after connection is run by the dashboard itself; subsequent pushes are picked up automatically.

  2. If not connected — two routes:

    • Activate push-to-deploy for future commits (recommended). Tell the user to open the Webflow dashboard → their Cloud app → Settings → Git, connect the repo, select the branch. The dashboard runs an initial deploy automatically to verify the connection. From then on, every git push to that branch deploys.
    • One-off manual deploy now, without enabling push-to-deploy. Pass --site-id matching the siteId in webflow.json:
      webflow apps deploy \
        --no-input \
        --site-id site_abc123 \
        --mount / \
        --environment main \
        --skip-mount-path-check \
        --skip-update-check
      
      This deploys the current state but does not wire up push-to-deploy. The next git push will still be a no-op on the Webflow side.

If a deploy auth error occurs: run webflow auth login, complete the browser flow, then retry.

Tool usage

  • Use the Bash tool for all webflow apps / webflow cloud commands
  • Use the Read tool to examine webflow.json, package.json — never modify these directly
  • Use the Glob tool to discover project files
  • Do not use Webflow MCP tools for CLI workflows

Authentication

# Interactive — local-only, opens a browser. NOT for agents or CI.
webflow auth login

webflow auth login performs an OAuth flow in the user's browser and then writes the token to .env. It refuses to run with --no-input (exits with No-input mode enabled. Aborting OAuth authentication). Agents cannot drive this command. If webflow auth login is needed (missing or expired token), ask the user to run it locally once and report back when it's done.

The CLI writes the same token env var for both modes. There is no per-mode split.

webflow auth login writes to .env:

Variable Always written? Description
WEBFLOW_API_TOKEN Yes (both modes) OAuth access token. The canonical token env var. Set by webflow auth login.
WEBFLOW_SITE_ID Site-attached only (or after first project-app deploy) Site ID. Written by apps init for site-attached projects, or by apps deploy for project apps after the first deploy provisions a site.

After the first project-app deploy, the CLI provisions a site on the backend and writes WEBFLOW_SITE_ID to .env. From that point on, the project behaves like a site-attached project — but the token env var is still WEBFLOW_API_TOKEN.

Deprecated legacy: WEBFLOW_SITE_API_TOKEN (and WEBFLOW_WORKSPACE_API_TOKEN) are read-only legacy fallbacks. The CLI never writes them, but if it finds one of them set in the environment when WEBFLOW_API_TOKEN is not set, it uses the legacy value and prints a deprecation warning on every run. Do not put WEBFLOW_SITE_API_TOKEN in .env or CI secrets for new projects — use WEBFLOW_API_TOKEN.

Other env vars (any mode):

Variable Description
DO_NOT_TRACK Set to 1 to opt out of telemetry.
WEBFLOW_SKIP_UPDATE_CHECKS Set to true to skip the @webflow package update check.

WEBFLOW_SITE_ID env var is read-only. Used at runtime when no flag or manifest value is set, but never written back to webflow.json. Setting WEBFLOW_SITE_ID=X in .env will not update the manifest — only apps init, apps deploy, and the manifest itself drive that.

GitHub Secrets: use WEBFLOW_API_TOKEN for the token in every mode. Also set WEBFLOW_SITE_ID for site-attached projects and project apps that have already had their first deploy. Never commit .env files. If existing CI uses WEBFLOW_SITE_API_TOKEN, rename it — the deploy will still succeed but every run prints a deprecation warning until you switch.

Configuration — webflow.json

{
  "siteId": "site_abc123",
  "cloud": {
    "app_id": "app_xyz",
    "environment_id": "env_xyz",
    "workspace_id": "ws_xyz",
    "framework": "nextjs",
    "skipMountPathCheck": false
  }
}

All cloud.* keys are snake_case (app_id, not appId).

Key When set Notes
siteId Site-attached: at apps init. Project app: after first deploy (CLI provisions a site). Absent on project apps that have not been deployed yet.
cloud.framework At apps init. Required for deploy resolution — see below.
cloud.app_id After first deploy. Canonical. Auto-written. Replaces the legacy cloud.project_id.
cloud.project_id Legacy only. Deprecated. Read as a fallback when cloud.app_id is absent (manifests created before the Project → App rename). New deploys never write it; will be removed in a future major release.
cloud.environment_id After first project-app deploy. Auto-written by createCloudApp.
cloud.workspace_id At project-app apps init (--new). Used by the first deploy to provision the site.
cloud.skipMountPathCheck User-managed. Equivalent to --skip-mount-path-check.

The CLI also writes cloud.deployment_type ("ssr" | "ssg" | "spa"), cloud.entrypoint_path, and cloud.framework_version into the bundled webflow.json at build time (these power the cosmic deployer's wrangler config and telemetry). They're build-time outputs — do not strip them from the source webflow.json if you find them there; missing values silently break Next.js server-side deploys.

ID resolution and env vars

A shared resolver resolves siteId, appId, environmentId, and workspaceId in a strict priority order:

explicit flag / positional arg  >  env var  >  webflow.json manifest  >  interactive prompt  >  error
Resource Flag / arg Env var (read-only) webflow.json
App ID --app-id / [appId] arg WEBFLOW_APP_ID cloud.app_id (falls back to legacy cloud.project_id)
Environment ID --environment-id / [envId] arg WEBFLOW_APP_ENVIRONMENT_ID cloud.environment_id
Site ID --site-id WEBFLOW_SITE_ID siteId
Workspace ID --workspace-id WEBFLOW_WORKSPACE_ID cloud.workspace_id

Env vars are read-only — they are never persisted back to the manifest. When a value comes from the manifest, the CLI logs a Using <resource> from webflow.json line (suppressed with --json). When nothing resolves and the command can't prompt (--no-input, CI=true, or no TTY), it exits with a machine-readable missingFlag on the error — see the --no-input contract in Managing apps.

cloud.framework resolution at deploy time:

  1. webflow.json exists with cloud.framework — used as-is. Invalid value exits with code 1.
  2. webflow.json exists but cloud.framework is absent — falls back to detecting from package.json.
  3. No webflow.json — auto-detected from package.json. CLI writes a new webflow.json on success.

Projects created via apps init always land in case 1.

Commands

webflow cloud list
webflow cloud list

Lists available scaffold templates (used by init). Check this before apps init --framework to confirm valid scaffold IDs. This is distinct from apps list (which lists your deployed apps) and lives only under the cloud namespace. Deprecated ahead of removal — it still works but prints a warning; prefer apps init --framework <bad-value> or --help to see valid scaffold IDs.

webflow apps init

Bootstrap a new app locally. Two modes: site-attached and app. (webflow cloud init is a deprecated alias with identical flags.)

Site-attached (connects to an existing Webflow site):

# Agent / non-TTY — always pass every flag
webflow apps init \
  --no-input \
  --app-name my-app \
  --framework nextjs \
  --mount /app \
  --site-id site_abc123

# Human at a real terminal — interactive prompts will fill in any missing flag
webflow apps init

Flags:

Flag Short Description
--app-name <name> -n App name. Must be 3–39 characters — the CLI rejects anything outside this range at init and at the first project-app deploy.
--project-name <name> — Deprecated alias of --app-name. Still accepted.
--framework <framework> -f Must match a scaffold ID from cloud list. Currently: nextjs, astro, vite, static (static is standalone-only — see Frameworks).
--mount <path> -m Mount path (default / for new domain, /app for existing site). Substituted into config files at scaffold time. Not stored in webflow.json.
--site-id <id> -s Required in non-interactive site-attached mode. Mutually exclusive with --workspace-id.
--workspace-id <id> -w Skips the workspace picker for --new (app mode). Mutually exclusive with --site-id.
--new — Project-app mode (no site).
--no-input — CI mode. Requires --app-name and --framework. Without --new, defaults to app behavior.

Credential resolution for --no-input site-attached: --site-id flag → siteId in webflow.json → WEBFLOW_SITE_ID env var → error.

After scaffolding a site-attached project, the CLI automatically runs a DevLink sync.

Project app (no site attachment):

# Agent / non-TTY — always pass --workspace-id to skip the workspace picker
webflow apps init --new --no-input \
  --app-name my-app \
  --framework nextjs \
  --workspace-id ws_abc123

# Human at a real terminal — prompts for workspace if not passed
webflow apps init --new

If the token sees multiple workspaces and the agent doesn't have a workspace ID, ask the user to run webflow apps deploy interactively from inside their project — the preflight prompt picks a workspace and writes cloud.workspace_id to webflow.json for subsequent agent-driven runs. The workspace ID is not exposed in the Webflow dashboard UI, so the interactive CLI run is the only practical way to discover it.

Site-attached Project app (--new)
OAuth / site selection Required at init Skipped (workspace selection instead)
WEBFLOW_SITE_ID in .env Written at init Written after first deploy only
WEBFLOW_API_TOKEN in .env Written Written
cloud.workspace_id in webflow.json Not set Set at init (used by first deploy)
Scaffold astro, nextjs, vite

Use this skill

Connect your agent to the Skill Store MCP server and ask for it by ref: webflow/webflow-cli-cloud-63905756720.

Download SKILL.md · Markdown version

Details

Publisher
webflow
Category
Software Development › DevOps & cloud
License
MIT
Updated
2026-10-19

References

More from webflow