AgentStack
SKILL verified MIT Self-run

Webflow Code Component:convert Component

skill-webflow-webflow-skills-convert-component · by webflow

Convert an existing React component into a Webflow Code Component. Analyzes TypeScript props, maps to Webflow prop types, generates the .webflow.tsx definition file, and identifies required modifications.

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-webflow-webflow-skills-convert-component

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Webflow Code Component:convert Component? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Convert Component

Convert an existing React component into a Webflow Code Component by analyzing its structure and generating the appropriate .webflow.tsx definition file.

When to Use This Skill

Use when:

  • User has an existing React component they want to use in Webflow
  • User asks to "convert", "adapt", or "make this work with Webflow"
  • User provides a React component file and wants a Webflow definition
  • User is migrating components from another React project

Do NOT use when:

  • Creating a component from scratch (use component-scaffold)
  • User just wants to understand code components (answer directly)
  • Component is already a Webflow code component (use component-audit)

Instructions

Phase 1: Analyze Existing Component

  1. Read the React component file: Get the full source code
  1. Extract component information:
  • Component name (function/const name)
  • Props interface or type definition
  • Each prop's TypeScript type
  • Default values if defined
  • Whether component uses children
  1. Identify incompatible patterns:

| Pattern | Issue | Resolution | |---------|-------|------------| | React Context usage | Context doesn't work across Webflow components | Refactor to props or use nano stores | | window/document in render | SSR will fail | Wrap in useEffect or set ssr: false | | localStorage/sessionStorage in render | SSR will fail | Wrap in useEffect or set ssr: false | | Complex object props | Can't map to Webflow prop types | Break into individual props | | Function props (callbacks) | Not supported in Webflow | Remove or internalize logic | | useContext hook | Won't work across components | Use alternative state patterns | | External CSS imports | May not work in Shadow DOM | Import in .webflow.tsx instead | | CSS class references to global styles | Won't work in Shadow DOM | Use component-scoped styles | | styled-components | Needs Shadow DOM decorator | Set up globals.ts with decorator | | Emotion (@emotion/styled) | Needs Shadow DOM decorator | Set up globals.ts with decorator |

  1. Detect styling approach and note required setup:

If using styled-components: ``bash npm i @webflow/styled-components-utils styled-components ``

Create/update globals.ts: ``typescript import { styledComponentsShadowDomDecorator } from "@webflow/styled-components-utils"; export const decorators = [styledComponentsShadowDomDecorator]; ``

If using Emotion: ``bash npm i @webflow/emotion-utils @emotion/cache @emotion/react ``

Create/update globals.ts: ``typescript import { emotionShadowDomDecorator } from "@webflow/emotion-utils"; export const decorators = [emotionShadowDomDecorator]; ``

For both CSS-in-JS approaches, update webflow.json:

styled-components: ``json { "library": { "globals": "./src/globals.ts", "renderer": { "server": "@webflow/styled-components-utils/server" } } } ``

Emotion: ``json { "library": { "globals": "./src/globals.ts", "renderer": { "server": "@webflow/emotion-utils/server" } } } ``

  1. Flag any dependencies that might cause issues:
  • Large libraries (bundle size concern)
  • Browser-only libraries
  • Libraries that manipulate DOM directly

Phase 2: Map Props to Webflow Types

  1. Apply TypeScript → Webflow prop type mapping:

| TypeScript Type | Webflow Prop | Notes | |-----------------|--------------|-------| | string | props.Text() | Default for short text | | string (long/HTML content) | props.RichText() | If prop name suggests content/body/description | | React.ReactNode / children | props.Slot() | For nested content | | number | props.Number() | Numeric values | | boolean | props.Boolean() | Toggles | | "option1" \| "option2" | props.Variant() | String literal unions (requires options array) | | enum | props.Variant() | Convert enum values to options array (required) | | { href: string; ... } | props.Link() | Returns { href, target?, preload? } object — may need wrapper if component expects separate href/target props | | Image-related types | props.Image() | Image src, url, etc. | | string (canvas-editable text) | props.TextNode() | For text editable directly on canvas; has multiline param | | boolean (show/hide) | props.Visibility() | Semantic show/hide toggle | | string (for HTML id) | props.Id() | If prop is named "id" or used for accessibility | | Complex objects | SPLIT | Break into multiple simple props | | Functions/callbacks | REMOVE | Not supported | | Arrays | SPECIAL | May need component redesign |

  1. Handle special cases:

Complex object props - Break them down: ```typescript // Original interface Props { author: { name: string; avatar: string; bio: string; } }

// Converted to flat props props: { authorName: props.Text({ name: "Author Name" }), authorAvatar: props.Image({ name: "Author Avatar" }), authorBio: props.RichText({ name: "Author Bio" }) } ```

Union types with more than simple strings: ```typescript // Original - complex union type Size = "sm" | "md" | "lg" | { width: number; height: number };

// Convert to Variant with only string options size: props.Variant({ name: "Size", options: ["sm", "md", "lg", "custom"], defaultValue: "md" }) // Note: Custom size would need additional Number props ```

Optional props - Provide defaultValue for prop types that support it. Note: Link, Image, Slot, and Id do not accept defaultValue. ```typescript // Original interface Props { title?: string; }

// Converted - provide default for types that support it title: props.Text({ name: "Title", defaultValue: "" // Empty string or sensible default }) ```

Phase 3: Check Project Setup

  1. Verify Webflow setup exists:
  • Check for webflow.json in project root
  • Check for required dependencies (@webflow/webflow-cli, @webflow/data-types, @webflow/react)
  • If using styled-components/Emotion, check for decorator packages
  • If missing, offer to set up or direct to local-dev-setup skill
  1. Determine file locations:
  • Identify where the original component lives
  • Determine where .webflow.tsx should be created (same directory)
  • Check for existing styles that need to be imported

Phase 4: Generate Definition File

  1. Create the .webflow.tsx file:
import { declareComponent } from "@webflow/react";
import { props } from "@webflow/data-types";
import { ComponentName } from "./ComponentName";
// Import styles if they exist
import "./ComponentName.module.css"; // or .css

export default declareComponent(ComponentName, {
  name: "ComponentName",
  description: "[Generated from component purpose]",
  group: "[Appropriate category]",
  props: {
    // Mapped props here
  },
  // decorators: [], // Optional — per-component decorators (e.g., for CSS-in-JS Shadow DOM support)
  options: {
    applyTagSelectors: true, // Default is false. Set to true to apply Webflow's tag selectors (e.g., h1, p styles) inside the component.
    ssr: true // or false if browser APIs detected
  }
});
  1. Provide the complete file with all props mapped

Phase 5: Document Required Changes

  1. List modifications needed to the original component:
## Required Changes to [ComponentName].tsx

### Must Fix (Component won't work without these):
- [ ] Issue 1: [Description and how to fix]
- [ ] Issue 2: [Description and how to fix]

### Recommended (Will improve Webflow integration):
- [ ] Recommendation 1
- [ ] Recommendation 2

### Props Mapping Summary:
| Original Prop | Webflow Prop | Notes |
|---------------|--------------|-------|
| title: string | props.Text() | Direct mapping |
| isOpen: boolean | props.Boolean() | Direct mapping |
| data: object | SPLIT → dataTitle, dataValue | Flattened |
| onClick: function | REMOVED | Not supported |
  1. Provide modified component code if changes are needed:
  • Show the updated TypeScript interface
  • Show any useEffect wrappers needed for SSR
  • Show style import changes
  • Note CSS-in-JS setup requirements if applicable

Examples

Example 1: Simple Component Conversion

User prompt:

Convert this React component to work with Webflow:

// TestimonialCard.tsx
interface TestimonialCardProps {
  quote: string;
  authorName: string;
  authorTitle?: string;
  rating?: number;
}

export const TestimonialCard: React.FC = ({
  quote,
  authorName,
  authorTitle = "",
  rating = 5
}) => {
  return (
    
      {"★".repeat(rating)}
      {quote}
      
        {authorName}
        {authorTitle && {authorTitle}}
      
    
  );
};

Response:

## Component Analysis: TestimonialCard

### Props Detected:
| Prop | TypeScript Type | Webflow Mapping |
|------|-----------------|-----------------|
| quote | string | props.Text() |
| authorName | string | props.Text() |
| authorTitle | string (optional) | props.Text() |
| rating | number (optional) | props.Number() |

### Issues Found:
- **CSS class "testimonial-card"** - Uses global class that won't work in Shadow DOM
  - Fix: Convert to CSS Modules or import scoped styles

### No blocking issues - ready to convert!

---

## Generated Files

### TestimonialCard.webflow.tsx
```typescript
import { declareComponent } from "@webflow/react";
import { props } from "@webflow/data-types";
import { TestimonialCard } from "./TestimonialCard";
import "./TestimonialCard.module.css";

export default declareComponent(TestimonialCard, {
  name: "TestimonialCard",
  description: "Display customer testimonials with rating stars",
  group: "Display",
  props: {
    quote: props.Text({
      name: "Quote",
      defaultValue: "This product changed my life!"
    }),
    authorName: props.Text({
      name: "Author Name",
      defaultValue: "Jane Doe"
    }),
    authorTitle: props.Text({
      name: "Author Title",
      defaultValue: "CEO, Company"
    }),
    rating: props.Number({
      name: "Rating",
      defaultValue: 5,
      min: 1,
      max: 5
    })
  },
  options: {
    applyTagSelectors: true,
    ssr: true
  }
});

Required Changes to TestimonialCard.tsx

  1. Convert to CSS Modules - Rename TestimonialCard.css to TestimonialCard.module.css and update imports:
import styles from "./TestimonialCard.module.css";

// Default CSS Modules uses bracket notation:

// Dot notation (styles.testimonialCard) requires camelCase class names
// or a webpack override for css-loader.

Setup Check

  • [ ] Verify webflow.json exists
  • [ ] Install dependencies if needed: npm i --save-dev @webflow/webflow-cli @webflow/data-types @webflow/react

---

### Example 2: Component with Incompatible Patterns

**User prompt:**

Make this work as a Webflow code component:

// Modal.tsx import { createContext, useContext, useState } from 'react';

const ModalContext = createContext void } | null>(null);

export const useModal = () => { const context = useContext(ModalContext); if (!context) throw new Error('useModal must be used within ModalProvider'); return context; };

interface ModalProps { trigger: React.ReactNode; children: React.ReactNode; onOpen?: () => void; onClose?: () => void; }

export const Modal: React.FC = ({ trigger, children, onOpen, onClose }) => { const [isOpen, setIsOpen] = useState(false);

const toggle = () => { const newState = !isOpen; setIsOpen(newState); if (newState && onOpen) onOpen(); if (!newState && onClose) onClose(); };

useEffect(() => { if (isOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = ''; } }, [isOpen]);

return (

{trigger} {isOpen && (

e.stopPropagation()}> {children}

)}

); };


**Response:**

```markdown
## Component Analysis: Modal

### Issues Found:

| Issue | Severity | Resolution |
|-------|----------|------------|
| React Context (ModalContext) | Critical | Context won't work across Webflow components. Since this is internal to Modal, it's OK but exported useModal hook won't work. |
| document.body manipulation | Critical | SSR incompatible. Must set `ssr: false` or wrap in useEffect check. |
| onOpen/onClose callbacks | Warning | Function props not supported in Webflow. Must remove. |
| Global CSS classes | Warning | "modal-overlay", "modal-content" won't work in Shadow DOM. |

### Props Detected:
| Prop | TypeScript Type | Webflow Mapping | Status |
|------|-----------------|-----------------|--------|
| trigger | React.ReactNode | props.Slot() | OK |
| children | React.ReactNode | props.Slot() | OK |
| onOpen | function | REMOVE | Not supported |
| onClose | function | REMOVE | Not supported |

---

## Required Changes

### 1. Remove function props (onOpen, onClose)
These cannot be passed from Webflow Designer. Remove from interface and component.

### 2. Fix SSR issue with document.body
Either set `ssr: false` or add typeof check:

```typescript
useEffect(() => {
  if (typeof document === 'undefined') return;
  // ... rest of effect
}, [isOpen]);

3. Convert to CSS Modules

Rename styles and update class references.

4. Remove exported useModal hook

This won't work for external components. Keep ModalContext internal only.


Generated Files

Modal.webflow.tsx

import { declareComponent } from "@webflow/react";
import { props } from "@webflow/data-types";
import { Modal } from "./Modal";
import "./Modal.module.css";

export default declareComponent(Modal, {
  name: "Modal",
  description: "Overlay modal dialog with trigger element",
  group: "Interactive",
  props: {
    trigger: props.Slot({
      name: "Trigger"
    }),
    children: props.Slot({
      name: "Content"
    })
  },
  options: {
    applyTagSelectors: true,
    ssr: false  // Required due to document.body usage
  }
});

Updated Modal.tsx

import { useState, useEffect } from 'react';
import styles from "./Modal.module.css";

interface ModalProps {
  trigger: React.ReactNode;
  children: React.ReactNode;
  // Removed: onOpen, onClose - not supported in Webflow
}

export const Modal: React.FC = ({ trigger, children }) => {
  const [isOpen, setIsOpen] = useState(false);

  const toggle = () => setIsOpen(!isOpen);

  useEffect(() => {
    if (typeof document === 'undefined') return;

    if (isOpen) {
      document.body.style.overflow = 'hidden';
    } else {
      document.body.style.overflow = '';
    }

    return () => {
      document.body.style.overflow = '';
    };
  }, [isOpen]);

  return (
    <>
      {trigger}
      {isOpen && (
        
           e.stopPropagation()}>
            {children}
          
        
      )}
    
  );
};

Setup Required

npm i --save-dev @webflow/webflow-cli @webflow/data-types @webflow/react

---

### Example 3: Component with Complex Object Props

**User prompt:**

Convert to Webflow:

interface Product { id: string; name: string; price: number; image: string; category: 'electronics' | 'clothing' | 'home'; }

interface ProductCardProps { product: Product; showBadge?: boolean; }

export const ProductCard = ({ product, showBadge = true }: ProductCardProps) => (

{showBadge && {product.category}} {product.name} ${product.price}

);


**Response:**

```markdown
## Component Analysis: ProductCard

### Complex Props Detected:

The `product` prop is a complex object that must be flattened for Webflow:

| Original | Flattened Prop

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [webflow](https://github.com/webflow)
- **Source:** [webflow/webflow-skills](https://github.com/webflow/webflow-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.