webflow-code-component:pre-deploy-check
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.
Skill body
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 for required fields (
- 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
- Verify component files:
- Find all
.webflow.tsx/.webflow.tsfiles matching the glob pattern - Ensure matching React components exist
- Check for orphaned definition files
- Find all
- Validate imports in
.webflow.tsxfiles:- Must import
declareComponentfrom@webflow/react - Must import
propsfrom@webflow/data-types(if props are defined) - Must import the actual React component being declared
- Must import
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
- If
- 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
- Scan for browser-only API usage outside of
- 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)
- Verify styles are imported in
- 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
- If a component uses slots (
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
- Suggest running
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
- If project uses styled-components: verify
- 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)
- Verify
- If project uses Tailwind 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
- If project uses Sass (
- 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 Library
Running 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 WARNINGS
You can deploy, but consider fixing these issues:
1. **Modal SSR Issue**
Add to Modal.webflow.tsx:
```typescript
options: {
ssr: false
}
- CartIcon localStorage Usage
Update CartIcon.tsx:
const [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 Library
Running 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/react Fix: npm install –save-dev @webflow/react
Build Test
❌ Build Failed
Error 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: ❌ NO
Fix the following before deployment:
- Install missing dependency
npm install --save-dev @webflow/react - 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:
```typescript
import { 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.head
instead 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 containers
with 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.innerWidth
document.getElementById
localStorage.getItem
navigator.userAgent
sessionStorage.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