diff --git a/plugins/webflow-skills/skills/webflow-cloud-command/SKILL.md b/plugins/webflow-skills/skills/webflow-cloud-command/SKILL.md index f31edc8..6df00a2 100644 --- a/plugins/webflow-skills/skills/webflow-cloud-command/SKILL.md +++ b/plugins/webflow-skills/skills/webflow-cloud-command/SKILL.md @@ -1,944 +1,679 @@ --- name: webflow-cli:cloud -description: Initialize, build, and deploy full-stack Webflow applications to Webflow Cloud hosting. List available templates, initialize projects with cloud init, and deploy with comprehensive validation. Use when creating or deploying Webflow Cloud applications. +description: Initialize, build, and deploy full-stack Webflow applications to Webflow Cloud hosting. Supports site-attached projects and apps (no site required). Use when creating new projects, deploying existing ones, or setting up CI/CD pipelines for Webflow Cloud. --- # Webflow Cloud -Initialize new projects from templates, build applications, and deploy to Webflow Cloud with comprehensive validation and deployment verification. +Initialize new projects from templates and deploy to Webflow Cloud. Supports two modes: **site-attached** (connected to a Webflow site) and **app** (independent app, no site required). -## Important Note - -**ALWAYS use Bash tool for all Webflow CLI operations:** -- Execute `webflow cloud` commands via Bash tool -- Use Read tool to examine configuration files (never modify) -- Use Glob tool to discover project files -- Verify CLI installation: `webflow --version` -- Check authentication: Use `webflow auth login` for site authentication -- DO NOT use Webflow MCP tools for CLI workflows -- All CLI commands require proper descriptions (not context parameters) - -**Non-Interactive Deployment (CRITICAL for agents and automation):** -The Webflow CLI is interactive by default (environment selection prompts, mount path prompts, update checks). Since AI agents and CI/CD pipelines cannot interact with interactive prompts, you MUST always use these flags together for deployment: -- `--no-input` — Disables all interactive prompts (environment selection, confirmations, etc.) -- `--mount ` — REQUIRED with `--no-input` to avoid `ENVIRONMENT_MOUNT_MISMATCH` errors. You MUST determine the correct mount path before deploying — see below. -- `--skip-mount-path-check` — Skips interactive mount path validation -- `--skip-update-check` — Skips the interactive package update check +## Instructions -**Determining the mount path (NEVER assume a default):** -The mount path varies between projects (e.g., `/app`, `/`, `/blog`). Assuming a common default like `/app` WILL cause deployment failures if the project uses a different path. The Webflow CLI does NOT persist the mount path to `webflow.json` after init or deploy, so it is often not available in local config. Follow these steps in order: -1. **Check `webflow.json`** — Read the `cloud` section and look for a `mount` or `mountPath` field. It is usually NOT present, but check anyway. -2. **Ask the user** — If the mount path is not in `webflow.json` (which is the common case), you MUST ask the user before deploying: _"What mount path does this project use? (e.g., /app, /, /blog)"_. Do NOT guess, do NOT assume `/app`, and do NOT proceed without a confirmed mount path. +### Step 0: Verify CLI is installed -The canonical non-interactive deploy command is: ```bash -webflow cloud deploy --no-input --mount --skip-mount-path-check --skip-update-check +webflow --version ``` -Add `--auto-publish` if the user wants changes published immediately. -**Package Manager Detection:** -- Check for lock files: `package-lock.json` (npm), `pnpm-lock.yaml` (pnpm), `yarn.lock` (yarn) -- If no lock file found, ask user which package manager to use (npm/pnpm/yarn) -- Use detected package manager for all install/build commands +If the command is not found, install it: -## Instructions +```bash +npm install -g @webflow/webflow-cli +# or yarn global add @webflow/webflow-cli +# or pnpm add -g @webflow/webflow-cli +``` -### Phase 1: Determine Operation Type -1. **Identify user intent**: What does the user want to do? - - List available project templates (`cloud list`) - - Initialize new Cloud project (`cloud init`) - - Deploy existing Cloud project (`cloud deploy`) -2. **Verify CLI installed**: Run `webflow --version` to confirm CLI is installed -3. **Check project state**: Determine if in existing project or starting new - -### Phase 2A: List Templates (if needed) -4. **List available templates**: Run `webflow cloud list` -5. **Show template options**: Display available frameworks (Astro, Next.js, etc.) -6. **Explain templates**: Brief description of each template - -### Phase 2B: Initialize New Project (if needed) -7. **Run cloud init**: Execute `webflow cloud init` with options: - - `--framework` or `-f`: Choose framework (astro, nextjs) - - `--mount` or `-m`: Mount path (e.g., `/app`) - - `--site-id` or `-s`: Webflow site ID to connect -8. **Monitor initialization**: Show CLI output -9. **Verify project created**: Check for webflow.json and project structure -10. **Show configuration**: Read and display webflow.json with cloud section - -### Phase 2C: Validate Existing Project (if deploying) -11. **Check authentication**: Verify site authentication (created via `webflow auth login`) -12. **Read project configuration**: Examine `webflow.json` cloud section: - - `projectId`: Cloud project identifier (set automatically on first deploy) - - `framework`: Either "nextjs" or "astro" - - `mount` or `mountPath`: Mount path (may or may not be present) -13. **Determine mount path**: Follow the "Determining the mount path" steps above. If the mount path is not in `webflow.json`, ask the user before proceeding. NEVER default to `/app` or any other value. -14. **Validate project structure**: - - Required files present - - Build scripts configured - - webflow.json has cloud configuration - -### Phase 3: Build Execution (for deployment) -14. **Run build command**: Execute `npm run build` or configured build script -15. **Monitor build progress**: Show build output and detect errors -16. **Validate build output**: - - Build artifacts created - - Output directory exists - - No critical errors - -### Phase 4: Deployment Preview (for deployment) -17. **Show deployment summary**: - - Project name and framework - - Build output location - - Environment configuration (if using --env) - - Mount path (if specified) - - Auto-publish setting (if using --auto-publish) -18. **Explain deployment process**: What happens during deployment -19. **Require explicit confirmation**: User must type "deploy" to proceed - -### Phase 5: Deployment Execution -20. **Execute deploy command**: Run `webflow cloud deploy` with non-interactive flags: - - `--no-input`: REQUIRED — disables all interactive prompts - - `--mount` or `-m`: REQUIRED — mount path (e.g., `/app`). Must match the existing environment's mount path. - - `--skip-mount-path-check`: REQUIRED — skips interactive mount path validation - - `--skip-update-check`: RECOMMENDED — skips interactive package update check - - `--auto-publish`: Optional — publish site after deployment - - `--project-name` or `-p`: Project name (for new projects only) - - `-e` or `--environment`: Environment name (defaults to first available with `--no-input`) -21. **Monitor deployment progress**: Show CLI output and deployment stages -22. **Verify deployment success**: Confirm deployment completed -23. **Provide post-deployment information**: - - Deployment success message - - Site URL (if published) - - Next steps +Then proceed to state detection. -## Examples +### Step 1: Detect project state -### Example 1: List Available Templates +Run both checks before deciding which path to follow: -**User prompt:** -``` -What Webflow Cloud templates are available? -``` +```bash +# Is this project already set up on Webflow Cloud? +cat webflow.json -**Response:** +# Is there a git remote? +git remote get-url origin 2>/dev/null ``` -📋 Webflow Cloud Templates -Listing available templates... -Executing: webflow cloud list +**Quick reference:** -Output: -Available templates: -1. astro - Astro framework template -2. nextjs - Next.js framework template +| `cloud.project_id` in `webflow.json` | git remote | → Path | +|---|---|---| +| No | — | **A** — new project | +| Yes | No | **B** — existing project, no git | +| Yes | Yes | **C** — ideal state | -Use these templates with: -webflow cloud init -f +--- -Example: -webflow cloud init -f astro -m /app -``` +> **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 `--project-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 | +> |---|---| +> | `cloud init` (site-attached) | `--no-input --project-name <3–39 chars> --framework --mount --site-id ` | +> | `cloud init --new` (app) | `--no-input --project-name <3–39 chars> --framework ` | +> | `cloud deploy` | `--no-input --mount --environment ` plus `--project-name` on first deploy | +> +> **One agent-fatal exception:** `cloud init --new` against a token that sees more than one workspace will **hang forever** — workspace selection is always interactive and has no `--workspace` flag and no non-TTY fallback. If you don't know whether the user's token is single- or multi-workspace, ask the user to run `cloud init --new` once locally; from there `cloud.workspace_id` is in `webflow.json` and you can take over. -### Example 2: Initialize New Cloud Project +--- -**User prompt:** -``` -Create a new Webflow Cloud project with Astro -``` +### Path A: No `project_id` — new project -**Step 1: Verify CLI** -``` -🔍 Webflow CLI Check +The project has not been deployed yet. Scaffold and deploy from scratch. -Checking CLI installation... -✓ Webflow CLI installed: v1.5.2 +**Before you run anything, ask the user which mode they want.** Picking wrong here is unrecoverable without manual cleanup — the deploy decision is locked into `webflow.json` at init time. -Ready to initialize Webflow Cloud project with Astro. +| User says... | Mode | Outcome | +|---|---|---| +| "deploy to my Webflow site ``", "site-attached", references an existing site | **Site-attached** | Project is bound to an existing Webflow site; site URL hosts the app at the chosen mount path. Requires `--site-id`. | +| "standalone", "just an app", "no site", or no existing site mentioned | **App (`--new`)** | First deploy provisions a brand-new Webflow site (`-.webflow.io`). | -Options needed: -1. Mount path (where project will be accessible, e.g., /app) -2. Site ID (optional - Webflow site to connect to) +If the user is ambiguous, **ask** before scaffolding. Do not default. -Would you like to initialize with default settings (/app mount path)? -``` +1. **Scaffold the project** — pick the form that matches the user's intent: -*User confirms: yes* + ```bash + # App (no site attachment) — single-workspace tokens only, see TTY note above + webflow cloud init --new --no-input \ + --project-name my-app \ + --framework astro + ``` -**Step 2: Initialize Project** -``` -🚀 Initializing Webflow Cloud Project + ```bash + # Site-attached (connect to an existing Webflow site) — agent must already know --site-id + webflow cloud init --no-input \ + --project-name my-app \ + --framework astro \ + --mount /app \ + --site-id site_abc123 + ``` -Executing: webflow cloud init -f astro -m /app + See [`cloud init`](#webflow-cloud-init) for all flags. If you don't have `--site-id` and the user wants site-attached, ask the user for the site ID before running anything. -Output: -✓ Creating new Astro project -✓ Installing dependencies -✓ Configuring Webflow Cloud -✓ Creating webflow.json +2. **Deploy:** + ```bash + webflow cloud deploy \ + --no-input \ + --project-name my-app \ + --mount / \ + --environment main \ + --skip-mount-path-check \ + --skip-update-check + ``` + This creates the project on Webflow Cloud and sets `cloud.project_id` in `webflow.json`. Commit the updated `webflow.json`. -Project initialized! +3. **Set up git** (if not already): + ```bash + 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 + ``` + From this point, every push to the connected branch triggers an automatic deploy. -📁 Project Structure: -/my-cloud-project/ -├── webflow.json (Cloud configuration) -├── package.json -├── src/ -│ └── pages/ -│ └── index.astro -├── public/ -└── astro.config.mjs +> If a deploy auth error occurs: run `webflow auth login`, complete the browser flow, then retry step 2. -📋 Configuration (webflow.json): -{ - "cloud": { - "projectId": "", // Will be set on first deploy - "framework": "astro" - } -} +--- -✅ Project Ready! +### Path B: `project_id` exists, no git remote — existing project, no git -Next Steps: -1. Build your application: npm run dev -2. Add your code to src/ -3. Deploy: webflow cloud deploy -``` +The project is already on Webflow Cloud but has no git repo. Deploy directly and nudge toward git setup. -### Example 3: Initialize with Site ID +1. **Deploy:** + ```bash + webflow cloud deploy \ + --no-input \ + --mount / \ + --environment main \ + --skip-mount-path-check \ + --skip-update-check + ``` -**User prompt:** -``` -Initialize Cloud project with Next.js for site ID abc123 -``` +2. **Nudge toward git:** suggest the user initializes a git repo and pushes to GitHub to unlock commit-push-deploy automation (see Path A, step 3). -**Response:** -``` -🚀 Initializing Webflow Cloud Project +> If a deploy auth error occurs: run `webflow auth login`, complete the browser flow, then retry step 1. -Framework: Next.js -Mount Path: /app -Site ID: abc123 +--- -Executing: webflow cloud init -f nextjs -m /app -s abc123 +### Path C: `project_id` exists + git remote — ideal state -Output: -✓ Creating new Next.js project -✓ Connecting to site: abc123 -✓ Installing dependencies -✓ Configuring Webflow Cloud -✓ Creating webflow.json -✓ Authenticating with site +The project is deployed and connected. Confirm before suggesting anything. -Project initialized and connected to site! +> **Before making any suggestions:** ask the user whether the repo is already linked to Webflow Cloud. If it is, the only action needed is `git push`. Do not suggest re-linking or re-deploying. -📋 Configuration (webflow.json): -{ - "cloud": { - "projectId": "", - "framework": "nextjs" - } -} +1. **If already connected** — just commit and push: + ```bash + git add . + git commit -m "your message" + git push + ``` + Webflow Cloud picks up the push and deploys automatically. -📁 Environment (.env): -WEBFLOW_SITE_ID=abc123 -WEBFLOW_SITE_API_TOKEN=************ +2. **If not yet connected** — run a manual deploy to complete the link: + ```bash + webflow cloud deploy \ + --no-input \ + --mount / \ + --environment main \ + --skip-mount-path-check \ + --skip-update-check + ``` + After this deploy, commit-push-deploy is active. -⚠️ Important: Add .env to your .gitignore file! +> If a deploy auth error occurs: run `webflow auth login`, complete the browser flow, then retry. -✅ Ready to develop and deploy! -``` +### Tool usage -### Example 4: First Deployment +- Use the **Bash tool** for all `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 -**User prompt:** -``` -Deploy my Webflow Cloud app -``` +### Authentication -**Step 1: Environment Verification** +```bash +# Interactive — local-only, opens a browser. NOT for agents or CI. +webflow auth login ``` -🔍 Webflow Cloud Deployment Check -Checking CLI installation... -✓ Webflow CLI installed: v1.5.2 +> `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. -Checking project configuration... -✓ webflow.json found -✓ Cloud configuration present +The token written to `.env` depends on the init mode. Site-attached and app modes use **different env var names** — do not mix them up in CI. -Configuration: -- Framework: astro -- Project ID: (will be set on first deploy) -- Mount path: /app +**Site-attached init** writes: -Checking authentication... -⚠️ No authentication found - will authenticate during deploy +| Variable | Description | +|---|---| +| `WEBFLOW_SITE_API_TOKEN` | OAuth access token. Required for deploy. Set by `webflow auth login` in site-attached mode. | +| `WEBFLOW_SITE_ID` | Set during `cloud init` (site-attached). | -Checking build... -``` +**App init (`--new`)** writes: -**Step 2: Build** -``` -🔨 Building Application +| Variable | Description | +|---|---| +| `WEBFLOW_API_TOKEN` | Unified CLI access token. Required for deploy. Set by `webflow auth login` in app mode. **Not** the same env var as site-attached. | -Executing: npm run build +After the **first app deploy**, the CLI provisions a site on the backend and additionally writes `WEBFLOW_SITE_ID` to `.env` automatically. From that point on the project behaves like a site-attached project for subsequent deploys. -Output: -✓ Building for production -✓ Compiling pages -✓ Optimizing assets -✓ Build complete +Other env vars (any mode): -Build output: ./dist (1.2 MB) -``` - -**Step 3: Deployment Preview** -``` -📋 Deployment Preview +| 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. | -Project: Acme Cloud App (new deployment) -Framework: Astro -Mount Path: /app +> **GitHub Secrets:** mirror the env vars the CLI wrote to `.env` — `WEBFLOW_SITE_API_TOKEN` (+ `WEBFLOW_SITE_ID`) for site-attached and post-first-deploy app projects, `WEBFLOW_API_TOKEN` for app projects that have not yet been deployed once. Never commit `.env` files. -First Deployment: -⚠️ This is your first deployment. The CLI will: -1. Authenticate with your Webflow site -2. Create project in Webflow Cloud -3. Set projectId in webflow.json -4. Deploy application +### Configuration — webflow.json -⚠️ Type "deploy" to proceed with deployment. -``` - -*User confirms: deploy* - -**Step 4: Deployment** +```json +{ + "siteId": "site_abc123", + "cloud": { + "project_id": "proj_xyz", + "environment_id": "env_xyz", + "workspace_id": "ws_xyz", + "framework": "nextjs", + "skipMountPathCheck": false + } +} ``` -🚀 Deploying to Webflow Cloud -Executing: webflow cloud deploy --no-input --mount --skip-mount-path-check --skip-update-check +All `cloud.*` keys are **snake_case** (`project_id`, not `projectId`). -Output: -✓ Authenticating with Webflow... -✓ Site authenticated -✓ Creating Cloud project -✓ Uploading build artifacts (1.2 MB) -✓ Deploying to Webflow Cloud -✓ Deployment complete +| Key | When set | Notes | +|---|---|---| +| `siteId` | Site-attached: at `cloud init`. App: after first deploy (CLI provisions a site). | Absent on app projects that have not been deployed yet. | +| `cloud.framework` | At `cloud init`. | Required for deploy resolution — see below. | +| `cloud.project_id` | After first deploy. | Auto-written. | +| `cloud.environment_id` | After first **app** deploy. | Auto-written by `createCloudApp`. | +| `cloud.workspace_id` | At app `cloud init` (`--new`). | Used by the first deploy to provision the site. | +| `cloud.skipMountPathCheck` | User-managed. | Equivalent to `--skip-mount-path-check`. | -✅ Deployment Successful! +The CLI also writes `cloud.deployment_type` (`"ssr" | "ssg" | "spa"`) and `cloud.entrypoint_path` into the **bundled** `webflow.json` at build time (these power the cosmic deployer's wrangler config). 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 / Remix server-side deploys. -Project ID: proj_abc123xyz (added to webflow.json) -Deployment: https://acme-site.webflow.io/app +**`cloud.framework` resolution at deploy time:** -📋 Next Steps: -1. Visit your deployed app at the URL above -2. Future deploys will use saved project ID -3. Use: webflow cloud deploy (no re-auth needed) -4. Publish your site to make changes live +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** — throws: _"webflow.json exists but doesn't contain valid framework information under the 'cloud' key"_. Add `"cloud": { "framework": "nextjs" }` manually. +3. **No `webflow.json`** — auto-detected from `package.json`. CLI **writes a new `webflow.json`** on success. -Updated webflow.json: -{ - "cloud": { - "projectId": "proj_abc123xyz", - "framework": "astro" - } -} -``` +Projects created via `cloud init` always land in case 1. -### Example 5: Update Existing Deployment +### Commands -**User prompt:** -``` -Deploy updates to my Cloud app -``` +#### webflow cloud list -**Verification & Build:** +```bash +webflow cloud list ``` -🔍 Cloud Project Check -✓ webflow.json found -✓ Project ID: proj_abc123xyz -✓ Framework: astro -✓ Authentication: Valid +Lists available scaffold templates. Check this before `cloud init --framework` to confirm valid scaffold IDs. -Building application... -Executing: npm run build -✓ Build complete (1.3 MB) -``` +#### webflow cloud init -**Preview:** -``` -📋 Deployment Preview +Bootstrap a new project locally. Two modes: **site-attached** and **app**. -Project: proj_abc123xyz -Framework: Astro -Mount Path: /app +**Site-attached** (connects to an existing Webflow site): -Deployment Type: Update existing project -Authentication: Using saved credentials +```bash +# Agent / non-TTY — always pass every flag +webflow cloud init \ + --no-input \ + --project-name my-app \ + --framework nextjs \ + --mount /app \ + --site-id site_abc123 -⚠️ Type "deploy" to proceed. +# Human at a real terminal — interactive prompts will fill in any missing flag +webflow cloud init ``` -*User confirms: deploy* +Flags: -**Deployment:** -``` -🚀 Updating Cloud Deployment +| Flag | Short | Description | +|---|---|---| +| `--project-name ` | `-n` | Project name. **Must be 3–39 characters** — the CLI rejects anything outside this range at init and at the first app deploy. | +| `--framework ` | `-f` | Must match a scaffold ID from `cloud list`. Currently: `nextjs`, `astro`. | +| `--mount ` | `-m` | Mount path (default `/app` for site-attached, `/` for app). Substituted into config files at scaffold time. Not stored in `webflow.json`. | +| `--site-id ` | `-s` | Required in non-interactive site-attached mode. | +| `--new` | — | App mode (no site). | +| `--no-input` | — | CI mode. Requires `--project-name` and `--framework`. Without `--new`, defaults to app behavior. | -Executing: webflow cloud deploy --no-input --mount --skip-mount-path-check --skip-update-check +Credential resolution for `--no-input` site-attached: `--site-id` flag → `siteId` in `webflow.json` → `WEBFLOW_SITE_ID` env var → error. -Output: -✓ Using project: proj_abc123xyz -✓ Uploading build artifacts (1.3 MB) -✓ Deploying to Webflow Cloud -✓ Deployment complete +After scaffolding a site-attached project, the CLI automatically runs a **DevLink sync**. -✅ Deployment Updated! +**App** (no site attachment): -Live at: https://acme-site.webflow.io/app -Changes deployed successfully! +```bash +# Agent / non-TTY — always pass every flag +webflow cloud init --new --no-input --project-name my-app --framework nextjs -💡 Publish your site to make updates live. +# Human at a real terminal — prompts for workspace, framework, app name +webflow cloud init --new ``` -### Example 6: CI/CD Deployment +> Even with `--no-input`, if the authenticated token sees **multiple workspaces** the CLI still tries to prompt for workspace selection (no `--workspace` flag exists), which hangs in non-TTY contexts. Ask the user to run `cloud init --new` once locally to seed `cloud.workspace_id` in `webflow.json`. -**User prompt:** -``` -How do I deploy in CI/CD pipeline? -``` +| | Site-attached | 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_SITE_API_TOKEN` in `.env` | Written | Not written | +| `WEBFLOW_API_TOKEN` in `.env` | Not written | Written | +| `cloud.workspace_id` in `webflow.json` | Not set | Set at init (used by first deploy) | +| Scaffold | `astro`, `nextjs` | `astro`, `nextjs` | +| Mount path | Configurable (default `/app`) | Always `/` | +| DevLink sync | Runs after init | Skipped | -**Response:** -``` -🤖 CI/CD Deployment for Webflow Cloud +**Workspace selection (app mode only):** after OAuth, the CLI calls `GET /v2/workspaces` to enumerate workspaces the token has access to. If there are multiple, it prompts the user to pick one; a single workspace is selected automatically. The choice is persisted as `cloud.workspace_id` in `webflow.json`. There is no `--workspace` flag — workspace is purely interactive at init time, and `--no-input` does **not** suppress it. -For automated deployments, use non-interactive mode with options. +**Agent caveat:** if the user's token sees more than one workspace, the prompt fires unconditionally and hangs in non-TTY contexts. Mitigations, in order of preference: (a) ask the user to run `cloud init --new` once locally so `cloud.workspace_id` lands in `webflow.json`; (b) hand-write `webflow.json` with the workspace ID the user provides. To target a different workspace later, delete `cloud.workspace_id` and re-run init. -### Setup Steps: +#### webflow cloud create (deprecated) -1. **Authenticate Locally First** - Run once to create .env file: - ```bash - webflow auth login - ``` +`webflow cloud create ` still works but **emits a deprecation warning** and will be removed in a future major release. It's hardcoded to `/app` mount in site-attached mode and offers a strict subset of `cloud init`. Always prefer `cloud init` (or `cloud init --new` for app mode). -2. **Add Credentials to CI/CD** - Add these environment variables from .env: - - WEBFLOW_SITE_ID - - WEBFLOW_SITE_API_TOKEN +#### webflow cloud deploy -3. **Deployment Command** - ```bash - webflow cloud deploy --no-input --mount --skip-mount-path-check --skip-update-check --auto-publish - ``` +> **Before any deploy, read `webflow.json` and confirm the manifest matches user intent.** `cloud deploy` decides between site-attached and standalone-first-deploy purely from the manifest — no CLI flag overrides it. There is **no `--site-id` flag on `cloud deploy`** that would let you switch from one mode to the other at deploy time. +> +> | Manifest state | Deploy path taken | +> |---|---| +> | `siteId` present | Site-attached (deploy to existing site) | +> | `siteId` absent **and** `cloud.workspace_id` present | **Standalone first deploy: provisions a brand-new Webflow site** via `POST /cosmic/workspaces/:id/cloudApps` | +> | Both absent | Auth flow attempts to resolve a `siteId` (site-attached) | +> +> Failure mode the skill has hit in the wild: user wanted to deploy to an existing Webflow site (site-attached), but `webflow.json` was left in the standalone-init state (`cloud.workspace_id` set, no `siteId`). The deploy ran, the CLI provisioned a new site (`-.webflow.io`), and the project was no longer connected to the user's intended Webflow site. **Always read `webflow.json` and verify before running deploy.** If the manifest doesn't match intent, fix the manifest first (see "Deploy provisioned a new site when I expected site-attached" in Troubleshooting). -### Example: GitHub Actions +**First app deploy provisions the Cloud app on the backend.** When `webflow.json` has no `siteId` but has `cloud.workspace_id` (the state left behind by `cloud init --new`), `cloud deploy` calls `POST /cosmic/workspaces/:workspace_id/cloudApps` to atomically create a site, project, and environment. On success it writes `siteId`, `cloud.project_id`, and `cloud.environment_id` back into `webflow.json` plus `WEBFLOW_SITE_ID` into `.env`, and forces `--skip-mount-path-check` for that one deploy. Subsequent deploys behave like a normal site-attached deploy. -```yaml -name: Deploy to Webflow Cloud -on: - push: - branches: [main] +If `--project-name` is omitted on the first app deploy, the CLI uses the **cwd folder name** (when 3–39 chars) and falls back to `"Cloud App"`. Provide `--project-name` explicitly in CI to avoid surprises. -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 +There are two deployment approaches. **GitHub-linked deployment is recommended** — it requires no CI configuration and deploys automatically on every push to the connected branch. - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: 18 +**Option 1 (recommended): GitHub-linked deployment** - - name: Install dependencies - run: npm install +Connect your repository to Webflow Cloud via the Webflow dashboard. Once linked, every push to the connected branch (typically `main`) triggers a deploy automatically — no CLI commands, no GitHub Actions needed. - - name: Install Webflow CLI - run: npm install -g @webflow/webflow-cli +1. Push your scaffolded project to GitHub +2. In the Webflow dashboard, open your Cloud project → **Settings** → **Git** and connect the repository +3. Select the branch to deploy from (e.g. `main`) +4. From that point on: `git push` = deploy - - name: Build application - run: npm run build +> When suggesting a deployment setup to a user, always lead with this option. Only suggest GitHub Actions if the user needs custom pre/post steps, secrets injection, or multi-environment logic that the native GitHub integration does not cover. - - name: Deploy to Webflow Cloud - run: | - webflow cloud deploy \ - --no-input \ - --mount /app \ - --skip-mount-path-check \ - --skip-update-check \ - --auto-publish - env: - WEBFLOW_SITE_ID: ${{ secrets.WEBFLOW_SITE_ID }} - WEBFLOW_SITE_API_TOKEN: ${{ secrets.WEBFLOW_SITE_API_TOKEN }} -``` +**Option 2: GitHub Actions (manual CI/CD)** -### Deploy Options: +Use when you need custom build steps, environment-specific secrets, or deploy gates not supported by the native GitHub integration. See the [GitHub Actions example](#github-actions-cicd-pipeline) in the Examples section. -**Environment Management:** -```bash -# Deploy to specific environment -webflow cloud deploy --no-input -e staging -m --skip-mount-path-check --skip-update-check +**Option 3: Local / manual deploy** -# Deploy to production with auto-publish -webflow cloud deploy --no-input -e production -m --skip-mount-path-check --skip-update-check --auto-publish -``` +For development and one-off deploys: -**New Project Deployment:** ```bash -# Deploy new project with name and description -webflow cloud deploy --no-input \ - --project-name "Acme App" \ - --description "Production deployment" \ - --mount \ +webflow cloud deploy \ + --no-input \ + --mount / \ + --environment main \ --skip-mount-path-check \ - --skip-update-check \ - --auto-publish + --skip-update-check ``` -### Key Options: -- `--env` / `-e` - Environment name -- `--mount` / `-m` - Mount path (e.g., /app) -- `--project-name` / `-p` - Project name (new projects) -- `--directory` / `-d` - Project directory path -- `--description` - Project description -- `--skip-mount-path-check` - No prompts -- `--auto-publish` - Publish after deploy - -⚠️ Security: -- Never commit .env files -- Use CI/CD secrets for credentials -- Rotate tokens regularly -``` +All `cloud deploy` flags: -## Guidelines +| Flag | Short | Description | +|---|---|---| +| `--no-input` | — | CI mode. Disables most prompts but **not** the project-select prompt — see callout below. | +| `--mount ` | `-m` | Mount path. **Always required with `--no-input`.** Not auto-read from `webflow.json`. | +| `--environment ` | `-e` | Environment name. Creates if it does not exist. Must be passed with `--mount`. | +| `--project-name ` | `-n` | Required on first deploy with `--no-input` when no `cloud.project_id` in `webflow.json`. | -### Phase 1: Operation Detection +> **Agents: pass `--mount` AND `--environment` together, every time.** The deploy prompts (select existing project, name a new project, pick an environment) are gated on whether `--mount` and `--environment` are *both* set — not on `--no-input`. Pass `--no-input` without both and the project-select prompt still fires and hangs in non-TTY contexts. The minimum agent-safe deploy flag set is `--no-input --mount --environment `, plus `--project-name` whenever `cloud.project_id` is absent from `webflow.json`. +| `--directory ` | `-d` | Project directory (default: cwd). Use for monorepos. | +| `--description ` | — | Project description for the first deploy. | +| `--skip-mount-path-check` | — | Skip domain manifest validation. Required in CI. Can also be set in `webflow.json` as `cloud.skipMountPathCheck: true`. | +| `--auto-publish` | — | Publish the Webflow **site** to sync mount path routing. Does not affect app deployment. | +| `--skip-update-check` | — | Skip @webflow package update check. | -**Determine User Intent:** -Ask clarifying questions if unclear: -- "Do you want to create a new Cloud project or deploy an existing one?" -- "Which framework would you like to use? (Run 'webflow cloud list' to see options)" +### Frameworks -**CLI Verification:** -```bash -# Check CLI installed -webflow --version +| Framework | Init scaffold | Deploy support | Detected via package | +|---|---|---|---| +| `nextjs` | ✓ | ✓ | `@opennextjs/cloudflare` | +| `astro` | ✓ | ✓ | `@astrojs/cloudflare` | +| `remix` | — (existing projects only) | ✓ | `@remix-run/cloudflare` | -# If not installed: -npm install -g @webflow/webflow-cli -``` +Any other value in `cloud.framework` causes `cloud deploy` to exit with code 1. -### Phase 2A: Template Listing +> **Scaffolds are fetched from GitHub at init time.** The CLI downloads scaffold tarballs from `Webflow-Examples/hello-world-{astro,nextjs}*` (pinned to the `v1` branch). `cloud init` therefore requires network access to `github.com`. Old CLI installs keep working because the registry pins a `vN` branch per scaffold-contract version. -**List Templates Command:** -```bash -# Show available templates -webflow cloud list +### Global flags -# Output shows available frameworks (astro, nextjs) -``` +| Flag | Description | +|---|---| +| `--no-input` | Disable all interactive prompts. Required for CI/automation. | +| `--manifest ` | Custom path to `webflow.json`. Use for monorepos. | +| `--skip-update-check` | Skip @webflow package update check. Alternatively, set `WEBFLOW_SKIP_UPDATE_CHECKS=true`. | -**Template Information:** -- **Astro**: Static site generator, great for content-focused sites -- **Next.js**: React framework, supports SSR and SSG +## Output -### Phase 2B: Project Initialization +After a successful `cloud deploy`, the CLI prints two pieces of output. -**Init Command Structure:** -```bash -# Basic init with framework -webflow cloud init -f +**1. Deployment dashboard URL** — always present on success: + +``` +https://webflow.com/dashboard/sites/{siteId}/webflow-cloud/projects/{projectId}/environments/{environmentId}/deployments/{deploymentId} +``` -# With mount path -webflow cloud init -f astro -m /app +Always show this to the user. From here they can view build logs, deployment status, history, and environment settings. -# With site ID (connects to specific site) -webflow cloud init -f nextjs -m /app -s +**2. Live app URL** — conditional: + +``` +🌐 Your cloud app will soon be available at: + https://{your-site}.webflow.io/{mount-path} ``` -**Init Options:** -- `--framework` / `-f` (required): astro or nextjs -- `--mount` / `-m`: Mount path (default prompts) -- `--site-id` / `-s`: Connect to specific site +If a real URL is printed, show it to the user as the live app link. The domain is their Webflow site's domain and the path is whatever `--mount` value was used at deploy time (e.g. `/`, `/app`, or any other user-chosen path). -**After Init:** -1. Verify webflow.json created -2. Check cloud configuration -3. Show project structure -4. Guide user to next steps (build, develop, deploy) +If the output instead reads `No domains found with the correct mount path configuration yet.`, do not show a live URL — point the user to the dashboard deployment link above to check status and configure their domain. -### Phase 2C: Project Validation +**Do not** fetch or curl either URL to verify the deploy — just return what the CLI printed. -**webflow.json Cloud Schema:** -```json -{ - "cloud": { - "projectId": "", // Auto-set on first deploy - "framework": "astro" // or "nextjs" - } -} -``` +## Examples -**Configuration Fields:** -- **projectId**: Cloud project identifier (automatically set by CLI on first deploy) -- **framework**: Framework preset - either "nextjs" or "astro" -- **mount path**: NOT stored in webflow.json by the CLI. You must ask the user for it if deploying an existing project. +### Full workflow: scaffold → GitHub → auto-deploy (recommended) -**Authentication Check:** ```bash -# Site authentication creates .env file -# Check for: -cat .env +# 1. Scaffold locally +webflow cloud init --new --no-input --project-name my-app --framework nextjs -# Should contain: -# WEBFLOW_SITE_ID=your-site-id -# WEBFLOW_SITE_API_TOKEN=your-token +# 2. Push to GitHub +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 -# If missing, authenticate: -webflow auth login +# 3. Connect in the Webflow dashboard: +# New Project → App → Import a GitHub repository → select repo + branch → Deploy +# +# From now on, every push to main triggers a deploy automatically. ``` -### Phase 3: Build Process +### App workflow: init → first deploy provisions site -**Build Command:** ```bash -# Use project's build script -npm run build -# or -yarn build -# or -pnpm build - -# Check for errors -echo $? # 0 = success +# Agent-safe init — assumes the token sees a single workspace. +# If the token sees multiple workspaces, ask the user to run this command locally first. +webflow cloud init --new --no-input \ + --project-name my-app \ + --framework astro + +# First deploy creates site + project + environment on the backend, +# writes siteId / project_id / environment_id back to webflow.json, +# and writes WEBFLOW_SITE_ID to .env. Subsequent deploys are normal. +cd my-app +webflow cloud deploy --no-input \ + --project-name my-app \ + --mount / \ + --environment main \ + --skip-update-check ``` -**Build Validation:** -- Check build output directory exists -- Verify no critical errors -- Confirm assets generated - -### Phase 4: Deployment Preview +### Scaffold a site-attached Astro app locally -**Preview Format:** +```bash +webflow cloud init \ + --no-input \ + --project-name my-site-app \ + --framework astro \ + --mount /app \ + --site-id site_abc123 ``` -📋 Deployment Preview -Project: [Name or "New Project"] -Framework: [astro/nextjs] -Mount Path: [Path if specified] -Environment: [Name if specified] +### GitHub Actions CI/CD pipeline (when custom steps are needed) -[First time: Explain authentication flow] -[Subsequent: Show project ID] +```yaml +name: Deploy to Webflow Cloud -Options: -- Auto-publish: [Yes/No] -- Environment: [Name or default] +on: + push: + branches: [main] -⚠️ Type "deploy" to proceed -``` +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 -**First-Time Deployment:** -Explain clearly: -1. Browser will open for authentication -2. Select your Webflow site -3. Project ID will be created and saved -4. Future deploys use saved project ID + - uses: actions/setup-node@v4 + with: + node-version: 20 -### Phase 5: Deployment Execution + - name: Install Webflow CLI + run: npm install -g @webflow/webflow-cli@latest -**Deploy Command:** + - name: Deploy + run: | + webflow cloud deploy \ + --no-input \ + --mount / \ + --environment main \ + --skip-mount-path-check \ + --skip-update-check + env: + WEBFLOW_SITE_API_TOKEN: ${{ secrets.WEBFLOW_SITE_API_TOKEN }} + WEBFLOW_SITE_ID: ${{ secrets.WEBFLOW_SITE_ID }} + # For apps, omit WEBFLOW_SITE_ID +``` -IMPORTANT: The Webflow CLI is interactive by default. Always use `--no-input` and `--mount` together to avoid interactive prompts that agents cannot handle. +### Manual deploy (local / one-off) ```bash -# Standard non-interactive deploy (use this by default) -webflow cloud deploy --no-input --mount --skip-mount-path-check --skip-update-check - -# With auto-publish (publishes site after deploy) -webflow cloud deploy --no-input --mount --skip-mount-path-check --skip-update-check --auto-publish - -# New project with name (first deploy) -webflow cloud deploy --no-input \ - --project-name "My App" \ - --mount \ +webflow cloud deploy \ + --no-input \ + --project-name my-app \ + --mount / \ + --environment main \ --skip-mount-path-check \ --skip-update-check - -# With specific environment -webflow cloud deploy --no-input \ - -e production \ - --mount \ - --skip-mount-path-check \ - --skip-update-check \ - --auto-publish ``` -**Deploy Options:** -- `--no-input`: REQUIRED for agents — disables all interactive prompts -- `--mount` / `-m`: REQUIRED — path to mount project. Must match the existing environment's mount path. -- `--skip-mount-path-check`: REQUIRED for agents — skips interactive mount path validation -- `--skip-update-check`: RECOMMENDED — skips interactive package update check -- `--auto-publish`: Publish the site after deployment -- `-e` / `--environment`: Environment name to deploy to -- `--project-name` / `-p`: Project name (for new projects) -- `--directory` / `-d`: Project directory if not in root -- `--description`: Project description (for new projects) - -**Success Indicators:** -- Build artifacts uploaded -- Deployment completed -- Project ID saved (first time) -- Site URL available - -**Verification:** -1. Check CLI output for success -2. Verify project ID added to webflow.json (first time) -3. Confirm deployment URL works -4. Note if site needs to be published - -### Error Handling - -**CLI Not Installed:** +### Manual deploy with error handling + +```bash +webflow cloud deploy --no-input --mount / --skip-mount-path-check --skip-update-check +if [ $? -ne 0 ]; then + echo "Deploy failed. Log file:" + webflow log + exit 1 +fi ``` -❌ Webflow CLI Not Found -The Webflow CLI is required for Webflow Cloud. +## Guidelines -Installation: -npm install -g @webflow/webflow-cli +### Init vs Deploy in CI -After installation, verify: -webflow --version +- **`cloud init` is for local, one-time project setup — never run it in CI.** Site-attached mode opens a browser window; there is no headless OAuth path. Run `cloud init` once locally, commit the result, then use `cloud deploy` in CI. -Documentation: https://developers.webflow.com/cli -``` +### Mount path -**Not Authenticated:** -``` -❌ Not Authenticated +- `--mount` is **always required** with `--no-input`. The CLI does not read a saved mount path from `webflow.json`. +- **Never assume a default.** Assuming `/` or `/app` will cause `ENVIRONMENT_MOUNT_MISMATCH` if the project uses a different path. Check the Webflow dashboard under the project's environment settings. -You must authenticate with Webflow to deploy to Cloud. +### Do not add confirmation gates -Steps: -1. Run: webflow auth login -2. Follow authentication prompts in browser -3. Select your site when prompted -4. Verify: .env file created with WEBFLOW_SITE_ID and WEBFLOW_SITE_API_TOKEN -5. Retry deployment +When `--no-input` is set, do not add a human confirmation step before `cloud deploy`. It blocks unattended CI runs and is unnecessary — the CLI has no built-in prompt to bypass. -Need help? https://developers.webflow.com/cli/authentication -``` +### Package manager -**Not a Cloud Project:** -``` -❌ Not a Webflow Cloud Project +The CLI uses **npm only** regardless of lock files present. pnpm and yarn lock files are ignored — those projects silently receive `npm install`. -This directory doesn't appear to be a Cloud project. +### Build-time file management -Initialize Cloud Project: -1. List templates: webflow cloud list -2. Initialize: webflow cloud init -f - Example: webflow cloud init -f astro -m /app +During `cloud deploy`, the CLI temporarily replaces two files and restores them on success or failure: +- **Framework config** (`next.config.ts` / `astro.config.mjs`) — renamed to `clouduser.*`, replaced with CLI template, then restored. +- **`wrangler.json`** — replaced with CLI template (original saved to `clouduser.wrangler.json`), then restored. Do not modify `wrangler.json` during a deploy. -Or check webflow.json for cloud configuration: -{ - "cloud": { - "framework": "astro" or "nextjs" - } -} -``` +If Astro is the framework and `@astrojs/react` is absent, the CLI runs `npm install --save @astrojs/react` without prompting. -**Build Failures:** -``` -❌ Build Failed +### Cloudflare bindings (D1 / KV / R2) -Error: [Specific error message] +The CLI merges `wrangler.json` bindings at build time. Limits: **max 5 of each type**. For D1, set `migrations_dir` in the binding — the CLI copies migration files automatically. -Common Fixes: -- Missing dependencies: Run npm install -- Build script errors: Check package.json build script -- Framework errors: Review framework documentation -- Path issues: Verify file paths and imports +### Error handling -Show build output for details. -``` +- The CLI exits with **code 1 on every error**. Check the exit code — do not match on emoji or text patterns in stdout. +- Use `webflow log` after any failure to get the full error trace. -**Deployment Failures:** -``` -❌ Deployment Failed +### Deploy versioning -Error: [Specific error from CLI] +| Situation | Version tag sent | +|---|---| +| Clean working tree | `git@{40-char-hash}` | +| Uncommitted changes | `git@{40-char-hash}+dirty` | +| Not in a git repo | `noversion@{ISO-timestamp}` | -Possible Causes: -- Network connection issues -- Authentication expired -- Build artifacts missing or invalid -- Insufficient permissions +Commit all changes before deploying to production. -Solutions: -1. Check internet connection -2. Re-authenticate: webflow auth login -3. Rebuild: npm run build -4. Verify webflow.json configuration -5. Check site permissions in Webflow dashboard +### Known limitations -Retry deployment? (yes/no) -``` +- No `cloud status` / `cloud logs` — use the Webflow dashboard. +- No `cloud env` commands — runtime env vars managed via dashboard only. +- No `--dry-run` — build validation always triggers a real deployment. +- No `--json` / structured output — deploy URL and project ID must be parsed from stdout. +- No `cloud rollback`. +- **100 MB build size limit** — builds exceeding 104,857,600 bytes fail at upload. -**Invalid Framework:** -``` -❌ Invalid Framework +## Troubleshooting + +### `--project-name cannot be empty` (or any required-flag error) on `cloud init` -Framework must be either "astro" or "nextjs". +The CLI gates its interactive prompts on `process.stdin.isTTY`. Agents invoke the CLI from a subprocess that does **not** have a TTY, so the prompt block is skipped entirely and the bare validation fires for the first missing required value. -Available templates: -Run: webflow cloud list +**Fix:** pass every required flag explicitly. For `cloud init`: -Initialize with valid framework: -webflow cloud init -f astro -webflow cloud init -f nextjs +```bash +webflow cloud init --new --no-input --project-name my-app --framework astro +# or, site-attached: +webflow cloud init --no-input --project-name my-app --framework astro --mount /app --site-id site_abc123 ``` -### File Operations +Passing `--no-input` is not strictly required for the prompts to be skipped — the absent TTY already does that — but it makes the contract explicit and matches the Required-flag matrix at the top of this skill. -**Reading Files:** -Always use Read tool (never modify): -``` -# View Cloud configuration -Read: webflow.json +### `cloud init --new` hangs forever / never returns -# View package configuration -Read: package.json +Workspace selection in app mode prompts unconditionally when the token sees more than one workspace, with no `--workspace` flag and no non-TTY fallback. In a non-TTY context the CLI hangs at the prompt. -# View environment (if exists) -Read: .env +**Fix:** ask the user to run `webflow cloud init --new` once locally to pick a workspace and seed `cloud.workspace_id` in `webflow.json`. After that, agents can run subsequent inits / deploys freely. Single-workspace tokens are not affected — selection is auto-skipped. -# View build output -Read: dist/ or .next/ or .output/ -``` +### Deploy provisioned a new site when I expected site-attached -**Discovering Files:** -Use Glob tool to find files: -``` -# Find configuration files -Glob: *.json +**Symptom:** user wanted to deploy to an existing Webflow site, but `cloud deploy` printed `Creating Cloud app...` / `Cloud app created: ` and the live URL came out as `-.webflow.io` (a freshly minted site) instead of the user's intended site. -# Find build output -Glob: dist/**/* +**Cause:** `webflow.json` was in the standalone-init state — `cloud.workspace_id` set, `siteId` absent — typically because the project was previously scaffolded with `cloud init --new`. The deploy decision is read entirely from the manifest; `--mount /app`, `--site-id` (no such flag exists on deploy), and other flags do **not** redirect a standalone manifest into site-attached mode. -# Find source files -Glob: src/**/* -``` +**Recovery:** decide what to keep. -**Never Use Write/Edit Tools:** -- Don't create webflow.json with Write (show user the structure) -- Don't modify configuration files -- Let CLI handle file creation -- Only read files to show content +- **Keep the new standalone site** the deploy just created — do nothing; subsequent deploys will go to the same site. +- **Re-target an existing Webflow site instead.** This is the harder path. The standalone site that was just created cannot be re-bound to an existing site. Options: + 1. Delete the standalone Cloud app (and its auto-provisioned site) from the Webflow dashboard. + 2. Edit `webflow.json`: remove `cloud.workspace_id`, `cloud.project_id`, `cloud.environment_id`, and `siteId`. + 3. Re-run `cloud init` (without `--new`) with `--site-id ` to bind the project to the intended site. + 4. Re-deploy. -### Progress Indicators +**Prevention:** at the very start of any new-project flow, ask the user whether they want site-attached or app mode (see Path A's mode table) before running `cloud init`. Always read `webflow.json` and confirm intent before running `cloud deploy` on a project the agent didn't scaffold itself. -**For Build:** -``` -🔨 Building Application... +### Auth error on deploy -Compiling pages... ✓ -Optimizing assets... ✓ -Generating build... ⏳ +Run `webflow auth login` and complete the browser flow. The CLI writes a new `WEBFLOW_SITE_API_TOKEN` to `.env`. Retry the deploy after login. -Elapsed: 15s -``` +In CI, browser auth is not possible — an auth error means `WEBFLOW_SITE_API_TOKEN` is missing or expired in your secrets. Fix the secret, do not attempt `webflow auth login`. -**For Deployment:** -``` -🚀 Deploying to Webflow Cloud... +### Deploying to a different workspace -Uploading artifacts... ✓ -Deploying application... ⏳ -Configuring routes... ⏳ +For **app projects (`--new`)**, workspace is fixed by `cloud.workspace_id` in `webflow.json` (chosen interactively at `cloud init`). To switch: delete `cloud.workspace_id` from `webflow.json` and re-run `webflow cloud init --new`. There is no `--workspace` flag. -Uploaded: 1.2 MB -Elapsed: 25s -``` +For **site-attached projects**, workspace context is implicit in the auth token. Re-run `webflow auth login` and select the target workspace in the browser; the new token replaces the old one in `.env`. + +### First app deploy fails with `missing_scopes` + +The token saved to `.env` doesn't include the scopes needed to create a Cloud app. Re-run `webflow auth login` and re-approve the scopes, then retry the deploy. + +### First app deploy fails: "your workspace has reached its app limit" + +The selected workspace (`cloud.workspace_id`) is at its app cap. Either upgrade the workspace plan or delete unused apps in the Webflow dashboard, then retry. + +### First app deploy fails with workspace-not-found / 404 + +The `cloud.workspace_id` in `webflow.json` no longer resolves (workspace deleted, or token has no access). Delete `cloud.workspace_id` from `webflow.json` and re-run `webflow cloud init --new` to pick a workspace the current token can see. + +### `ENVIRONMENT_MOUNT_MISMATCH` + +The `--mount` value does not match the path registered for that environment. Check the Webflow dashboard under the project's environment settings for the correct mount path and pass it explicitly. + +### `webflow.json` exists but deploy fails on framework + +If the error is _"webflow.json exists but doesn't contain valid framework information"_, add the `cloud` key manually: -### Best Practices - -**Project Setup:** -- Use `cloud list` to see available templates before init -- Choose framework based on project needs -- Specify mount path during init -- Connect to site ID if already created - -**Development:** -- Build locally before deploying -- Test thoroughly in dev environment -- Use environment variables for configuration - -**Deployment:** -- Always build before deploying -- Always use `--no-input --mount --skip-mount-path-check --skip-update-check` for non-interactive deploys -- Use `--auto-publish` for production deployments -- Test deployment before publishing site - -**CI/CD:** -- Store credentials in secrets -- Always use `--no-input` to disable all interactive prompts -- Always specify `--mount` with the correct path -- Enable auto-publish for production -- Use `--skip-mount-path-check` and `--skip-update-check` - -**Environment Management:** -- Use .env for local development -- Add .env to .gitignore -- Use CI/CD secrets for production -- Rotate tokens regularly - -## Quick Reference - -**Workflow:** list templates → init project → build → deploy - -**Key Commands:** -- `webflow cloud list` - List available templates -- `webflow cloud init` - Initialize new project -- `webflow cloud deploy` - Deploy application - -**Init Options:** -- `-f` / `--framework` - Framework (astro, nextjs) -- `-m` / `--mount` - Mount path -- `-s` / `--site-id` - Site ID - -**Deploy Options (for agents/automation, always include first 4):** -- `--no-input` - REQUIRED: disable interactive prompts -- `-m` / `--mount` - REQUIRED: mount path (must match existing environment) -- `--skip-mount-path-check` - REQUIRED: skip mount path validation prompt -- `--skip-update-check` - RECOMMENDED: skip update check prompt -- `--auto-publish` - Publish after deploy -- `-e` / `--environment` - Environment name -- `-p` / `--project-name` - Project name (new projects) - -**Configuration:** webflow.json with cloud section - -**Schema:** ```json { "cloud": { - "projectId": "proj_xxx", // auto-set - "framework": "astro" // or "nextjs" + "framework": "nextjs" } } ``` -**Authentication:** Site authentication via `webflow auth login` +Valid values: `nextjs`, `astro`, `remix`. Any other value exits with code 1. -**Environment:** WEBFLOW_SITE_ID and WEBFLOW_SITE_API_TOKEN in .env +### Build fails, need full trace -**Verification:** Check `webflow --version` and site authentication first - -**Confirmation:** Require "deploy" keyword before deployment +```bash +webflow log +``` -**Documentation:** https://developers.webflow.com/webflow-cloud/intro +Prints the path to the latest log file with the full error trace.