Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webflow",
"version": "1.0.6",
"version": "1.0.7",
"description": "Production-ready agent skills for Webflow - CMS management, site auditing, Designer tools, Code Components, CLI workflows, and safe publishing",
"author": {
"name": "Webflow",
Expand All @@ -20,6 +20,8 @@
"asset-optimization",
"designer",
"designer-tools",
"figma",
"figma-to-webflow",
"components",
"code-components",
"cli",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ All skills ship from the single `webflow-skills` plugin.
| webflow-mcp:custom-code-management | Manage tracking scripts and custom code safely |
| webflow-mcp:flowkit-naming | Apply Webflow's official FlowKit CSS naming conventions |
| webflow-mcp:designer-tools | Build and manage page structure, elements, components, and styles in Webflow Designer |
| webflow-mcp:figma-to-webflow | Build pages, sections, components, or full sites from Figma designs using Figma MCP and Webflow MCP |

### Webflow CLI Skills

Expand Down
2 changes: 1 addition & 1 deletion plugins/webflow-skills/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webflow-skills",
"description": "Production-ready skills for managing Webflow CMS content, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes",
"version": "1.0.6",
"version": "1.0.7",
"skills": "./skills/"
}
5 changes: 4 additions & 1 deletion plugins/webflow-skills/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webflow-skills",
"version": "1.0.6",
"version": "1.0.7",
"description": "Production-ready skills for managing Webflow CMS content, auditing site health, optimizing assets, building Designer pages and components, creating Code Components, running CLI workflows, and safely publishing changes.",
"author": {
"name": "Webflow",
Expand All @@ -24,6 +24,8 @@
"designer-tools",
"components",
"code-components",
"figma",
"figma-to-webflow",
"cli",
"devlink",
"webflow-cloud",
Expand All @@ -48,6 +50,7 @@
"Find and fix broken links on my site",
"Prepare a safe publish checklist",
"Inspect the current Designer page structure",
"Build this Figma design in Webflow",
"Create a new Webflow Code Component",
"Deploy a Webflow Cloud app"
],
Expand Down
138 changes: 138 additions & 0 deletions plugins/webflow-skills/skills/figma-to-webflow/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
name: webflow-mcp:figma-to-webflow
description: >-
Build a Webflow page, section, component, or full site from a Figma design
using the Figma MCP and the Webflow MCP (Designer Bridge + Data API). Use
whenever translating a Figma file/frame into Webflow, building directly in a
Webflow project, or implementing a design as live Webflow elements/styles
(not a copy-paste fragment). Triggers: "build this Figma in Webflow",
"Figma to Webflow", "implement this design in Webflow", a figma.com URL +
a Webflow site, "recreate this in my Webflow project".
---

# Figma → Webflow

Translate a Figma design into a live Webflow project: real elements, styles,
assets, fonts, and (optionally) custom code + interactions.

## Instructions

Follow this order exactly. When a step says to read a reference file, read it
before doing that work; those files contain the failure modes for that step.

## Non-Negotiable Gates

Treat these as build gates, not suggestions. If you cannot satisfy one, stop
and explain the tradeoff instead of silently substituting.

- **Bridge gate:** Designer Bridge is the default build mode. If selected, provide or request the Designer launch link and wait for the user to open the project with the Designer tab foregrounded before bridge-dependent steps. If the bridge disconnects, keep structural work headless and reconnect before snapshots/canvas inspection.
- **Native style gate:** apply styles with `data_style_tool`, never with the `data_whtml_builder` `css` param or raw `var()` strings. Otherwise styles land in Custom properties instead of native controls. Bind Webflow variables with `variable_as_value`.
- **Visible element gate:** build with real Designer-visible elements and native classes. Do not use embed `<style>` blocks, `::before` / `::after`, or other hidden constructs for normal layout/decorative elements.
- **Class existence gate:** create every class with `data_style_tool create_style` before using it in WHTML/element class lists. Webflow can silently drop class names that do not exist yet.
- **Variables gate:** decide the Webflow variable/design-system strategy before creating styles. Do not hard-code repeated colors/type/spacing/radii unless the user explicitly chooses hard-coded output.
- **Vector gate:** logos, icons, and marks must be inline SVG embeds, not PNG/JPG uploads, unless the user explicitly approves raster fallback.
- **Raster quality gate:** hero/product/mockup images must use a confirmed 2x source where crispness matters.
- **Dashed accent gate:** dashed lines, dividers, grids, accents, and underlines must use `repeating-linear-gradient`, not `border-style:dashed`, unless the user explicitly accepts browser-default dash rhythm.
- **Navbar gate:** custom navbar mobile behavior must be CSS-only, not JavaScript. Use the checkbox/sibling-selector pattern in `references/navbar.md`.
- **Verification gate:** never call a build done until you have verified rendered output. If visual verification is blocked, say what is unverified and ask the user to check it.
- **Capability gate:** do not assert that Webflow or MCP "can't" do something until you have tested the relevant tool path or clearly label it as untested.
- **Publish gate:** do not publish by default. Offer `.webflow.io` publish only after build/review, and only proceed on explicit user confirmation.

## Tool Surfaces

| Surface | Examples | Needs Designer open? |
|---|---|---|
| **Data API** (headless) | `data_whtml_builder`, `data_element_builder`, `data_element_tool`, `data_style_tool`, `data_fonts_tool`, `data_pages_tool`, `data_scripts_tool`, `data_assets_tool`, publish | No |
| **Designer Bridge** | `element_snapshot_tool`, `designer_tool` canvas/selection/navigation, `asset_tool upload_image_by_url` | **Yes — Designer tab open AND foregrounded** |

- Call `webflow_guide_tool` once before other Webflow tools. Confirm auth/site with `whoami` + `get_site`.
- Prefer bridge-assisted builds by default for better visual feedback, while still using `data_*` tools for DOM, classes/styles, text, semantic tags, responsive overrides, fonts, scripts, pages, and asset records.
- If Designer is disconnected, continue structural work headlessly with `query_styles`, `get_all_elements`, and `query_elements`; reconnect the bridge for snapshots, canvas inspection, and any still-required bridge-gated image processing fallback.
- If a bridge tool returns `status:false` or "Unable to connect to Webflow Designer," share the launch link and ask the user to open the Designer **and keep that browser tab in the foreground** — it idles/disconnects when backgrounded. Retry before assuming anything broke.

## Workflow

### 1. Gather And Decide

1. Use Figma MCP:
- `get_metadata` for structure.
- `get_design_context` for major frames/sections.
- `get_variable_defs` for colors, type, spacing, radii.
- Read page/canvas background; do not assume white.
2. Use Webflow MCP:
- `webflow_guide_tool` first.
- Confirm target site/page and inspect existing variables/styles.
3. Ask the required setup prompts below.
4. Confirm ambiguous design intent before building. If Figma component instances contain repeated placeholder labels, ask for intended copy instead of copying placeholders.

### Required Prompts

Before creating Webflow variables, classes, or CSS, ask these four questions:

- **Build mode:** Designer Bridge during build (default, better visual QA; requires Designer tab open/foregrounded) or headless first (faster, structural checks only until bridge needed).
- **Variables/design system:** read existing variables and create missing ones (default), create a new design system from scratch, use existing variables only, or hard-code with no Webflow variables.
- **Style naming:** FlowKit naming (default; reference `webflow-mcp:flowkit-naming`), existing Webflow design-system naming, or clear semantic kebab-case names.
- **Units:** `px` (default), `rem`, or `em`. Keep units consistent; only mix when there is a clear reason.

If the user does not choose, use the defaults above. For a blank site, recommend creating a new design system from scratch and explain why.

### 2. Build Foundations And Sections

Before creating variables/classes/styles, read [CSS rules](references/css-rules.md).

1. Create or map Webflow variables according to the selected strategy.
2. Create reusable primitives first: page wrapper, containers, typography, spacing, buttons, image-fill, cards, nav.
3. Create needed classes with `data_style_tool create_style` before referencing them in WHTML/element class lists.
4. Use `data_whtml_builder` for DOM/structure only: one root section per action, semantic tags, nesting, text, and existing class names.
5. Style with `data_style_tool update_style`. Repeat: do **not** use the WHTML `css` param or embed `<style>` blocks for normal styling.
6. Capture returned element ids. Re-find later with `query_elements`, then filter by exact class/type before acting.
7. Build in section-sized batches. Prefer structural verification with `query_elements` / `query_styles` between visual checks.

### 3. Attach Assets

Before handling images or vectors, read [Assets and SVG](references/assets-and-svg.md).

1. Use `data_assets_tool create_asset` for raster assets. Download source bytes locally, compute MD5, POST to presigned S3, then verify nonzero size/variants before placement.
2. For hero/product/mockup images, confirm 2x source before placement.
3. Bind images by asset ID with `set_image_asset`; never rely on raw `<img src="...">`.
4. Inline vector marks as `HtmlEmbed` SVGs and set embed code with `data_element_tool set_settings`.
5. Upload fonts with `data_fonts_tool`; never add Google Fonts `<link>` tags to head.

### 4. Navbar And Custom Behavior

If the build includes a navbar, read [Navbar](references/navbar.md) before building it.

- Ask which breakpoint should collapse to hamburger.
- Webflow native Navbar cannot be created via API/WHTML. Build a semantic custom nav or ask the user to add the native element in Designer.
- Put CSS-only component behavior in an HtmlEmbed inside the component root. Do not use JavaScript for the custom navbar.

### 5. Responsive And QA

Before responsive/final verification, read [Verification](references/verification.md).

1. Use `data_style_tool update_style` with breakpoint ids (`main`, `medium`, `small`, `tiny`). Desktop-first: set base, override downward.
2. If Designer Bridge is selected, snapshot groups/wrappers rather than every element. Keep the Designer tab foregrounded.
3. Verify overlays/layering with a full-page composite, not isolated-section snapshots.
4. Do not trust first snapshots for fonts; warm cache and re-snapshot before changing font implementation.
5. Test tool capabilities before asserting limitations. If you cannot test, say "untested" and describe the uncertainty.
6. Do not claim embed behavior, custom code, blur, WebGL, animation, or mobile widths are verified from your side. Ask the user to confirm in preview/published site.
7. Offer publish/review next steps. Default remains **no publish**.

## Checklist before declaring done

- [ ] Required reference files were read at their point of use.
- [ ] All CSS longhand; correct breakpoints; flexbox-first.
- [ ] Styles applied via `data_style_tool` (native controls), variables bound with `variable_as_value`, and only truly non-native CSS (`backdrop-filter`, `aspect-ratio`, `repeating-linear-gradient`, etc.) left as custom properties.
- [ ] All class names used in WHTML/element class lists exist as Webflow styles; none were silently dropped.
- [ ] No embed `<style>` blocks or `::before` / `::after` pseudo-elements used for normal layout/decorative elements.
- [ ] Build mode followed: bridge-assisted by default with Designer tab open and foregrounded, or headless-first if the user chose it.
- [ ] Webflow variables handled according to the selected strategy; repeated colors/type/spacing/radii are mapped or created unless hard-coding was explicitly selected.
- [ ] Images attached by asset ID (not orphan `<img src>`); 2× source confirmed where crispness matters.
- [ ] Vector marks are clean inline-SVG embeds (backgrounds stripped), or user explicitly approved raster fallback.
- [ ] Dashed accents/dividers/grids use `repeating-linear-gradient`, not `border-style:dashed`, unless user explicitly approved browser-default dashes.
- [ ] Fonts uploaded + referenced by exact family name; temp `<head>` link removed.
- [ ] Runtime-toggled classes have guaranteed CSS (not stripped).
- [ ] Responsive overrides at medium/small/tiny.
- [ ] Rendered output verified visually, or unverified items clearly reported to the user.
- [ ] No untested capability limitation was stated as fact.
- [ ] If published to subdomain, user asked to confirm anything you can't self-verify (embeds, WebGL, blur, mobile).
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Assets, SVG, And Fonts

Read this before exporting, uploading, or placing images, SVGs, logos, icons, or fonts.

## Figma Extraction

- Pull `get_metadata`, `get_design_context`, and `get_variable_defs` early.
- Asset URLs from design context live about 7 days; screenshot URLs are short-lived. Download promptly.
- Read the page/canvas background color from Figma. Do not assume white.
- For composed mockups or complex product visuals, export the parent node at 2x with `download_assets` and treat it as one image instead of rebuilding every layer.

## Raster Images

- Use the headless Data API asset path first. Do not build around `asset_tool upload_image_by_url`; it is Designer Bridge-gated and may be removed.
- Download image bytes locally from the Figma export/design-context URL.
- Compute MD5 of the actual bytes.
- Call `data_assets_tool create_asset` with `site_id`, `file_name`, and `file_hash`.
- POST bytes to the returned presigned S3 form: form fields first, file field last.
- Validate the presigned `policy` is pure base64 ASCII before POSTing:

```bash
printf '%s' "$POLICY" | grep -q '[^A-Za-z0-9+/=]' && echo "ABORT: non-ASCII in policy"
```

- Verify the created asset has nonzero size/variants before placing it. If it remains `size:0` or has no variants, report that Webflow accepted the upload but has not processed a renderable asset.
- Bind images by asset ID with `set_image_asset`, or create the Image with `data_element_builder` and `set_image_asset`.
- Never rely on raw WHTML `<img src="...">`; it is inserted without a managed Webflow asset.
- Apply an image-fill class to images inside placeholders: `width:100%; height:100%; object-fit:cover; display:block`.
- For crisp display, ship a 2x source and constrain it to display size with CSS. Do not depend on the Designer-only HiDPI checkbox.
- Delete orphaned `size:0` assets when safe.

## Inline SVG Embeds

- Logos, icons, and marks must be inline SVG inside `HtmlEmbed`, not uploaded SVG assets in `<img>`, unless the user explicitly approves fallback.
- Gradient/complex SVGs placed as `<img>` can render as a filled blob; inline embed avoids that.
- Prefer Figma right-click **Copy as SVG** for logos/marks/icons; it usually gives clean artwork with tight bounds. Use MCP `download_assets` / design-context SVG export only when clipboard output is unavailable, and expect scaffolding to strip.
- Create the `HtmlEmbed` first, then set code via `data_element_tool set_settings` with key `"code"` as `static_text`.
- Pass the SVG as the literal `static_text.value` of the `code` setting and let the tool layer encode it. Do not hand-build, pre-escape, or wrap the arguments in a raw/blob form. If you get "could not be parsed as JSON," the tool call is malformed; fix the call shape, do not shrink the SVG.
- There is no ~13 KB per-SVG `set_settings` ceiling; 20 KB can pass as a string value. The real practical limit is Webflow Designer's HTML Embed UI, about 10,000 characters. Data API embeds over ~10k can render, but they are not safely hand-editable in Designer and may be truncated if opened/re-saved. If the embed must remain Designer-editable, reduce it below ~10k.
- Optimize only as needed:
- Single-quote SVG attributes.
- Collapse whitespace between tags.
- Hoist shared fill to the root `<svg>` where possible.
- Keep vectorized wordmark text as paths; never substitute live text for logo text unless the user explicitly wants editable text.
- Never round coordinates to integers; it destroys curves on small artwork. One decimal is the floor, and only round if needed to fit the ~10k Designer-editable limit.
- Clean MCP/Figma SVG exports:
- Strip full-canvas backing `<rect>` elements by oversized dimensions, not just fill; some inherit the root fill and render as a giant dark box.
- Strip page-fill `<path>` elements, often `#F4F1FD` or `#F3F5F7`.
- Strip dashed component-boundary `<rect stroke="#9747FF" stroke-dasharray=...>`.
- Strip nested wrapper `<g id>` elements when not needed.
- Strip `<defs><clipPath>` scaffolding only when no kept artwork references it.
- Remove off-target paths and unused `id` attributes.
- Keep ids referenced by `url(#...)` gradients/clips.
- Leave `fill="white"` inside kept `<defs><clipPath>` alone; those are masks.
- Verify id integrity after cleanup: every `url(#id)` must resolve to a kept element. If embedding the same SVG more than once on a page, suffix gradient/clip ids uniquely per instance and update every `url(#...)` reference, because duplicate ids resolve to the first match.
- Export the artwork node, not its parent frame. Frame exports pad the `viewBox` with empty space so height-based sizing renders tiny artwork. Crop the `viewBox` to ink/artwork bounds; for height-based sizing, put `style="height:Npx; width:auto; display:block"` on the root `<svg>`.
- Regex gotcha: `id="X"` contains `d="X"` as a substring. Match `\sd="`, not bare `d="`.
- Replacing an `<img>` with an embed loses the image's classes/margins; reapply spacing on the embed.
- Never call `set_text("")` on a Link that contains icon embeds; it can wipe child embeds.

## Fonts

- Upload fonts with `data_fonts_tool`: `create_font` with MD5 `file_hash`, then presigned upload.
- Source woff2 from Google Fonts `css2` latin endpoint with a desktop User-Agent when needed.
- Never add Google Fonts `<link>` tags to page/site head after uploading fonts; they create duplicate `@font-face` declarations.
- Reference fonts by exact family name.
- First snapshots can show fallback fonts during cold-cache `font-display: swap`. Warm the cache with a throwaway/full-page snapshot and re-snapshot before changing font implementation.
- Variable-font woff2 files can serve multiple weights; registering each weight against the same source file is acceptable.
Loading
Loading