BMAD-METHOD/docs/tools/prepare-for-figma-export.md

18 KiB

Prepare for Figma Export: ID Injection Workflow

Version: 1.0
Last Updated: January 21, 2026
Purpose: Temporarily add OBJECT IDs to HTML for Figma MCP export
Direction: Code → Figma (with temporary ID injection)


Overview

This workflow enables exporting code to Figma via the html.to.design MCP server without permanently adding IDs to production code. The agent temporarily injects OBJECT IDs from specifications during export, then removes them afterward.

The Problem This Solves

  • Production code stays clean - No unnecessary IDs cluttering components
  • Figma layers get proper names - OBJECT IDs from specifications used for layer naming
  • Specification mapping maintained - Clear connection between specs, code, and Figma
  • Accessibility preserved - No misuse of aria-label for layer naming
  • Flexible workflow - Works for early prototypes and production code

When to Use This Workflow

Use this workflow when:

  • Exporting early prototypes that don't have IDs yet
  • Exporting from browser preview for quick design review
  • Sending production code to Figma without modifying source files
  • Testing visual iterations in Figma before committing to code changes

Choosing Your Export Method

There are two methods for exporting to Figma, each with different capabilities:

Feature Method 1: MCP Server Method 2: Browser Extension
Automation Fully automated ⚠️ Manual capture required
File Modification No files modified ⚠️ Temporary aria-labels added to source
Multiple Viewports One viewport at a time Mobile, tablet, desktop simultaneously
Responsive Testing Limited True responsive capture
Speed Instant ⚠️ Requires browser interaction
Safety Zero risk (no file changes) ⚠️ Must remember to remove aria-labels
Best For Quick single-page exports Responsive design documentation

Recommendation

Use MCP Server (Method 1) when:

  • You need a quick export for design review
  • You're exporting a single viewport
  • You want zero risk of modifying source files

Use Browser Extension (Method 2) when:

  • You need multiple viewport captures (mobile/tablet/desktop)
  • You're documenting responsive behavior
  • You want to see how design adapts across breakpoints

Core Principle: Temporary aria-label Injection

The Strategy:

  1. Read the component code (without aria-labels)
  2. Load OBJECT IDs from specification
  3. Generate temporary HTML with aria-label attributes matching OBJECT IDs
  4. Export to Figma via MCP (one page at a time)
  5. Discard temporary HTML (never save to files)

Result: Figma layers get named from aria-label values, production code stays clean.

Why aria-label for Figma?

  • The html.to.design MCP server uses aria-label attributes to name Figma layers
  • These are temporary - only added during export, never saved to source files
  • Production code keeps proper accessibility practices (aria-labels only where needed)

Phase 1: Identify Export Target

Step 1.1: Determine What to Export

User Request Examples:

  • "Export the sign-in page to Figma"
  • "Send the CTA button states to Figma for design review"
  • "I want to iterate on the hero section spacing in Figma"

Extract:

  • Component/page name
  • File path (if provided)
  • Purpose (design review, state documentation, visual iteration)

Step 1.2: Locate Source Code

Search Strategy:

1. Check if user provided file path
2. Search in components/ directory
3. Search in app/ directory
4. Search in docs/ for prototypes

Decision Point:

  • Source found → Continue to Phase 2
  • Source not found → Ask user for clarification

Phase 2: Load Specification OBJECT IDs

Step 2.1: Search for Specification

Search Locations (priority order):

  1. docs/C-Scenarios/ - Scenario specifications
  2. docs/D-Design-System/ - Component specifications
  3. Project root - Any related markdown files

Search Method:

Use grep_search or find_by_name to locate:
- Files containing component/page name
- Files with "OBJECT ID" references
- Specification markdown files

Step 2.2: Extract OBJECT IDs

What to Extract:

From specification file:

#### Hero Section CTA Button
**OBJECT ID**: `start-hero-cta`
**CSS Class**: `.btn-cta-primary`

Extract:
- OBJECT ID: start-hero-cta
- Component: Hero Section CTA Button
- CSS Class: btn-cta-primary

Create ID Mapping:

{
  "start-hero-cta": {
    "cssClass": "btn-cta-primary",
    "selector": "button.btn-cta-primary",
    "type": "button"
  },
  "start-hero-headline": {
    "cssClass": "hero-headline",
    "selector": "h1.hero-headline",
    "type": "heading"
  }
}

Step 2.3: Handle Missing Specifications

If no specification found:

Option A: Generate IDs from Code Structure

Analyze component structure:
- Extract CSS class names
- Identify semantic elements
- Generate OBJECT IDs following project convention

Pattern: {page}-{section}-{element}
Example: start-hero-cta, start-hero-headline

Option B: Ask User for Guidance

⚠️ No specification found for {component-name}

I can:
1. Generate temporary IDs based on code structure
2. Create a specification first (recommended)
3. Use CSS class names as IDs

Which approach would you prefer?

Phase 3: Generate Temporary HTML with IDs

Step 3.1: Read Source Code

For React/TSX Components:

// Original component (no IDs)
export function LandingHero() {
  return (
    <section className="hero-section">
      <div className="hero-content">
        <h1 className="hero-headline">
          Every walk. on time. Every time.
        </h1>
        <button className="btn-cta-primary">
          Start Planning
        </button>
      </div>
    </section>
  )
}

Step 3.2: Map OBJECT IDs to Elements

Mapping Strategy:

Match by CSS class:
  .hero-section → aria-label="start-hero-section"
  .hero-content → aria-label="start-hero-content"
  .hero-headline → aria-label="start-hero-headline"
  .btn-cta-primary → aria-label="start-hero-cta"

Match by semantic element + context:
  <section> in hero → aria-label="start-hero-section"
  <h1> in hero → aria-label="start-hero-headline"
  <button> with CTA class → aria-label="start-hero-cta"

Step 3.3: Generate HTML with Injected aria-labels

Transformation:

<!-- Generated HTML for Figma export -->
<section aria-label="start-hero-section" class="hero-section">
  <div aria-label="start-hero-content" class="hero-content">
    <h1 aria-label="start-hero-headline" class="hero-headline">
      Every walk. on time. Every time.
    </h1>
    <button aria-label="start-hero-cta" class="btn-cta-primary">
      Start Planning
    </button>
  </div>
</section>

Key Points:

  • aria-label attributes added to semantic elements (temporary, for Figma layer naming)
  • Original classes preserved
  • Structure unchanged
  • Content matches source exactly

Step 3.4: Add Inline Styles for Figma Compatibility

Style Requirements:

<style>
  @import url('https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600&display=swap');
  
  /* Convert CSS variables to hex values */
  .hero-section {
    background: linear-gradient(180deg, #FFA100 0%, #FF2714 100%);
    padding: 60px 20px;
    font-family: 'Fredoka', sans-serif;
  }
  
  .hero-headline {
    font-size: 48px;
    font-weight: 600;
    color: #FEF3CF;
    line-height: 1.2;
  }
  
  .btn-cta-primary {
    background: linear-gradient(to bottom, #FFA100, #FF2714);
    color: #FEF3CF;
    padding: 13px 25px 16px;
    border-radius: 16px;
    font-size: 18px;
    font-weight: 500;
    border: 1px solid #FFA100;
  }
</style>

Style Conversion Rules:

  • CSS variables → Hex colors
  • rem/em → px values
  • Google Fonts only
  • Inline or <style> block

Note: Styles use class selectors. The aria-label attributes are only for Figma layer naming, not for styling.


Phase 4: Export to Figma

Step 4.1: Verify MCP Connection

Check:

Is mcp1_import-html tool available?
- ✅ Yes → Continue to export
- ❌ No → Guide user through setup (see figma-mcp.md)

Step 4.2: Execute Export

MCP Call:

mcp1_import-html({
  name: "Landing Hero - Start Page",
  html: `
    <div aria-label="start-hero-export">
      <style>
        /* Figma-compatible styles */
      </style>
      
      <!-- HTML with aria-label attributes matching OBJECT IDs -->
      <section aria-label="start-hero-section" class="hero-section">
        ...
      </section>
    </div>
  `
})

Expected Response:

{
  "node": {
    "id": "3:150",
    "name": "Landing Hero - Start Page by html.to.design...",
    "type": "SECTION"
  }
}

Step 4.3: Verify Export Success

Success Indicators:

  • Node ID returned
  • No error message
  • User confirms layer visible in Figma
  • Layer names match OBJECT IDs (from aria-label attributes)

Communicate to User:

✅ Successfully exported to Figma!

Export Details:
- Component: Landing Hero
- Figma Node ID: 3:150
- OBJECT IDs used (as aria-labels):
  • start-hero-section
  • start-hero-content
  • start-hero-headline
  • start-hero-cta

The layers in Figma now match your specification OBJECT IDs. 
You can make visual adjustments in Figma and reference these IDs 
when discussing changes.

Note: The aria-label attributes were added temporarily for export 
only - your source code remains unchanged.

Phase 5: Post-Export Cleanup

Step 5.1: Discard Temporary HTML

Important:

  • DO NOT save the temporary HTML to any file
  • DO NOT commit aria-label-injected code to repository
  • ONLY use temporary HTML for MCP export (one page at a time)
  • KEEP original source code unchanged

Why:

  • Production code should only have aria-labels for genuine accessibility needs
  • Temporary aria-labels are for Figma layer naming only
  • Specifications remain the source of truth for OBJECT IDs

Step 5.2: Document Export Metadata (Optional)

If user wants to track exports:

## Figma Export Log

### Landing Hero - 2026-01-21
- **Source**: components/landing-hero.tsx
- **Figma Node**: 3:150
- **OBJECT IDs** (via aria-label): start-hero-section, start-hero-content, start-hero-headline, start-hero-cta
- **Purpose**: Design review for spacing and gradient adjustments
- **Specification**: docs/C-Scenarios/01-Customer-Onboarding/1.1-Start-Page/1.1-Start-Page.md

Workflow Variations

Variation A: MCP Server Export (Single Viewport)

Scenario: Quick export via MCP server, one page at a time

Process:

  1. User identifies component to export
  2. Agent locates source file
  3. Agent loads specification OBJECT IDs
  4. Agent generates temporary HTML with aria-label attributes in memory
  5. Agent exports to Figma via MCP
  6. Agent discards temporary HTML

Advantages:

  • Fully automated
  • No file modifications
  • No manual steps

Limitations:

  • One viewport at a time
  • Cannot capture responsive variations simultaneously

Variation B: Browser Extension Export (Multiple Viewports)

Scenario: User wants to capture mobile, tablet, and desktop viewports simultaneously using html.to.design browser extension

Process:

Step 1: Add aria-labels to Preview

Agent adds aria-label attributes to source files temporarily:

components/landing-hero.tsx:
<section aria-label="start-hero-section" className="hero-section">
  <h1 aria-label="start-hero-headline" className="hero-headline">
    Every walk. on time. Every time.
  </h1>
  <button aria-label="start-hero-cta" className="btn-cta-primary">
    Start Planning
  </button>
</section>

⚠️ IMPORTANT: These changes are temporary and will be removed after capture

Step 2: User Captures with Browser Extension

Instructions to user:

1. Open preview in browser (http://localhost:3000)
2. Activate html.to.design browser extension
3. Select multiple viewports:
   - Mobile (375px)
   - Tablet (768px)
   - Desktop (1440px)
4. Click "Capture" in extension
5. Confirm layers appear in Figma with proper OBJECT ID names
6. Notify agent when capture is complete

Step 3: Remove aria-labels from Source

Agent removes temporary aria-label attributes:

components/landing-hero.tsx:
<section className="hero-section">
  <h1 className="hero-headline">
    Every walk. on time. Every time.
  </h1>
  <button className="btn-cta-primary">
    Start Planning
  </button>
</section>

✅ Source code restored to clean state

Advantages:

  • Multiple viewports captured simultaneously
  • True responsive testing in Figma
  • Layers properly named with OBJECT IDs

Limitations:

  • ⚠️ Requires temporary file modification
  • ⚠️ Manual browser extension interaction
  • ⚠️ Must remember to remove aria-labels after capture

Safety Protocol:

Before removing aria-labels, agent asks:

"Have you completed the Figma capture with the browser extension?
I'll now remove the temporary aria-label attributes from your source files."

Wait for user confirmation before proceeding.

Variation C: Export Component States

Scenario: Export button with hover, active, disabled states

Process:

  1. Load OBJECT IDs from specification
  2. Generate HTML for each state:
    <div aria-label="button-states-showcase">
      <div class="state-container">
        <div class="state-label">Default</div>
        <button aria-label="btn-cta-primary-default">Start Planning</button>
      </div>
      <div class="state-container">
        <div class="state-label">Hover</div>
        <button aria-label="btn-cta-primary-hover">Start Planning</button>
      </div>
      <!-- More states... -->
    </div>
    
  3. Export to Figma (one page at a time)
  4. Discard temporary HTML

Variation D: Export Early Prototype

Scenario: Prototype HTML in docs/ needs design review

Process:

  1. Read prototype HTML file
  2. Check if aria-labels already present
  3. If missing, inject aria-labels with OBJECT IDs from specification
  4. Export to Figma
  5. Optionally: Update prototype file with aria-labels (user decision)

Decision Point:

The prototype HTML is missing aria-labels for Figma export.

Would you like me to:
1. Add aria-labels temporarily for this export only
2. Add aria-labels permanently to the prototype file
3. Create a specification first, then add aria-labels

Recommendation: Option 2 is best for prototypes since they're 
documentation artifacts, not production code.

Best Practices

DO

  • Always load OBJECT IDs from specifications first
  • Generate temporary HTML in memory (never save to files)
  • Preserve original component structure (only add aria-labels)
  • Export one page at a time through MCP server
  • Use specification naming conventions for consistency
  • Communicate clearly that aria-labels are temporary
  • Verify export success before discarding HTML
  • Document exports if tracking is needed

DON'T

  • Don't modify source files with temporary aria-labels (except for browser extension method)
  • Don't commit aria-label-injected code to repository
  • Don't save temporary HTML (only use for MCP export)
  • Don't skip specification lookup (always check first)
  • Don't export without aria-labels (Figma layers will have generic names)
  • Don't use generic aria-labels (follow specification patterns)

Troubleshooting

Issue: Figma Layers Have Generic Names

Cause: aria-label attributes not properly injected into HTML

Solution:

  1. Verify OBJECT IDs were loaded from specification
  2. Check aria-label injection mapping logic
  3. Ensure aria-labels added to correct elements
  4. Re-export with corrected HTML

Issue: Specification Not Found

Cause: Component doesn't have specification yet

Solution:

⚠️ No specification found for {component-name}

Options:
1. Create specification first (recommended for production components)
2. Generate temporary IDs from code structure (for quick exports)
3. Use CSS class names as IDs (fallback)

For production components, I recommend creating a specification 
to maintain design-code parity. Would you like me to create one?

Issue: aria-label Mapping Unclear

Cause: Multiple elements with same class, unclear hierarchy

Solution:

  1. Analyze component structure more carefully
  2. Use parent-child context for OBJECT ID generation
  3. Ask user for clarification on ambiguous elements
  4. Reference similar components in specifications

Integration with Existing Workflows

Works With: Figma Export Workshop

This workflow is a preprocessing step for the main Figma Export Workshop:

Prepare for Figma Export (this workflow)
  ↓ Generates HTML with aria-labels matching OBJECT IDs
Figma Export Workshop (existing)
  ↓ Validates and exports to Figma (one page at a time)
Result: Figma layers with proper OBJECT ID names

Works With: Specification-Driven Development

This workflow reinforces the specification-first approach:

1. Specification created with OBJECT IDs
2. Component implemented (without aria-labels in production)
3. Export to Figma (aria-labels injected from spec, one page at a time)
4. Design iteration in Figma (using OBJECT ID layer names)
5. Changes communicated using OBJECT IDs
6. Code updated based on OBJECT ID references

Result: Specifications remain source of truth for naming


Summary

This workflow enables clean, specification-driven Figma exports without cluttering production code:

  • Specifications remain source of truth for OBJECT IDs
  • Production code stays clean (no unnecessary aria-labels)
  • Figma layers properly named (using OBJECT IDs via aria-labels)
  • Design-code parity maintained (shared naming system)
  • Flexible for any stage (prototypes, production, previews)
  • One page at a time through MCP server (no file saving needed)

Key Principle: aria-label attributes are injected temporarily during export, then discarded. The specification-to-Figma connection is maintained without modifying source files.


Related Documentation:

Version History:

  • v1.0 (2026-01-21): Initial workflow based on ID injection strategy