Common Mistakes That Break Site Editor Functionality
1. Incorrect useBlockProps Implementation
❌ WRONG:
export default function Edit({ attributes, setAttributes }) {
const blockProps = useBlockProps(); // Called but not properly configured
return (
<aside className="my-custom-classes"> {/* Classes added directly */}
<InspectorControls>...</InspectorControls>
{/* Block content */}
</aside>
);
}
✅ CORRECT:
export default function Edit({ attributes, setAttributes }) {
const blockProps = useBlockProps({
className: 'my-custom-classes' // Pass classes to useBlockProps
});
return (
<>
<InspectorControls>...</InspectorControls>
<aside {...blockProps}> {/* Spread blockProps on main element */}
{/* Block content */}
</aside>
</>
);
}
2. Variable Declaration Order
❌ WRONG:
export default function Edit({ attributes, setAttributes }) {
const blockProps = useBlockProps(); // Declared after destructuring
const { numberOfPosts = 6 } = attributes;
}
✅ CORRECT:
export default function Edit({ attributes, setAttributes }) {
const { numberOfPosts = 6 } = attributes;
const blockProps = useBlockProps(); // Hooks after regular variables
}
3. Missing React Fragment Wrapper
❌ WRONG:
return (
<InspectorControls>...</InspectorControls>
<div {...blockProps}>...</div>
);
✅ CORRECT:
return (
<>
<InspectorControls>...</InspectorControls>
<div {...blockProps}>...</div>
</>
);
Essential Checklist for Site Editor Compatible Blocks
1. Block Structure Requirements
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
export default function Edit({ attributes, setAttributes }) {
// 1. Destructure attributes first
const { someAttribute = 'default' } = attributes;
// 2. Call hooks after regular variables
const blockProps = useBlockProps({
className: 'your-custom-classes',
// Other props as needed
});
// 3. Data fetching hooks
const data = useSelect(/* ... */);
// 4. Return with proper structure
return (
<>
{/* Inspector Controls outside main element */}
<InspectorControls>
<PanelBody title={__('Settings', 'textdomain')}>
{/* Controls */}
</PanelBody>
</InspectorControls>
{/* Main block element with blockProps */}
<div {...blockProps}>
{/* Block content */}
</div>
</>
);
}
2. block.json Requirements
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3, // MUST be 3 for modern features
"name": "namespace/block-name",
"version": "1.0.0",
"title": "Block Title",
"category": "widgets",
"icon": "star-filled",
"description": "Block description",
"example": {}, // Helps with block preview
"supports": {
"html": false,
"align": ["wide", "full"],
"anchor": true,
"className": true,
"spacing": {
"margin": true,
"padding": true
}
},
"textdomain": "your-textdomain",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php",
"attributes": {
// Your attributes
}
}
3. index.js Registration
import { registerBlockType } from '@wordpress/blocks';
import Edit from './edit';
import metadata from './block.json';
registerBlockType(metadata.name, {
...metadata,
edit: Edit,
save: () => null, // For dynamic blocks
});
Testing Protocol
1. Test in Both Editors
- ✅ Test in Post Editor first
- ✅ Test in Site Editor/Template Editor
- ✅ Test when block is hardcoded in template files
2. Clear Cache Between Tests
- Browser cache: Ctrl+F5 / Cmd+Shift+R
- WordPress cache if using caching plugins
- Run
npm run build
after changes
3. Check Console for Errors
- Open browser DevTools (F12)
- Look for JavaScript errors
- Check Network tab for failed resource loads
Template File Usage
When adding blocks to template files:
<!-- wp:namespace/block-name {"attribute":"value","showHeader":true} /-->
Or with inner content:
<!-- wp:namespace/block-name {"attribute":"value"} -->
<div class="wp-block-namespace-block-name">
<!-- Default content -->
</div>
<!-- /wp:namespace/block-name -->
Common Site Editor Issues and Solutions
Issue: Block settings don’t appear in Site Editor
Solution:
- Ensure
useBlockProps()
is properly implemented - Verify
apiVersion: 3
in block.json - Use React Fragments (
<>...</>
) to wrap multiple elements
Issue: Block appears broken after adding to template
Solution:
- Delete the block instance
- Clear browser cache
- Re-add the block fresh
Issue: Attributes not saving in Site Editor
Solution:
- Check attribute definitions in block.json
- Ensure proper
setAttributes
calls - Verify attribute names match exactly
Build Process Best Practices
- Use WordPress Scripts
{
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
}
}
- File Structure
blocks/
└── your-block/
├── src/
│ ├── index.js
│ ├── edit.js
│ ├── editor.scss (optional)
│ └── style.scss (optional)
├── build/ (generated)
├── block.json
└── render.php
- Dependencies
{
"devDependencies": {
"@wordpress/scripts": "latest"
}
}
Key Principles to Remember
- Site Editor is Stricter – Code that works in Post Editor may fail in Site Editor
- useBlockProps is Mandatory – Always use it and spread it on your main element
- React Fragment Wrapping – When returning multiple elements, wrap in
<>...</>
- Test in Both Contexts – Always test in both Post Editor and Site Editor
- Clear Cache Often – Many issues are solved by clearing cache and rebuilding
- Check Console – JavaScript errors often reveal the root cause
- API Version Matters – Use
apiVersion: 3
for modern block features
Quick Debugging Checklist
When InspectorControls don’t appear:
- ✓ Is
useBlockProps()
called with className passed as parameter? - ✓ Is
{...blockProps}
spread on the main block element? - ✓ Are InspectorControls wrapped in React Fragment with main element?
- ✓ Is
apiVersion: 3
set in block.json? - ✓ Did you rebuild (
npm run build
) after changes? - ✓ Did you clear browser cache?
- ✓ Did you remove and re-add the block?
- ✓ Are there any console errors?
Following these guidelines will ensure your blocks work consistently in both the Post Editor and Site Editor, providing a smooth experience for theme users.