---
name: duplicate-page
description: "[EXPERIMENTAL] Duplicate an existing web page by capturing it through Figma as a structured design intermediary and generating high-fidelity React + Tailwind components. This skill is experimental — it does not fit reliably into the project workflow and may produce inconsistent results. Use when user says "duplicate page", "clone page", "copy page", "replicate page", "recreate page", "make a copy of this site", provides a URL they want to reproduce as a React page, or wants to faithfully recreate an external website. This skill produces much higher fidelity reproductions than create-page because it uses Figma's capture engine to extract actual DOM structure, colors, typography, and layout rather than relying on screenshot-based inspiration."
allowed-tools: Bash, Bash(playwright-cli:*), Read, Write, Edit, Glob, Grep, mcp__figma__generate_figma_design, mcp__figma__get_design_context, mcp__figma__get_screenshot, mcp__figma__get_metadata, mcp__figma__add_code_connect_map
---

# Duplicate Page Skill (Experimental)

> **⚠️ Experimental:** This skill is not yet fit for the project's standard workflow and cannot produce reliable results. Use with caution and expect manual adjustments.

Faithfully reproduce an external web page as a React + Tailwind page in this project. Unlike `create-page` (which uses screenshots as loose inspiration), this skill routes the source page through Figma's capture engine to extract structured layout, colors, and typography — then converts the Figma design back into project-native React + Tailwind code.

**Pipeline:** URL → Figma Design → Structured Code Extraction → Adapted React Components & Page

## Parameters

- **url** (required): URL of the web page to duplicate
- **route** (required): Target route path (e.g., "landing", "pricing")
- **scope** (optional): `repository` or `local` (default: ask user)
- **extractComponents** (optional): Whether to extract reusable components from page sections (default: `true`)

## Prerequisites

This skill requires the Figma MCP server (`figma@claude-plugins-official`).
If unavailable, report: "Figma MCP server not connected. Enable `figma@claude-plugins-official` in `.claude/settings.json` or check your Figma authentication." Then fall back to the `create-page` skill with the URL as `referenceUrl`.

## Workflow

### 1. Reconnaissance with Playwright

Before Figma captures the page, use playwright to understand the page structure and prepare it for clean capture. This step matters because pages often have cookie banners, popups, and lazy-loaded content that would pollute the capture.

1. Open the target URL:
   ```bash
   playwright-cli open {url}
   ```
2. Resize to standard desktop width for consistent Figma frames:
   ```bash
   playwright-cli resize 1440 900
   ```
3. Wait for the page to finish loading, then take a snapshot to understand structure:
   ```bash
   playwright-cli snapshot
   ```
4. Inspect the snapshot for cookie banners, popups, or overlays. If found, dismiss them by clicking the appropriate button (e.g., "Accept", "Close", "✕").
5. Scroll through the page to trigger lazy-loaded content:
   ```bash
   playwright-cli eval "window.scrollTo(0, document.body.scrollHeight)"
   playwright-cli eval "window.scrollTo(0, 0)"
   ```
6. Take a full-page screenshot as the reference baseline:
   ```bash
   playwright-cli screenshot --filename=reference-original.png
   ```
7. Scroll down and capture additional sections at key scroll positions to ensure you understand the full page layout.
8. Close the browser:
   ```bash
   playwright-cli close
   ```

Record the page sections you identified (e.g., header/nav, hero, features, pricing, footer) — you'll use this to guide the Figma structure inspection in Step 3.

### 2. Capture to Figma

**Important limitation:** `generate_figma_design` runs in an isolated browser context that does not share session profiles (cookies, authentication, local storage) with the user's regular browser. This means:
- Pages requiring login or specific session state will not capture correctly
- Even public pages may render differently without the user's browser profile (e.g., region-specific content, A/B test variants, dismissed cookie banners)
- The capture can fail outright if the page detects an unfamiliar browser environment

**Because of this, ask the user to capture the page manually:**

1. Tell the user: "Please open **{url}** in your browser, select the content you want to capture, and copy it to your clipboard. Then paste it into a new Figma file. Once done, share the Figma file URL (with the node selected) so I can extract the design."
2. Wait for the user to provide a Figma URL (format: `figma.com/design/:fileKey/:fileName?node-id=:nodeId`)
3. Parse the `fileKey` and `nodeId` from the URL (convert `-` to `:` in nodeId)

**Optional — try automated capture first:**

If the user prefers, you can attempt `generate_figma_design` as a first pass:
- Call `generate_figma_design` with:
  - `url`: The source page URL
  - `outputMode`: `newFile` (creates a new Figma file)
  - `fileName`: "Duplicate - {domain} - {date}" (e.g., "Duplicate - stripe.com - 2026-03-15")
- The tool returns a `captureId` — poll for completion every 5 seconds (up to 10 polls)
- On completion, extract the `fileKey` and root `nodeId` from the response

If the automated capture fails, falls back to manual clipboard capture as described above.

### 3. Inspect Figma Design Structure

Use `get_metadata` to understand the layer hierarchy of the captured Figma design. This reveals the logical sections Figma identified from the DOM.

- Call `get_metadata` with `fileKey` and root `nodeId`
- Parse the XML response to identify top-level frames/sections
- Build a section map: name, nodeId, type, and approximate size
- Cross-reference with the sections you identified during playwright reconnaissance

### 4. Extract Code Section-by-Section

For each top-level section identified in Step 3, call `get_design_context` to extract React + Tailwind code. Extracting per-section (rather than the whole page at once) produces cleaner, more manageable code.

- For each section, call `get_design_context` with:
  - `fileKey` and section `nodeId`
- Each call returns:
  - React + Tailwind code snippet
  - A screenshot of that section
  - Design hints (Code Connect mappings, component docs, design tokens, annotations)
- Collect all section code blocks and note any image asset references
- If a section is too large and returns metadata-only, break it into smaller sub-sections using `get_metadata` and extract those individually

### 5. Gather Project Context

Load the project's design system to adapt the extracted code:

- Read `shared/references/component-registry.md` — discover existing components to reuse
- Read `shared/references/tailwind-theme.md` — project design tokens
- Read `shared/references/figma-compat-rules.md` — compatibility constraints
- Read `shared/references/image-handling.md` — image asset workflow

### 6. Adapt and Generate Components

This is where raw Figma-extracted code becomes project-native. The goal is faithful visual reproduction while using the project's design system.

**If `extractComponents` is true:**

Analyze each extracted section for reusability:
- Sections matching common patterns (Navbar, Hero, Card grid, CTA, Footer) become standalone components
- Highly page-specific sections stay inline in the page file

For each component to extract:
- Create `src/components/{Name}/{Name}.tsx` (or `src/components/_local/{Name}/{Name}.tsx` for local scope)
- Create matching `{Name}.stories.tsx` with representative stories
- Map Figma-extracted values to project theme tokens:
  - Convert arbitrary hex colors (e.g., `bg-[#6366f1]`) to theme tokens (e.g., `bg-primary`)
  - Convert arbitrary spacing to the nearest theme value
  - Use project typography scale
- If no close theme token match exists, keep the arbitrary value — fidelity to the original is the priority

**If `extractComponents` is false:**

Keep all sections inline within the page component.

### 7. Generate Page

Create the page file composing all sections:

- **Repository scope**: `src/pages/{route}/index.tsx`
- **Local scope**: `src/pages/_local/{route}/index.tsx`

The page should:
- Default export a React component
- Import extracted components from Step 6
- Compose sections in order: header/nav → main content sections → footer
- Use Tailwind CSS utility classes

**Handle image assets:**
- Download images from Figma MCP URLs (they expire after 14 days, so download immediately)
- Save to `src/assets/images/{route}/` with content-hash filenames
- Update `src/assets/images/asset-map.json` with new mappings
- Reference local paths in `<img>` tags with explicit width/height

### 8. Update Indexes

Add documentation entries:

- Add page entry to `docs/pages.md` (or `docs/_local/pages.md` for local scope):
  ```markdown
  ## {Title}
  - **Route**: `/{route}`
  - **Title**: {page title}
  - **Description**: Duplicated from {url}
  - **Path**: `src/pages/{route}/index.tsx`
  - **Dependencies**: {list of components used}
  - **Figma**: {Figma file URL}
  ```

- If new components were created, add entries to `docs/components.md` (or `docs/_local/components.md`)
- Update `shared/references/component-registry.md` with new components

### 9. Visual Verification

Perform a three-way comparison to verify fidelity:

1. Start the dev server if not already running
2. Open the generated page in playwright at `http://localhost:5173/{route}`
3. Take a screenshot of the rendered page
4. Fetch the Figma design screenshot via `get_screenshot`
5. Compare all three: original site (from Step 1), Figma design, and rendered page
6. Describe any visual discrepancies

If discrepancies are found:
- Identify the root cause (missing styles, wrong colors, layout issues)
- Apply corrective edits to the source files
- Re-verify (up to 3 iterations)

After verification passes:
- Establish Code Connect mapping via `add_code_connect_map` to link the Figma design to the React code

## Output

Report:
1. Figma design created (URL + file key)
2. Sections identified and extracted (list with node IDs)
3. Components created (file paths)
4. Page created (file path, route)
5. Image assets downloaded (count, paths)
6. Figma compatibility notes (if any)
7. Index documents updated
8. Visual verification result (screenshot comparison)
9. Code Connect mappings established

## Error Handling

- **Figma MCP unavailable**: Fall back to `create-page` skill with URL as `referenceUrl`
- **URL unreachable**: Report error, suggest checking the URL or network
- **Capture timeout**: Report after 10 polls, fall back to manual clipboard capture
- **Automated capture fails (session/auth issues)**: Ask the user to copy the page to clipboard in their browser and paste into Figma, then provide the Figma URL
- **Section too large for `get_design_context`**: Break into smaller sub-sections via `get_metadata`
- **Image download failure**: Use placeholder, warn user, provide Figma URL for manual download
- **Auth-gated pages**: Document as limitation — capture only works on publicly accessible pages

## Example

User: "Duplicate https://stripe.com/pricing — route it to /pricing"

1. Opens stripe.com/pricing in playwright, dismisses cookie banner, scrolls to load all content, captures reference screenshots
2. Asks user to copy the page to clipboard in their browser and paste into a Figma file → user provides Figma URL with node ID
3. Inspects Figma structure: identifies Hero, PricingTable, FeatureComparison, FAQ, Footer frames
4. Extracts React + Tailwind code per section via `get_design_context`
5. Loads project theme tokens and component registry
6. Creates components: PricingHero, PricingTable, FeatureGrid, PricingFAQ
7. Creates `src/pages/_local/pricing/index.tsx` composing all components
8. Updates docs/_local/pages.md and docs/_local/components.md
9. Three-way visual verification, establishes Code Connect mappings
