From webflow-code-component-skills
Generates Webflow Code Component boilerplate with React component, .webflow.tsx definition file, and optional styling. Checks prerequisites and sets up missing webflow.json/config/dependencies.
npx claudepluginhub webflow/webflow-skills --plugin webflow-code-component-skillsThis skill uses the workspace's default tool permissions.
Generate a new Webflow Code Component with proper file structure, React component, and `.webflow.tsx` definition file.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Generate a new Webflow Code Component with proper file structure, React component, and .webflow.tsx definition file.
Use when:
Do NOT use when:
Note: This skill can handle basic setup (webflow.json + dependencies) automatically. Use local-dev-setup only for complex setups requiring Tailwind, custom webpack config, or monorepo configurations.
Before gathering any requirements, verify the project is set up for Webflow Code Components:
Check for webflow.json:
# Look for webflow.json in project root
Check for required dependencies in package.json:
{
"devDependencies": {
"@webflow/webflow-cli": "...",
"@webflow/data-types": "...",
"@webflow/react": "..."
}
}
npm i --save-dev @webflow/webflow-cli @webflow/data-types @webflow/react
Check for components directory:
src/components/)Report setup status:
If all prerequisites met:
✅ Project ready for code components
- webflow.json: Found
- Dependencies: Installed
- Components path: src/components/
Let's create your component...
If prerequisites missing:
⚠️ Project Setup Required
Missing:
- [ ] webflow.json configuration file
- [ ] @webflow/webflow-cli dependency
- [ ] @webflow/data-types dependency
- [ ] @webflow/react dependency
Would you like me to:
1. Set up the missing items now (quick setup)
2. Run full project initialization (local-dev-setup skill)
Choose an option:
Quick setup creates minimal config:
// webflow.json
{
"library": {
"name": "My Component Library",
"components": ["./src/components/**/*.webflow.tsx"]
}
}
And installs dependencies.
Optional: webflow.json also supports a "globals" field pointing to a globals file (e.g., "globals": "./src/globals.webflow.ts"). The globals file is used for global CSS imports (e.g., Tailwind) and exporting decorator arrays. Add this when using styled-components, Emotion, or Tailwind.
Only proceed to Phase 1 after prerequisites are confirmed.
Get component name: Ask user for the component name
Determine component type: Ask what kind of component
Identify props needed: Based on component type, suggest props
props.Text() or props.RichText()props.TextNode()props.Image()props.Link()props.Number()props.Variant()props.Slot()props.Boolean()props.Visibility()props.Id()Styling approach: Ask preferred styling method
SSR requirements: Determine if component needs client-only features
ssr: falsessr: true (default)Check project structure:
webflow.json existsCheck for conflicts:
.webflow.tsx file with same namesrc/components/[ComponentName]/
├── [ComponentName].tsx
├── [ComponentName].webflow.tsx
└── [ComponentName].module.css (if CSS Modules)
[ComponentName].tsx):import React from "react";
import styles from "./[ComponentName].module.css";
export interface [ComponentName]Props {
// Props interface based on user requirements
}
export const [ComponentName]: React.FC<[ComponentName]Props> = ({
// Destructured props with defaults
}) => {
return (
<div className={styles.container}>
{/* Component JSX */}
</div>
);
};
[ComponentName].webflow.tsx):import { declareComponent } from "@webflow/react";
import { props } from "@webflow/data-types";
import { [ComponentName] } from "./[ComponentName]";
import "./[ComponentName].module.css";
export default declareComponent([ComponentName], {
name: "[ComponentName]",
description: "[User-provided or generated description]",
group: "[Category]",
props: {
// Props configuration based on requirements
},
options: {
applyTagSelectors: true,
ssr: true // or false based on requirements
}
});
Note on decorators: declareComponent also accepts an optional decorators array for wrapping components with providers. Built-in decorators include styledComponentsShadowDomDecorator (for styled-components) and emotionShadowDomDecorator (for Emotion). Global decorators can be exported from a globals file referenced in webflow.json — see the globals file note below.
.container {
/* Base styles */
}
Show created files: List all files created with paths
Explain next steps:
npm run dev)npx webflow library shareShadow DOM awareness:
Note: Code components run inside Shadow DOM. Site-level CSS classes won't work
inside your component. Use component-scoped styles (CSS Modules, etc.).
Site CSS variables DO work — use var(--variable-name, fallback).
⚠️ Important: Do not rename the .webflow.tsx file after deployment.
Renaming creates a new component and breaks existing instances.
User prompt:
Create an accordion component
Step 1: Requirements Gathering
📦 New Component: Accordion
I'll create an accordion component. Let me confirm the requirements:
**Props to include:**
1. `title` (Text) - The accordion header text
2. `content` (Rich Text) - The expandable content
3. `defaultOpen` (Boolean) - Whether to start expanded
4. `icon` (Variant) - Chevron style: "arrow" | "plus" | "none"
**Styling:** CSS Modules (recommended for Shadow DOM)
**SSR:** Enabled (no browser-only APIs needed)
Does this look right? Any props to add or remove?
Step 2: After User Confirms
📁 Creating Component Files...
Created:
├── src/components/Accordion/Accordion.tsx
├── src/components/Accordion/Accordion.webflow.tsx
└── src/components/Accordion/Accordion.module.css
✅ Component scaffold complete!
---
**Accordion.tsx** - React component with:
- Props: title, content, defaultOpen, icon
- State management for open/closed
- Accessible keyboard navigation
- CSS Module classes
**Accordion.webflow.tsx** - Webflow definition with:
- All props configured for Designer editing
- Default values set
- SSR enabled
---
💡 Next Steps:
1. Review and customize the generated code
2. Test locally by running your React project (e.g., `npm run dev`)
3. Deploy to Webflow: `npx webflow library share`
⚠️ Remember: Don't rename .webflow.tsx files after deployment!
Generated Accordion.tsx:
import React, { useState } from "react";
import styles from "./Accordion.module.css";
export interface AccordionProps {
title: string;
content: string;
defaultOpen?: boolean;
icon?: "arrow" | "plus" | "none";
}
export const Accordion: React.FC<AccordionProps> = ({
title,
content,
defaultOpen = false,
icon = "arrow"
}) => {
const [isOpen, setIsOpen] = useState(defaultOpen);
return (
<div className={styles.accordion}>
<button
className={styles.header}
onClick={() => setIsOpen(!isOpen)}
aria-expanded={isOpen}
>
<span className={styles.title}>{title}</span>
{icon !== "none" && (
<span className={`${styles.icon} ${isOpen ? styles.open : ""}`}>
{icon === "arrow" ? "▼" : "+"}
</span>
)}
</button>
{isOpen && (
<div
className={styles.content}
dangerouslySetInnerHTML={{ __html: content }}
/>
)}
</div>
);
};
Generated Accordion.webflow.tsx:
import { declareComponent } from "@webflow/react";
import { props } from "@webflow/data-types";
import { Accordion } from "./Accordion";
import "./Accordion.module.css";
export default declareComponent(Accordion, {
name: "Accordion",
description: "Expandable content section with customizable header and icon",
group: "Interactive",
props: {
title: props.Text({
name: "Title",
defaultValue: "Accordion Title"
}),
content: props.RichText({
name: "Content",
defaultValue: "<p>Accordion content goes here.</p>"
}),
defaultOpen: props.Boolean({
name: "Start Expanded",
defaultValue: false
}),
icon: props.Variant({
name: "Icon Style",
options: ["arrow", "plus", "none"],
defaultValue: "arrow"
})
},
options: {
applyTagSelectors: true,
ssr: true
}
});
| User Wants | Prop Type | Notes |
|---|---|---|
| Editable text | props.Text() | Single line, max 256 chars |
| Long formatted text | props.RichText() | HTML content |
| Canvas-editable text | props.TextNode() | Double-click to edit |
| Image upload | props.Image() | Returns image object |
| URL/link | props.Link() | Returns { href, target, preload } |
| Number input | props.Number() | Numeric values |
| Toggle/flag | props.Boolean() | true/false |
| Style options | props.Variant() | Dropdown selection |
| Nested content | props.Slot() | Other components inside |
| HTML ID | props.Id() | For accessibility |
Set ssr: false if ANY of these apply:
1. Browser APIs — Uses window, document, localStorage, or similar
2. Dynamic/personalized content — User-specific dashboards, authenticated views, client data
3. Heavy/interactive UI — Charts, 3D scenes, maps, animation-driven elements
4. Non-deterministic output — Random numbers, time-based values, anything that renders differently server vs client
Otherwise → Keep ssr: true (default)
ProductCard)ProductCard.tsx, ProductCard.webflow.tsxProductCard.module.csssrc/components/ProductCard/Always provide meaningful defaults:
props: {
title: props.Text({
name: "Title",
defaultValue: "Card Title" // ✅ Good
}),
count: props.Number({
name: "Count",
defaultValue: 0 // ✅ Good
})
}
Not:
props: {
title: props.Text({
name: "Title"
// ❌ Missing defaultValue
})
}
Component name already exists:
⚠️ Component "Button" already exists at src/components/Button/
Options:
1. Choose a different name
2. Update existing component (use component-audit skill)
3. Delete existing and create new
Which would you like to do?
Missing webflow.json:
❌ No webflow.json found in project root
This file is required for code components. Would you like me to:
1. Create a basic webflow.json
2. Run local-dev-setup skill for full project initialization
Choose an option (1/2):
Invalid component name:
⚠️ Invalid component name: "my-button"
Component names must be:
- PascalCase (e.g., "MyButton")
- Start with a letter
- Contain only letters and numbers
Suggested name: "MyButton"
Use this name? (yes/no)