Audit Webflow Code Components for architecture decisions - prop exposure, state management, slot opportunities, and Shadow DOM compatibility. Focused on Webflow-specific patterns, not generic React best practices.
npx skills add https://github.com/webflow/webflow-skills --skill webflow-code-component:component-audit
Audit existing code components for Webflow-specific architecture decisions. This skill focuses on how well components integrate with Webflow Designer, not generic React best practices.
Use when:
Do NOT use when:
This audit answers three questions:
For each component, analyze these Webflow-specific areas:
Goal: Identify what designers SHOULD be able to control but currently can't.
| Look For | Recommendation |
|----------|----------------|
| Hardcoded text strings | Expose as props.Text() |
| Text that designers should edit on canvas | Expose as props.RichText() |
| Hardcoded values from a fixed set of options | Expose as props.Variant({ options: [...] }) |
| Hardcoded image URLs | Expose as props.Image() |
| Hardcoded link URLs | Expose as props.Link() |
| Hardcoded HTML id attributes | Expose as props.Id() |
| Conditional rendering with boolean | Expose as props.Boolean() or props.Visibility() |
| Internal state that affects appearance | Consider exposing initial value as prop |
| children not using Slot | Convert to props.Slot() |
> Aliases: props.String = props.Text, props.Children = props.Slot. Treat these as equivalent during audit.
Questions to ask:
Goal: Identify patterns that won't work in Webflow.
| Anti-Pattern | Why It Fails | Alternative |
|--------------|--------------|-------------|
| React Context for cross-component state | Each component has isolated React root | Use nano stores, custom events, or URL params |
| Prop drilling through Slots | Slot children are separate React apps | Use nano stores or custom events |
| Shared state via module-level variables | May cause SSR issues | Use browser storage or nano stores |
| Global event listeners without cleanup | Memory leaks, SSR issues | Use useEffect with cleanup |
Refactoring recommendations:
Goal: Identify hardcoded content that should be designer-controlled.
| Current Pattern | Better Pattern |
|-----------------|----------------|
| Hardcoded button inside card | Slot for actions area |
| Hardcoded icon component | Slot or Image prop |
| Fixed header/footer structure | Slots for header and footer |
| Hardcoded list items | Consider if this should be multiple components |
When NOT to use Slots:
Goal: Ensure styles work in isolation.
| Issue | Detection | Fix |
|-------|-----------|-----|
| Using site/global CSS classes | Class names like .container, .btn | Use CSS Modules or component-scoped styles |
| CSS-in-JS not configured | styled-components/Emotion without decorator | Add globals.ts with styledComponentsShadowDomDecorator (styled-components) or emotionShadowDomDecorator (Emotion/MUI) |
| Missing style imports | Styles defined but not imported in .webflow.tsx | Add import statement |
| Relying on inherited styles | Expecting parent styles to cascade | Use explicit styles or CSS variables |
| Needs tag selectors (h1, p, etc.) | Tags not styled inside Shadow DOM | Enable applyTagSelectors: true in component options |
> SSR Note: When using styled-components or Emotion, you must also configure the server renderer in webflow.json for SSR to work correctly:
> - styled-components: "library": { "renderer": { "server": "@webflow/styled-components-utils/server" } }
> - Emotion: "library": { "renderer": { "server": "@webflow/emotion-utils/server" } }
Goal: Identify browser-only code that runs during render.
| Pattern | Problem | Solution |
|---------|---------|----------|
| window.innerWidth in render | SSR error | Use useEffect or set ssr: false |
| document.getElementById in render | SSR error | Use useEffect or refs |
| localStorage.getItem outside useEffect | SSR error | Wrap in useEffect with useState |
| Third-party library that requires window | SSR error | Dynamic import or ssr: false |
Goal: Determine if component is at the right level of abstraction.
Signs a component should be SPLIT:
Signs components should be COMBINED:
Generate actionable report with:
| Check | Question |
|-------|----------|
| Prop completeness | Can designers customize everything they'd want to? |
| Prop types | Are the right Webflow prop types used? |
| Default values | Do props have sensible defaults? |
| Prop naming | Are names clear for non-developers? |
| Slot usage | Is nested content handled via Slots? |
| Visibility props | Can sections be shown/hidden? |
| Check | Question |
|-------|----------|
| SSR safe | Does component render without browser APIs? |
| Style isolation | Do styles work in Shadow DOM? |
| State independence | Does component work without Context from parent? |
| No function props | Are there callback props that won't work? |
| Check | Question |
|-------|----------|
| Single responsibility | Does component do one thing well? |
| Right granularity | Is this the right size for Designer use? |
| Cross-component state | If needed, is it implemented correctly? |
User prompt:
Audit my ProductCard component
Response:
## Audit: ProductCard
### Component Overview
// Current props
props: {
title: props.Text(),
price: props.Number(),
imageUrl: props.Text() // ⚠️ Should be Image
}
---
### A. Prop Exposure Analysis
| Finding | Severity | Recommendation |
|---------|----------|----------------|
| `imageUrl` is Text, not Image | Warning | Change to `props.Image()` for proper asset handling |
| "Add to Cart" button text is hardcoded | Suggestion | Expose as prop: `addToCartText: props.Text()` |
| Sale badge is conditionally rendered but not controllable | Suggestion | Add `showSaleBadge: props.Boolean()` |
| Badge color is hardcoded red | Suggestion | Add `badgeVariant: props.Variant({ options: ["sale", "new", "featured"] })` |
**Hardcoded Content Found:**
// Line 24 - hardcoded, should be prop
<button>Add to Cart</button>
// Line 18 - hardcoded, should be prop or removed
{onSale && <span className="badge">SALE</span>}
**Recommended Props to Add:**
props: {
// ...existing
addToCartLabel: props.Text({
name: "Button Label",
defaultValue: "Add to Cart"
}),
showBadge: props.Boolean({
name: "Show Badge",
defaultValue: false
}),
badgeType: props.Variant({
name: "Badge Type",
options: ["sale", "new", "featured"],
defaultValue: "sale"
})
}
---
### B. State Management
| Finding | Severity |
|---------|----------|
| Uses `localStorage` for cart count | Warning |
| No React Context dependencies | OK |
**Issue: localStorage in render**
// Line 8 - will break SSR
const cartCount = localStorage.getItem('cart');
**Fix:**
const [cartCount, setCartCount] = useState(0);
useEffect(() => {
setCartCount(parseInt(localStorage.getItem('cart') || '0'));
}, []);
---
### C. Slot Opportunities
| Current | Recommendation |
|---------|----------------|
| Hardcoded button | Consider: `actions: props.Slot()` for flexible CTAs |
If designers need to put different content (button, link, custom element) in the action area:
props: {
actions: props.Slot({
name: "Actions"
})
}
// Component
<div className={styles.actions}>
{actions}
</div>
**However**, if button behavior is tied to cart logic, keep it hardcoded.
---
### D. Shadow DOM Compatibility
| Check | Status |
|-------|--------|
| Styles imported in .webflow.tsx | ✅ OK |
| CSS Modules used | ✅ OK |
| No global class references | ✅ OK |
---
### E. SSR Safety
| Check | Status |
|-------|--------|
| window usage | ✅ None |
| document usage | ✅ None |
| localStorage usage | ⚠️ Needs guard (see fix above) |
---
### F. Component Granularity
**Current size**: 4 props (will be 7 after recommendations)
**Verdict**: Good granularity - single purpose, manageable props
---
## Summary
| Category | Status |
|----------|--------|
| Designer Control | ⚠️ Needs work - 4 hardcoded items found |
| State Management | ⚠️ localStorage needs SSR guard |
| Shadow DOM | ✅ Good |
| SSR Safety | ⚠️ One issue |
| Granularity | ✅ Good |
**Priority Actions:**
1. Fix localStorage SSR issue (blocks deployment)
2. Change imageUrl from Text to Image prop
3. Expose badge controls as props
4. Consider exposing button label
This is not a generic code quality audit. Skip:
Focus only on Webflow-specific concerns.
Should be a prop:
Should NOT be a prop:
Use Slot when:
Use Props when:
If components need to share state, recommend in this order:
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling
Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification
Take webflow/webflow-code-component:component-audit from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.