Webflow → React (1:1, visually verified)
Recreate a Webflow page in React so faithfully that automated screenshot
comparison can't tell the copy from the original — and prove it with Playwright.
Core principle
The visual diff is the spec. The job is done when the React copy's
full-page screenshots match the captured Webflow baselines, within tolerance, at
every breakpoint. Everything in this skill exists to drive and verify that
match. Build in a tight loop: capture once → build a section → compare → read the
diff image → fix the cause → repeat.
When to use vs. not
- Use for: cloning/porting a Webflow page or multi-page site into React;
rebuilding a marketing/landing page off Webflow; adding visual-regression
coverage that grades a rebuild against an original URL.
- Not the right fit for: building a brand-new design from scratch (use a design
skill), or backend/app logic unrelated to the visual rebuild.
Inputs to gather first
Confirm these with the user before scaffolding (ask only what's unclear):
- Source — published URL (default) or a Webflow export ZIP? →
references/01-capture-source.md
- Target framework — Vite + React (default) or Next.js (SSR/SEO)? →
references/02-project-setup.md
- Styling strategy — preserve Webflow CSS (default, fastest to 1:1) or
rebuild in Tailwind/CSS Modules? →
references/03-styling-fidelity.md
- Scope — which routes/pages, and the viewports that matter.
Sensible defaults if the user has no preference: published URL · Vite + React +
TS · preserve Webflow CSS. These minimize risk and reach a passing visual gate
fastest; you can refactor toward idiomatic React afterward with the gate
protecting you.
Workflow
Follow in order. Each step links the reference with the detail; load it when you
reach that step rather than all up front.
Capture the source of truth. Inventory fonts/CSS/JS/images/forms/CMS, then
capture baseline screenshots of the original at every viewport. Commit the
baseline/ folder — it's the contract. → references/01-capture-source.md
cp scripts/targets.example.json scripts/targets.json # then edit baseUrl, routes, viewports, hide
node scripts/capture-baseline.mjs --config scripts/targets.json
Scaffold the React project and copy this skill's scripts/ into it. Wire
global styles (normalize → webflow → site) and the document shell. → references/02-project-setup.md
Reproduce styling exactly. Bring Webflow CSS over verbatim (default) or
rebuild; self-host the exact fonts; match the base reset. → references/03-styling-fidelity.md
Componentize without changing the DOM. One component per section; same
tags, nesting, classes, and data-* as the original. Convert HTML→JSX attrs;
.map() over Collection Lists. → references/04-componentization.md
Port interactions & animations. Either keep webflow.js + jQuery for exact
parity (default) or reimplement natively. Match the resting state the gate
screenshots. → references/05-interactions-animations.md
Run the visual loop until green. Compare the running copy to baselines,
read the diff images, fix the topmost difference, repeat — section by section,
viewport by viewport, then tighten thresholds for sign-off. → references/06-visual-testing.md
npm run build && npm run preview & # serve the production build
node scripts/compare-visual.mjs --config scripts/targets.json --url http://localhost:4173 --only home-desktop
npx playwright test --config scripts/playwright.config.ts # CI-grade gate + HTML report
Troubleshoot diffs with the symptom→cause→fix catalog. → references/07-troubleshooting.md
What's in this skill
scripts/capture-baseline.mjs — screenshot the original at all viewports (run once).
scripts/compare-visual.mjs — fast inner-loop diff of the running copy vs baselines; writes report/*.diff.png + report.json.
scripts/visual.spec.ts + playwright.config.ts — the CI gate with retries and an HTML report.
scripts/lib/ — shared snapshot/freeze/crop helpers so every capture is identical.
scripts/targets.example.json — config: source URL, copy URL, routes, viewports, hide selectors, thresholds.
scripts/package.snippet.json — devDeps + vt:* npm scripts to merge in.
references/01–07 — the deep-dive guides linked above.
Definition of done
Guardrails — avoid these mistakes
- Don't screenshot the dev server. Always grade the production build
(
vite preview / next start); HMR and error overlays add pixels.
- Don't change the DOM nesting to "clean it up" while chasing fidelity —
extra/removed wrappers shift layout. Refactor only after the gate is green.
- Don't widen thresholds to hide a real bug. Fix the cause; reserve
pixelThreshold/maxDiffRatio for genuine anti-aliasing noise.
- Don't compare across OSes without regenerating baselines there — font
rendering differs; capture and compare in the same environment.
- Don't skip fonts. Wrong/missing weights are the #1 diff source; the scripts
wait for
document.fonts.ready, but the right files must actually load.
- Capture baselines before you start building, and re-capture only when the
original intentionally changes — review baseline updates like code.
1---2name: webflow-to-react3description: Convert a Webflow page or site into a pixel-perfect React implementation (Vite or Next.js) with Playwright visual-regression testing as the correctness gate. Use when the user wants to migrate, port, rebuild, clone, or recreate a Webflow design 1:1 in React, move off Webflow, or set up screenshot/visual-diff testing of a rebuilt page against the original. Triggers: "convert Webflow to React", "rebuild this Webflow site in Next.js", "pixel-perfect clone", "visual regression vs the original".4license: MIT5---67# Webflow → React (1:1, visually verified)89Recreate a Webflow page in React so faithfully that automated screenshot10comparison can't tell the copy from the original — and prove it with Playwright.1112## Core principle1314**The visual diff is the spec.** The job is done when the React copy's15full-page screenshots match the captured Webflow baselines, within tolerance, at16every breakpoint. Everything in this skill exists to drive and verify that17match. Build in a tight loop: capture once → build a section → compare → read the18diff image → fix the cause → repeat.1920## When to use vs. not2122- Use for: cloning/porting a Webflow page or multi-page site into React;23 rebuilding a marketing/landing page off Webflow; adding visual-regression24 coverage that grades a rebuild against an original URL.25- Not the right fit for: building a brand-new design from scratch (use a design26 skill), or backend/app logic unrelated to the visual rebuild.2728## Inputs to gather first2930Confirm these with the user before scaffolding (ask only what's unclear):31321. **Source** — published URL (default) or a Webflow export ZIP? → `references/01-capture-source.md`332. **Target framework** — Vite + React (default) or Next.js (SSR/SEO)? → `references/02-project-setup.md`343. **Styling strategy** — preserve Webflow CSS (default, fastest to 1:1) or35 rebuild in Tailwind/CSS Modules? → `references/03-styling-fidelity.md`364. **Scope** — which routes/pages, and the viewports that matter.3738Sensible defaults if the user has no preference: **published URL · Vite + React +39TS · preserve Webflow CSS**. These minimize risk and reach a passing visual gate40fastest; you can refactor toward idiomatic React afterward with the gate41protecting you.4243## Workflow4445Follow in order. Each step links the reference with the detail; load it when you46reach that step rather than all up front.47481. **Capture the source of truth.** Inventory fonts/CSS/JS/images/forms/CMS, then49 capture baseline screenshots of the original at every viewport. Commit the50 `baseline/` folder — it's the contract. → `references/01-capture-source.md`51 ```bash52 cp scripts/targets.example.json scripts/targets.json # then edit baseUrl, routes, viewports, hide53 node scripts/capture-baseline.mjs --config scripts/targets.json54 ```55562. **Scaffold the React project** and copy this skill's `scripts/` into it. Wire57 global styles (normalize → webflow → site) and the document shell. → `references/02-project-setup.md`58593. **Reproduce styling exactly.** Bring Webflow CSS over verbatim (default) or60 rebuild; self-host the exact fonts; match the base reset. → `references/03-styling-fidelity.md`61624. **Componentize without changing the DOM.** One component per section; same63 tags, nesting, classes, and `data-*` as the original. Convert HTML→JSX attrs;64 `.map()` over Collection Lists. → `references/04-componentization.md`65665. **Port interactions & animations.** Either keep `webflow.js` + jQuery for exact67 parity (default) or reimplement natively. Match the **resting** state the gate68 screenshots. → `references/05-interactions-animations.md`69706. **Run the visual loop until green.** Compare the running copy to baselines,71 read the diff images, fix the topmost difference, repeat — section by section,72 viewport by viewport, then tighten thresholds for sign-off. → `references/06-visual-testing.md`73 ```bash74 npm run build && npm run preview & # serve the production build75 node scripts/compare-visual.mjs --config scripts/targets.json --url http://localhost:4173 --only home-desktop76 npx playwright test --config scripts/playwright.config.ts # CI-grade gate + HTML report77 ```78797. **Troubleshoot diffs** with the symptom→cause→fix catalog. → `references/07-troubleshooting.md`8081## What's in this skill8283- `scripts/capture-baseline.mjs` — screenshot the original at all viewports (run once).84- `scripts/compare-visual.mjs` — fast inner-loop diff of the running copy vs baselines; writes `report/*.diff.png` + `report.json`.85- `scripts/visual.spec.ts` + `playwright.config.ts` — the CI gate with retries and an HTML report.86- `scripts/lib/` — shared snapshot/freeze/crop helpers so every capture is identical.87- `scripts/targets.example.json` — config: source URL, copy URL, routes, viewports, `hide` selectors, thresholds.88- `scripts/package.snippet.json` — devDeps + `vt:*` npm scripts to merge in.89- `references/01–07` — the deep-dive guides linked above.9091## Definition of done9293- [ ] Every route × viewport **passes** `visual.spec.ts` at the agreed94 `maxDiffRatio` (start 1%, tighten toward ~0.3–0.5% for strict 1:1).95- [ ] No **size mismatches** (copy and original full-page dimensions agree).96- [ ] Diff images show only scattered anti-aliasing, **no structural red**.97- [ ] Interactions/forms behave like the original (nav, tabs, sliders, submit).98- [ ] All declared breakpoints verified, not just desktop.99- [ ] Fonts self-hosted and resolving; no FOUT/fallback in captures.100- [ ] Baselines committed; CI runs the gate on the production build.101102## Guardrails — avoid these mistakes103104- **Don't screenshot the dev server.** Always grade the production build105 (`vite preview` / `next start`); HMR and error overlays add pixels.106- **Don't change the DOM nesting** to "clean it up" while chasing fidelity —107 extra/removed wrappers shift layout. Refactor only after the gate is green.108- **Don't widen thresholds to hide a real bug.** Fix the cause; reserve109 `pixelThreshold`/`maxDiffRatio` for genuine anti-aliasing noise.110- **Don't compare across OSes** without regenerating baselines there — font111 rendering differs; capture and compare in the same environment.112- **Don't skip fonts.** Wrong/missing weights are the #1 diff source; the scripts113 wait for `document.fonts.ready`, but the right files must actually load.114- **Capture baselines before you start building**, and re-capture only when the115 original intentionally changes — review baseline updates like code.