Translates Figma design URLs into complete Nuxt 3 landing pages using RDS Vue UI components. Supports both Dev+ accounts (rich design context) and Basic accounts (screenshot-based). Use when user provides a Figma URL or screenshot of a design to implement.
Converts Figma designs into production-ready Nuxt 3 pages composed from @rds-vue-ui/* components. This skill implements a two-tier approach to accommodate different Figma account levels:
Tier
Input
Context Quality
When Used
Rich Path (Dev+)
Figma URL
Full layout tree, typography, colors, component structure
get_design_context returns rich data
Screenshot Path (Basic)
Figma URL, prototype URL, or image
Visual analysis only
get_design_context fails, returns limited data, or user provides an image/screenshot
Both tiers produce the same output: a pages/<page-name>.vue file with a companion assets/content/<page-name>.json data file, built entirely from @rds-vue-ui/* components.
2. Prerequisites
Before starting, confirm the following are available:
Figma MCP server — connected and responding (required for Figma URL inputs)
Playwright MCP — available for screenshot capture (required for prototype URLs and visual validation)
rds-component-mapper skill — must be available; it provides the shared component selection decision tree used by both tiers
User input — one of the following:
A Figma design URL (e.g. https://figma.com/design/:fileKey/:fileName?node-id=1-2)
A Figma prototype URL (e.g. https://figma.com/proto/:fileKey/...)
A screenshot or image file of the design
3. Step 1 — Detect Input Type & Account Tier
Determine which processing tier to use based on the input and available Figma access.
3.1 Parse the Input
If Figma design URL → extract fileKey and nodeId from the URL format:
Download any assets (icons, illustrations, images) from the Figma MCP localhost endpoints.
IMPORTANT: Use the localhost URLs returned by the Figma MCP server directly. Do NOT import icon packages or substitute with icon libraries. The Figma assets are the source of truth for the design.
4.4 Handle Large / Truncated Responses
If get_design_context returns a response that is too large or appears truncated:
Call get_metadata(fileKey, nodeId) first to get the top-level structure
Identify child node IDs from the metadata
Fetch each child node individually with get_design_context(fileKey, childNodeId)
Reassemble the full design context from the individual responses
4.5 Map Sections to RDS Components
For each design section identified in the context:
Invoke the rds-component-mapper skill decision tree to select the best @rds-vue-ui/* component for the section's visual intent
Create assets/content/campaign-summer-2025.json with all extracted text, images, and links
Validate: compare rendered page screenshot against Figma screenshot
Example 2: User Provides a Screenshot (Screenshot Path)
User input:
Here's a screenshot of the design I need built:
[attached: design-mockup.png]
Agent workflow:
No Figma URL → proceed to Screenshot Path
Analyze design-mockup.png with vision model:
Identified sections:
- Hero: full-width, dark background, large white heading, subtitle, orange CTA button
- Stats bar: horizontal row of 4 stat counters with numbers and labels
- Cards: 3-column grid, each card has an icon, heading, and paragraph
- CTA banner: accent-colored background, centered heading, two buttons
- Footer: dark background, 4-column links layout, social icons
Create assets/content/design-mockup.json with placeholder content:
{
"hero": {
"heading": "[Hero heading — replace with actual copy]",
"subheading": "[Subheading — replace with actual copy]",
"ctaLabel": "Get Started",
"ctaUrl": "#"
}
}
Take screenshot of rendered page via Playwright MCP
Compare side-by-side with original design-mockup.png
Iterate: adjust component props and layout until visual match is satisfactory
1---2name: figma-to-landing-page3description: Translates Figma design URLs into complete Nuxt 3 landing pages using RDS Vue UI components. Supports both Dev+ accounts (rich design context) and Basic accounts (screenshot-based). Use when user provides a Figma URL or screenshot of a design to implement.4---56# Figma to Landing Page78## 1. Overview910Converts Figma designs into production-ready Nuxt 3 pages composed from `@rds-vue-ui/*` components. This skill implements a **two-tier approach** to accommodate different Figma account levels:1112| Tier | Input | Context Quality | When Used |13|------|-------|-----------------|-----------|14| **Rich Path** (Dev+) | Figma URL | Full layout tree, typography, colors, component structure | `get_design_context` returns rich data |15| **Screenshot Path** (Basic) | Figma URL, prototype URL, or image | Visual analysis only | `get_design_context` fails, returns limited data, or user provides an image/screenshot |1617Both tiers produce the same output: a `pages/<page-name>.vue` file with a companion `assets/content/<page-name>.json` data file, built entirely from `@rds-vue-ui/*` components.1819---2021## 2. Prerequisites2223Before starting, confirm the following are available:24251. **Figma MCP server** — connected and responding (required for Figma URL inputs)262. **Playwright MCP** — available for screenshot capture (required for prototype URLs and visual validation)273. **`rds-component-mapper` skill** — must be available; it provides the shared component selection decision tree used by both tiers284. **User input** — one of the following:29 - A Figma design URL (e.g. `https://figma.com/design/:fileKey/:fileName?node-id=1-2`)30 - A Figma prototype URL (e.g. `https://figma.com/proto/:fileKey/...`)31 - A screenshot or image file of the design3233---3435## 3. Step 1 — Detect Input Type & Account Tier3637Determine which processing tier to use based on the input and available Figma access.3839### 3.1 Parse the Input40411. **If Figma design URL** → extract `fileKey` and `nodeId` from the URL format:42 ```43 https://figma.com/design/:fileKey/:fileName?node-id=<nodeId>44 ```45 - `fileKey` is the path segment after `/design/`46 - `nodeId` is the `node-id` query parameter (e.g. `1-2`)47482. **If Figma prototype URL** → extract `fileKey` from:49 ```50 https://figma.com/proto/:fileKey/...51 ```52 - A prototype URL indicates the Screenshot Path (no design context available)53543. **If screenshot/image** → proceed directly to Screenshot Path (Step 2b)5556### 3.2 Probe Account Tier5758If a `fileKey` and `nodeId` were extracted:59601. Call `get_design_context(fileKey, nodeId)` via the Figma MCP server612. Evaluate the response:62 - **Rich data returned** (layout tree, typography tokens, colors, component structure) → proceed to **Rich Path (Step 2a)**63 - **Call fails, times out, or returns limited/empty data** → fall back to **Screenshot Path (Step 2b)**6465---6667## 4. Step 2a — Rich Path (Dev+ Account)6869Use this path when `get_design_context` returns comprehensive design data.7071### 4.1 Extract Design Context7273```74get_design_context(fileKey, nodeId)75```7677From the response, extract:78- **Layout structure** — frame hierarchy, auto-layout direction, spacing, padding79- **Typography** — font family, size, weight, line height, letter spacing80- **Colors** — fills, strokes, effects (map to RDS theme CSS variables)81- **Component structure** — instances, variants, nested components8283### 4.2 Get Visual Reference8485```86get_screenshot(fileKey, nodeId)87```8889Capture a screenshot for visual validation later.9091### 4.3 Download Assets9293Download any assets (icons, illustrations, images) from the Figma MCP localhost endpoints.9495> **IMPORTANT:** Use the localhost URLs returned by the Figma MCP server directly. Do **NOT** import icon packages or substitute with icon libraries. The Figma assets are the source of truth for the design.9697### 4.4 Handle Large / Truncated Responses9899If `get_design_context` returns a response that is too large or appears truncated:1001011. Call `get_metadata(fileKey, nodeId)` first to get the top-level structure1022. Identify child node IDs from the metadata1033. Fetch each child node individually with `get_design_context(fileKey, childNodeId)`1044. Reassemble the full design context from the individual responses105106### 4.5 Map Sections to RDS Components107108For each design section identified in the context:1091101. **Invoke the `rds-component-mapper` skill decision tree** to select the best `@rds-vue-ui/*` component for the section's visual intent1112. **Map Figma design tokens to RDS component props:**112 - Figma auto-layout → RDS section layout props113 - Figma text styles → RDS typography props (heading level, size, weight)114 - Figma color fills → RDS theme CSS variables (`var(--rds-color-*)`)115 - Figma component instances → nested RDS sub-components1163. **Extract content:** headings, body text, CTA labels, image URLs, link targets1174. **Extract colors:** map hex values to the closest RDS theme variable118119### 4.6 Compose the Page120121Assemble all mapped sections into a single `pages/<page-name>.vue` file:122123```vue124<script setup>125const content = await import('~/assets/content/<page-name>.json')126</script>127128<template>129 <div>130 <!-- Each section maps to an @rds-vue-ui/* component -->131 <HeroStandardApollo v-bind="content.hero" />132 <SectionCardsApollo v-bind="content.cards" />133 <!-- ... -->134 </div>135</template>136```137138### 4.7 Create Content JSON139140Create `assets/content/<page-name>.json` with all extracted content:141142```json143{144 "hero": {145 "heading": "Extracted heading from Figma",146 "subheading": "Extracted subheading",147 "ctaLabel": "Get Started",148 "ctaUrl": "#",149 "backgroundImage": "/images/hero-bg.jpg"150 },151 "cards": {152 "items": [153 {154 "title": "Card Title",155 "description": "Card description text",156 "image": "/images/card-1.jpg"157 }158 ]159 }160}161```162163### 4.8 Validate Against Screenshot164165Compare the composed page output against the Figma screenshot captured in Step 4.2. Check alignment, spacing, typography, and color fidelity.166167---168169## 5. Step 2b — Screenshot Path (Basic Account / Image Input)170171Use this path when rich design context is unavailable.172173### 5.1 Obtain the Screenshot174175| Input Type | Method |176|------------|--------|177| Figma design URL | Call `get_screenshot(fileKey, nodeId)` — works on all Figma account tiers |178| Figma prototype URL | Use Playwright MCP: `browser_navigate` to the URL, then `browser_take_screenshot` |179| User-provided image | Use the image directly |180181### 5.2 Analyze the Screenshot182183Use the vision model to analyze the screenshot and identify:1841851. **Page sections** — hero area, content blocks, testimonial strips, card grids, CTAs, footer1862. **Approximate layout** — full-width sections, grid columns (2-col, 3-col, 4-col), sidebars, stacked layouts1873. **Content** — headings (H1, H2, H3), body text, button labels, image placeholders1884. **Color palette** — dominant colors, accent colors, background tones1895. **Typography hints** — relative font sizes, weight variations (bold headings vs. regular body), text alignment190191### 5.3 Map Sections to RDS Components192193For each visually identified section:1941951. **Invoke the `rds-component-mapper` skill decision tree** to select the closest `@rds-vue-ui/*` component1962. **Infer props from visual analysis:**197 - Section height/width → layout sizing props198 - Observed colors → closest RDS theme CSS variables199 - Text content → extract where readable, use descriptive placeholders where not (e.g. `"[Hero heading text]"`)200 - Image areas → placeholder image paths2013. **Generate placeholder content** for any text that cannot be reliably extracted from the screenshot202203### 5.4 Compose the Page204205Assemble into `pages/<page-name>.vue` following the same structure as the Rich Path (Step 4.6).206207### 5.5 Create Content JSON208209Create `assets/content/<page-name>.json` following the same structure as the Rich Path (Step 4.7). Mark placeholder content clearly:210211```json212{213 "hero": {214 "heading": "[Hero heading — replace with actual copy]",215 "subheading": "[Subheading — replace with actual copy]",216 "ctaLabel": "Learn More",217 "backgroundImage": "/images/placeholder-hero.jpg"218 }219}220```221222### 5.6 Visual Comparison2232241. Take a screenshot of the generated page using Playwright MCP (`browser_navigate` → `browser_take_screenshot`)2252. Compare side-by-side with the original Figma screenshot / user image2263. Iterate on component selection and props until the output closely matches the original design227228---229230## 6. Translation Rules231232Figma MCP outputs React + Tailwind CSS by default. All output must be translated to the RDS stack:233234| Figma MCP Output | RDS Target |235|-------------------|------------|236| React JSX | Vue 3 `<template>` with `<script setup>` |237| Tailwind utility classes | Bootstrap 5 classes or custom SCSS |238| Inline `style` objects | SCSS `<style lang="scss" scoped>` blocks |239| Hardcoded hex colors | RDS theme CSS variables (`var(--rds-primary)`, `var(--rds-secondary)`, etc.) |240| `className` | `class` |241| `onClick` / `onChange` | `@click` / `@change` |242| `{condition && <El/>}` | `v-if="condition"` |243| `{items.map(i => ...)}` | `v-for="item in items"` |244| React component imports | **None** — RDS components are auto-imported via Nuxt component scanner |245246### Component Naming247248- Use **PascalCase** for all component names in templates: `<HeroStandardApollo>`, `<SectionCardsApollo>`249- Do **NOT** add `import` statements for `@rds-vue-ui/*` components — they are auto-imported250251### Styling252253- Use Bootstrap 5 utility classes where they match the design intent254- For custom styling beyond Bootstrap, use scoped SCSS:255 ```vue256 <style lang="scss" scoped>257 .custom-section {258 padding: 4rem 0;259 background-color: var(--rds-surface);260 }261 </style>262 ```263- Never use Tailwind classes — the project uses Bootstrap 5 + SCSS exclusively264265---266267## 7. Desktop + Mobile268269### When Both Viewports Are Provided270271If the user provides separate Figma nodes for desktop and mobile:2722731. Extract/analyze both viewports2742. Implement responsive behavior using Bootstrap responsive classes:275 - `col-lg-*` / `col-md-*` / `col-sm-*` for grid columns276 - `d-none d-lg-block` / `d-lg-none` for viewport-specific elements277 - `order-lg-*` for reordering on different breakpoints2783. Validate both viewports against their respective Figma screenshots279280### When Only Desktop Is Provided2812821. Implement the desktop design faithfully2832. Apply sensible mobile defaults using Bootstrap's responsive grid2843. Stack columns on mobile (`col-12` on small screens, `col-lg-*` on large)285286### Breakpoint Reference287288| Bootstrap Class | Breakpoint |289|----------------|------------|290| `col-sm-*` | ≥ 576px |291| `col-md-*` | ≥ 768px |292| `col-lg-*` | ≥ 992px |293| `col-xl-*` | ≥ 1200px |294| `col-xxl-*` | ≥ 1400px |295296---297298## 8. Validation Checklist299300Before considering the page complete, verify every item:301302- [ ] **Layout matches** — spacing, alignment, sizing match the Figma design303- [ ] **Typography matches** — font family, size, weight, line height are correct304- [ ] **Colors match** — all colors use RDS theme CSS variables (no hardcoded hex)305- [ ] **Components used** — all sections use `@rds-vue-ui/*` components where a suitable match exists306- [ ] **Content is JSON-driven** — all text, images, and data come from `assets/content/<page-name>.json`307- [ ] **No manual imports** — no `import` statements for RDS components (auto-imported)308- [ ] **Vue 3 syntax** — `<script setup>`, `v-if`, `v-for`, `@click` (no React patterns)309- [ ] **Bootstrap 5 only** — no Tailwind classes; Bootstrap utilities + SCSS310- [ ] **Responsive** — desktop and mobile viewports render correctly311- [ ] **Assets downloaded** — icons and images from Figma are saved locally (not imported from packages)312- [ ] **Visual comparison** — side-by-side screenshot matches the original design313314---315316## 9. Examples317318### Example 1: Figma URL with Dev+ Account (Rich Path)319320**User input:**321```322Build a landing page from this Figma design:323https://figma.com/design/ABC123xyz/campaign-summer-2025?node-id=1-2324```325326**Agent workflow:**3273281. Parse URL → `fileKey = "ABC123xyz"`, `nodeId = "1-2"`3292. Call `get_design_context("ABC123xyz", "1-2")` → returns rich data:330 ```331 Frame "Hero Section"332 - Auto-layout: vertical, gap 24px, padding 64px333 - Background: linear-gradient(#1a2b3c, #2c3d4e)334 - Text "Summer Campaign 2025" — Inter Bold 48px #FFFFFF335 - Text "Discover what's new" — Inter Regular 18px #B0B8C4336 - Button "Explore Now" — fill #FF6B35, text #FFFFFF337 Frame "Features Grid"338 - Auto-layout: horizontal, gap 32px, wrap339 - 3x Card children with icon + title + description340 Frame "Testimonials"341 - Carousel with 4 testimonial cards342 ```3433. Call `get_screenshot("ABC123xyz", "1-2")` → save reference image3444. Download icon assets from Figma MCP localhost URLs3455. Invoke `rds-component-mapper` for each section:346 - "Hero Section" → `HeroStandardApollo`347 - "Features Grid" → `SectionCardsApollo`348 - "Testimonials" → `SectionTestimonialsApollo`3496. Map Figma tokens to RDS props:350 - `#1a2b3c` gradient → `var(--rds-primary-dark)`351 - `#FF6B35` button → `var(--rds-accent)`352 - Inter Bold 48px → heading level 13537. Create `pages/campaign-summer-2025.vue`:354 ```vue355 <script setup>356 import content from '~/assets/content/campaign-summer-2025.json'357 </script>358359 <template>360 <div>361 <HeroStandardApollo362 :heading="content.hero.heading"363 :subheading="content.hero.subheading"364 :cta-label="content.hero.ctaLabel"365 :cta-url="content.hero.ctaUrl"366 :background-image="content.hero.backgroundImage"367 />368 <SectionCardsApollo369 :heading="content.features.heading"370 :cards="content.features.items"371 />372 <SectionTestimonialsApollo373 :testimonials="content.testimonials.items"374 />375 </div>376 </template>377 ```3788. Create `assets/content/campaign-summer-2025.json` with all extracted text, images, and links3799. Validate: compare rendered page screenshot against Figma screenshot380381---382383### Example 2: User Provides a Screenshot (Screenshot Path)384385**User input:**386```387Here's a screenshot of the design I need built:388[attached: design-mockup.png]389```390391**Agent workflow:**3923931. No Figma URL → proceed to Screenshot Path3942. Analyze `design-mockup.png` with vision model:395 ```396 Identified sections:397 - Hero: full-width, dark background, large white heading, subtitle, orange CTA button398 - Stats bar: horizontal row of 4 stat counters with numbers and labels399 - Cards: 3-column grid, each card has an icon, heading, and paragraph400 - CTA banner: accent-colored background, centered heading, two buttons401 - Footer: dark background, 4-column links layout, social icons402 ```4033. Invoke `rds-component-mapper` for each section:404 - Hero → `HeroStandardApollo`405 - Stats bar → `SectionCountersApollo`406 - Cards grid → `SectionCardsApollo`407 - CTA banner → `SectionCtaApollo`408 - Footer → `FooterStandardApollo`4094. Infer props from visual analysis:410 - Dark hero background → `var(--rds-primary-dark)`411 - Orange CTA → `var(--rds-accent)`412 - 3-column layout → `columns: 3`4135. Create `pages/design-mockup.vue`:414 ```vue415 <script setup>416 import content from '~/assets/content/design-mockup.json'417 </script>418419 <template>420 <div>421 <HeroStandardApollo422 :heading="content.hero.heading"423 :subheading="content.hero.subheading"424 :cta-label="content.hero.ctaLabel"425 :cta-url="content.hero.ctaUrl"426 />427 <SectionCountersApollo428 :counters="content.stats.items"429 />430 <SectionCardsApollo431 :heading="content.cards.heading"432 :cards="content.cards.items"433 :columns="3"434 />435 <SectionCtaApollo436 :heading="content.cta.heading"437 :primary-label="content.cta.primaryLabel"438 :secondary-label="content.cta.secondaryLabel"439 />440 <FooterStandardApollo441 :columns="content.footer.columns"442 :social-links="content.footer.socialLinks"443 />444 </div>445 </template>446 ```4476. Create `assets/content/design-mockup.json` with placeholder content:448 ```json449 {450 "hero": {451 "heading": "[Hero heading — replace with actual copy]",452 "subheading": "[Subheading — replace with actual copy]",453 "ctaLabel": "Get Started",454 "ctaUrl": "#"455 }456 }457 ```4587. Take screenshot of rendered page via Playwright MCP4598. Compare side-by-side with original `design-mockup.png`4609. Iterate: adjust component props and layout until visual match is satisfactory
Run npx skillmds@latest add chandima/figma-to-landing-page in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Translates Figma design URLs into complete Nuxt 3 landing pages using RDS Vue UI components. Supports both Dev+ accounts (rich design context) and Basic accounts (screenshot-based). Use when user provides a Figma URL or screenshot of a design to implement. It is listed under Design & Media on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
chandima (@chandima) published this skill. Their other Agent Skills are listed on their SkillMD profile.