The editor canvas must show a rendered preview that matches the frontend. Editors need to see what the block looks like while editing, a blank or invisible canvas is never acceptable.
Canvas Heading Must Use Element Classes
The heading element class from window.wptElements.buildElementClasses() must be applied to the canvas heading. This is what makes the editor preview reflect the element cascade styles.
el( attr.headingLevel || 'h2', {
className: 'wpt-{slug}__heading ' + headingClasses( attr )
}, attr.heading || 'Placeholder heading text' )
Always provide placeholder text as the second argument to el(). If attr.heading is empty (fresh block insert), the canvas must still show something visible, never render an empty heading tag.
Conditional Renders, Ternary Only
Never use && for conditional rendering in wpTruss blocks. false && el(...) returns false, which React may interpret unexpectedly and which can cause reconciliation issues in the editor.
// ✅ Correct
attr.btn2Enabled ? el( 'span', { className: buildSecondaryBtnClass(attr) }, 'Learn More' ) : null
// ❌ Wrong — can cause React reconciliation issues
attr.btn2Enabled && el( 'span', { className: buildSecondaryBtnClass(attr) }, 'Learn More' )
TextareaControl, Not Raw textarea
Never use a raw el('textarea', {...}) in Gutenberg blocks. Always use the WordPress component:
var TextareaControl = wp.components.TextareaControl;
el( TextareaControl, {
label: 'Description',
value: attr.description || '',
rows: 3,
onChange: function(v) { setAttr({ description: v }); }
})
Raw textarea elements cause React reconciliation issues inside the Gutenberg editor.