Skill v1.0.1
currentAutomated scan100/1003 files
version: "1.0.1" name: webflow-code-component:pre-deploy-check description: Pre-deployment validation for Webflow Code Components. Checks bundle size, dependencies, prop configurations, SSR compatibility, styling setup, and common issues before running webflow library share. compatibility: Node.js 18+, React 18+, TypeScript, @webflow/webflow-cli metadata: author: webflow version: "1.1"
Build Validate
Validate code components before deployment to catch issues early.
When to Use This Skill
Use when:
- User is about to deploy and wants to check for issues first
- Proactively before running
webflow library share - User asks to validate, check, or verify their components
- After making significant changes to components
Do NOT use when:
- Deployment already failed (use troubleshoot-deploy instead)
- Just building for local development
- Auditing code quality (use component-audit instead)
Instructions
Phase 1: Project Structure Check
- Verify webflow.json exists:
- Check for required fields (
library.name,library.components) - Validate glob pattern matches component files — the recommended pattern is
"./src/**/*.webflow.@(js|jsx|mjs|ts|tsx)"covering all supported extensions - Check
globalspath if specified — file must exist and be importable - Check
bundleConfigpath if specified — file must exist
- Check dependencies:
- Verify
@webflow/webflow-cliinstalled - Verify
@webflow/data-typesinstalled - Verify
@webflow/reactinstalled - Check for version compatibility (check installed versions, don't assume specific versions)
- Verify component files:
- Find all
.webflow.tsx/.webflow.tsfiles matching the glob pattern - Ensure matching React components exist
- Check for orphaned definition files
- Validate imports in `.webflow.tsx` files:
- Must import
declareComponentfrom@webflow/react - Must import
propsfrom@webflow/data-types(if props are defined) - Must import the actual React component being declared
Phase 2: Component Analysis
- For each component, check:
declareComponentis called with the component and a config objectnameis provided in the config- All props have
nameproperties and appropriatedefaultValuewhere applicable - Prop types are valid — the 11 supported types are:
- Text (alias: String) — single line text input
- RichText — multi-line text with formatting
- TextNode — single/multi-line text editable on canvas
- Link — URL input (returns
{ href, target, preload }object) - Image — image upload and selection
- Number — numeric input
- Boolean — true/false toggle
- Variant — dropdown with predefined options (requires
optionsarray) - Visibility — show/hide controls
- Slot — content areas for child components
- ID — HTML element ID
- Validate component options:
- If
optionsobject is present, validate: applyTagSelectorsis a boolean (default:false) — enables site tag selectors in Shadow DOMssris a boolean (default:true) — controls server-side rendering
- Check for SSR issues:
- Scan for browser-only API usage outside of
useEffector guarded blocks: window,document,localStorage,sessionStorage,navigator- Flag dynamic/personalized content patterns (user-specific dashboards, authenticated views)
- Flag heavy/interactive UI that doesn't benefit from SSR (charts, 3D scenes, maps, animation-heavy elements)
- Flag non-deterministic output (random numbers, time-based values that differ server vs client)
- Suggest
ssr: falsein options if component is purely interactive or browser-dependent
- Check styling:
- Verify styles are imported in
.webflow.tsxor via globals file - Check for site class usage — site classes do NOT work in Shadow DOM
- Site variables DO work:
var(--variable-name, fallback) - Inherited CSS properties DO work:
font-family: inherit - Tag selectors work IF
applyTagSelectors: trueis set in component options - Validate CSS-in-JS setup if used (see CSS-in-JS detection below)
- Check for Shadow DOM + React Context issues:
- If a component uses slots (
props.Slot) AND imports/usesuseContextor a Context Provider: - Warn that parent and child components in slots cannot share React Context — each child renders in its own Shadow DOM with a separate React root
- Suggest alternatives: Nano Stores, custom events, URL parameters, or browser storage
Phase 3: Build Test
- Run TypeScript/build check:
- Check for TypeScript compilation errors
- Verify all imports resolve correctly
- Identify any build-time issues
- Check bundle size:
- If a build output exists, verify total bundle size is under 50MB (maximum bundle limit)
- If over limit, flag as error and suggest optimization
- Run local bundle test (optional, suggest to user):
- Suggest running
npx webflow library bundle --public-path http://localhost:4000/to test bundling before sharing - If bundling issues occur, suggest
--debug-bundlerflag to inspect the final webpack config
Phase 4: Detect Framework-Specific Setup
- CSS-in-JS library detection:
- If project uses styled-components: verify
@webflow/styled-components-utilsis installed andstyledComponentsShadowDomDecoratoris exported from globals decorators array - If project uses Emotion or Material UI (
@emotion/styled,@emotion/react,@mui/material): verify@webflow/emotion-utilsis installed andemotionShadowDomDecoratoris exported from globals decorators array
- Tailwind CSS detection:
- If project uses Tailwind CSS (
tailwindcssin dependencies): - Verify
@tailwindcss/postcssis installed - Verify
postcss.config.mjsexists with@tailwindcss/postcssplugin - Verify Tailwind CSS is imported in globals file (e.g.,
@import "tailwindcss"in globals.css)
- Sass/Less preprocessor detection:
- If project uses Sass (
.scssfiles orsassin dependencies): verifysassandsass-loaderare installed, and a webpack config adds the.scssrule - If project uses Less (
.lessfiles orlessin dependencies): verifylessandless-loaderare installed, and a webpack config adds the.lessrule - For either: verify
bundleConfigis set inwebflow.jsonpointing to the webpack config
- Webpack custom config validation (if
bundleConfigis specified):
- Verify the file exists at the specified path
- Verify it uses CommonJS exports (
module.exports) - Warn if it attempts to override blocked properties:
entry,output,target(these are silently filtered out) - Verify
module.rulesuses function syntax(currentRules) => { ... }, not an array
Phase 5: Report Results
- Generate validation report:
- List all checks performed
- Show passed/failed/warning status
- Provide fix suggestions for failures
- Indicate deployment readiness
Validation Checks
Required Checks
| Check | Severity | Description | |
|---|---|---|---|
| webflow.json exists | Error | Required for CLI | |
| Dependencies installed | Error | @webflow/webflow-cli, @webflow/data-types, @webflow/react | |
| Component files exist | Error | React + definition files present | |
| declareComponent called | Error | Required in .webflow.tsx with correct imports | |
| Valid prop types | Error | Only the 11 supported types (Text/String, RichText, TextNode, Link, Image, Number, Boolean, Variant, Visibility, Slot, ID) | |
| Build succeeds | Error | No compilation errors | |
| Bundle size < 50MB | Error | Maximum bundle limit enforced by Webflow |
Warning Checks
| Check | Severity | Description | |
|---|---|---|---|
| Props have defaults | Warning | Better designer experience | |
| SSR compatibility | Warning | Browser APIs, dynamic content, heavy UI, non-deterministic output | |
| Styles imported | Warning | Styles may not appear in Shadow DOM | |
| Site class usage | Warning | Site classes don't work in Shadow DOM — use component-specific classes | |
| Shadow DOM + Context | Warning | Slots prevent React Context sharing between parent/child | |
| CSS-in-JS decorator | Warning | styled-components/Emotion need Shadow DOM decorators | |
| Tailwind setup | Warning | Missing postcss config or globals import | |
| Sass/Less setup | Warning | Missing loaders or webpack config | |
| Webpack blocked props | Warning | entry, output, target overrides are silently ignored | |
| Webpack rules format | Warning | Must use function syntax, not array | |
| Component options | Warning | applyTagSelectors and ssr must be booleans | |
| Glob pattern coverage | Warning | Pattern should cover all supported extensions (.js, .jsx, .mjs, .ts, .tsx) | |
| bundleConfig file | Warning | File must exist if specified in webflow.json |
Info Checks
| Check | Severity | Description | |
|---|---|---|---|
| Component count | Info | Number of components | |
| Prop count | Info | Props per component | |
| Bundle size | Info | Current bundle size vs 50MB limit | |
| Frameworks detected | Info | CSS-in-JS, Tailwind, Sass/Less usage |
Examples
User prompt:
Check if my components are ready to deploy
Response:
🔍 Build Validation: My Component LibraryRunning pre-deployment checks...---## Project Structure✅ webflow.json found✅ library.name: "My Component Library"✅ library.components: "./src/**/*.webflow.@(js|jsx|mjs|ts|tsx)"✅ globals: "./src/globals.ts"✅ bundleConfig: not specified (using defaults)---## Dependencies✅ @webflow/webflow-cli: installed✅ @webflow/data-types: installed✅ @webflow/react: installed✅ react: installed✅ typescript: installed---## Frameworks Detected✅ Tailwind CSS detected✅ @tailwindcss/postcss installed✅ postcss.config.mjs found✅ globals.css imports Tailwind---## Components Found (4)### 1. Button ✅- File: src/components/Button/Button.webflow.tsx- Imports: ✅ declareComponent, ✅ props, ✅ Button component- Props: label (Text), variant (Variant), disabled (Boolean)- All props have defaults ✅- SSR compatible ✅- Options: applyTagSelectors: true ✅- Styles imported ✅### 2. Card ✅- File: src/components/Card/Card.webflow.tsx- Imports: ✅ declareComponent, ✅ props, ✅ Card component- Props: title (Text), image (Image), content (RichText), link (Link)- All props have defaults ✅- SSR compatible ✅- Styles imported ✅### 3. Modal ⚠️- File: src/components/Modal/Modal.webflow.tsx- Imports: ✅ declareComponent, ✅ props, ✅ Modal component- Props: title (Text), isOpen (Boolean), content (Slot)- All props have defaults ✅- ⚠️ SSR Issue: Uses `document.body` in render→ Suggestion: Add `ssr: false` to options or wrap in useEffect- Styles imported ✅### 4. CartIcon ⚠️- File: src/components/CartIcon/CartIcon.webflow.tsx- Imports: ✅ declareComponent, ✅ CartIcon component- Props: none- ⚠️ Missing props - component has no editable properties→ Suggestion: Consider adding props for designer customization- ⚠️ Uses localStorage without SSR guard→ Suggestion: Wrap in useEffect or useState initializer- Styles imported ✅---## Build Test✅ Build completed successfully✅ No TypeScript errors✅ No webpack errors✅ Bundle size: 2.3MB / 50MB limit---## Summary| Category | Status ||----------|--------|| Project Structure | ✅ Pass || Dependencies | ✅ Pass || Frameworks | ✅ Pass || Components | ⚠️ 2 warnings || Build | ✅ Pass |---## Ready to Deploy: ⚠️ WITH WARNINGSYou can deploy, but consider fixing these issues:1. **Modal SSR Issue**Add to Modal.webflow.tsx:```typescriptoptions: {ssr: false}```2. **CartIcon localStorage Usage**Update CartIcon.tsx:```typescriptconst [count, setCount] = useState(() => {if (typeof window === "undefined") return 0;return parseInt(localStorage.getItem("cartCount") || "0");});```---💡 To deploy: `npx webflow library share`💡 To test locally first: `npx webflow library bundle --public-path http://localhost:4000/`
Example: Build Failure
🔍 Build Validation: My Component LibraryRunning pre-deployment checks...---## Project Structure✅ webflow.json found⚠️ library.components uses narrow glob: "./src/**/*.webflow.tsx"→ Recommendation: Use "./src/**/*.webflow.@(js|jsx|mjs|ts|tsx)" to cover all supported extensions---## Dependencies❌ Missing: @webflow/reactFix: npm install --save-dev @webflow/react---## Build Test❌ Build FailedError in src/components/Button/Button.webflow.tsx:
Module not found: Error: Can't resolve '@webflow/react'
---## Summary| Category | Status ||----------|--------|| Dependencies | ❌ 1 error || Build | ❌ Failed |---## Ready to Deploy: ❌ NOFix the following before deployment:1. **Install missing dependency**```bashnpm install --save-dev @webflow/react```2. **Re-run validation**After installing, run this check again.
Example: CSS-in-JS Missing Decorator
🔍 Build Validation: My Component Library---## Frameworks Detected⚠️ styled-components detected but Shadow DOM decorator not configured→ Install: npm install @webflow/styled-components-utils→ Add to globals.ts:```typescriptimport { styledComponentsShadowDomDecorator } from "@webflow/styled-components-utils";export const decorators = [styledComponentsShadowDomDecorator];```→ Reference globals in webflow.json:```json{ "library": { "globals": "./src/globals.ts" } }```Without this, styled-components styles will be injected into document.headinstead of the Shadow DOM, and your components will appear unstyled.
Example: Webpack Config Issues
🔍 Build Validation: My Component Library---## Webpack Configuration⚠️ webpack.webflow.js: `module.rules` uses array syntax→ Must use function syntax: `rules: (currentRules) => { return [...]; }`→ Array syntax will not work — the function receives current rules to extend⚠️ webpack.webflow.js: overrides `output` property→ The `output` property is blocked and will be silently ignored→ Blocked properties: entry, output, target💡 Use `--debug-bundler` flag to inspect the final merged webpack config:npx webflow library bundle --debug-bundler
Example: Shadow DOM Context Warning
## Components Found (2)### 1. ThemeProvider ⚠️- File: src/components/ThemeProvider/ThemeProvider.webflow.tsx- Props: theme (Variant), children (Slot)- ⚠️ Shadow DOM + React Context Issue:Component uses Slot prop AND React Context (ThemeContext).Children placed in slots render in separate Shadow DOM containerswith their own React roots — they cannot access this Context.Alternatives for cross-component state:- Nano Stores (lightweight reactive state)- Custom events (window.dispatchEvent/addEventListener)- URL parameters (for shareable state)- Browser storage (localStorage/sessionStorage)
Guidelines
Validation Order
Run checks in this order for efficiency:
- Project structure (fast, catches obvious issues)
- Dependencies (medium, required for build)
- Component analysis (medium, catches code issues)
- Framework detection (medium, validates CSS-in-JS/Tailwind/Sass setup)
- Build test (slow, but required)
SSR Detection Patterns
Look for these patterns that indicate SSR issues:
// Direct browser API usage (will break SSR)window.innerWidthdocument.getElementByIdlocalStorage.getItemnavigator.userAgentsessionStorage.getItem// Dynamic/personalized content (may cause hydration mismatch)// User-specific dashboards, authenticated views// Heavy/interactive UI (SSR adds no value, re-renders anyway)// Charts, 3D scenes, maps, animation-driven elements// Non-deterministic output (differs server vs client)Math.random()new Date().toLocaleString()// Safe patterns (in useEffect or state initializer)useEffect(() => {// Browser APIs here are fine}, []);useState(() => {if (typeof window === "undefined") return default;return window.innerWidth;});
When SSR issues are found, prominently suggest the ssr: false option:
export default declareComponent(MyComponent, {name: "My Component",options: {ssr: false // Disables server-side rendering},});
CSS-in-JS / Tailwind / Preprocessor Detection
Check project dependencies and files to detect styling frameworks:
styled-components:
- Detect:
styled-componentsin package.json dependencies - Require:
@webflow/styled-components-utilsinstalled - Require:
styledComponentsShadowDomDecoratorin globals decorators array
Emotion / Material UI:
- Detect:
@emotion/styled,@emotion/react, or@mui/materialin dependencies - Require:
@webflow/emotion-utilsinstalled - Require:
emotionShadowDomDecoratorin globals decorators array
Tailwind CSS:
- Detect:
tailwindcssin dependencies - Require:
@tailwindcss/postcssinstalled - Require:
postcss.config.mjswith@tailwindcss/postcssplugin - Require: Tailwind import in globals CSS (
@import "tailwindcss")
Sass:
- Detect:
.scssfiles in src orsassin dependencies - Require:
sassandsass-loaderinstalled as dev dependencies - Require: webpack config with
.scssrule using function syntax for module.rules - Require:
bundleConfigset in webflow.json
Less:
- Detect:
.lessfiles in src orlessin dependencies - Require:
lessandless-loaderinstalled as dev dependencies - Require: webpack config with
.lessrule using function syntax for module.rules - Require:
bundleConfigset in webflow.json
Webpack Config Validation Rules
When bundleConfig is specified in webflow.json:
- File must exist at the specified path
- Must use CommonJS:
module.exports = { ... } - Blocked properties that are silently ignored:
entry,output,target module.rulesmust be a function, not an array:rules: (currentRules) => { ... }ModuleFederationPluginandMiniCssExtractPluginare auto-deduplicated
Common Build Errors
| Error | Cause | Fix | |
|---|---|---|---|
| "Can't resolve '@webflow/react'" | Missing dependency | npm i -D @webflow/react | |
| "Cannot find module './Component'" | Wrong import path | Check relative paths | |
| "Type 'X' is not assignable" | TypeScript error | Fix type mismatch | |
| "Unexpected token" | Syntax error | Check JSX/TS syntax | |
| "Maximum call stack" | Circular import | Break dependency cycle | |
| Bundle exceeds 50MB | Too many/large dependencies | Tree-shake, lazy load, replace heavy libs | |
| Styles not appearing | Missing Shadow DOM decorator | Add CSS-in-JS decorator or import styles in .webflow.tsx |
Bundle Size Optimization
Quick wins for reducing bundle size:
- Use production build: Ensure minification is enabled
- Tree-shake imports: Import specific exports
- Replace heavy libraries: moment → date-fns, lodash → lodash-es
- Lazy load: Dynamic imports for heavy components
- Check for duplicates: Multiple React versions, etc.
- Monitor size: Bundle must stay under 50MB limit