Attributes are how Gutenberg blocks store their data. Each attribute is defined in the block’s schema, serialised into the block comment in the database, and passed to both the edit and save functions as props. The InspectorControls component places settings into the right sidebar panel of the Block Editor.
Problem: How do you add sidebar controls to a Gutenberg block — such as colour pickers, toggles, or text inputs — that let editors customise it without editing HTML?
Solution: Define attributes in the block's block.json, then render InspectorControls inside the edit function — changes to controls update attributes, which are saved as part of the block comment and passed as props to the save function.
A block with text colour, background colour, and alignment attributes:
const { registerBlockType } = wp.blocks;
const { InspectorControls } = wp.editor;
const { PanelBody, ColorPicker, SelectControl } = wp.components;
const { __ } = wp.i18n;
registerBlockType( 'my-plugin/notice', {
title: __( 'Notice', 'my-plugin' ),
icon: 'info',
category: 'common',
attributes: {
message: {
type: 'string',
default: '',
},
backgroundColor: {
type: 'string',
default: '#e7f3ff',
},
textAlign: {
type: 'string',
default: 'left',
},
},
edit( { attributes, setAttributes } ) {
const { message, backgroundColor, textAlign } = attributes;
return [
// Sidebar controls
wp.element.createElement( InspectorControls, null,
wp.element.createElement( PanelBody, { title: __( 'Notice settings', 'my-plugin' ) },
wp.element.createElement( 'p', null, __( 'Background color', 'my-plugin' ) ),
wp.element.createElement( ColorPicker, {
color: backgroundColor,
onChangeComplete: ( color ) => setAttributes( { backgroundColor: color.hex } ),
} ),
wp.element.createElement( SelectControl, {
label: __( 'Text alignment', 'my-plugin' ),
value: textAlign,
options: [
{ label: 'Left', value: 'left' },
{ label: 'Center', value: 'center' },
{ label: 'Right', value: 'right' },
],
onChange: ( value ) => setAttributes( { textAlign: value } ),
} )
)
),
// Block preview
wp.element.createElement(
'div',
{ style: { backgroundColor, textAlign }, className: 'notice-block' },
wp.element.createElement( 'p', null, message || __( 'Enter your notice text…', 'my-plugin' ) )
),
];
},
save( { attributes } ) {
const { message, backgroundColor, textAlign } = attributes;
return wp.element.createElement(
'div',
{ style: { backgroundColor, textAlign }, className: 'notice-block' },
wp.element.createElement( 'p', null, message )
);
},
} );
NOTE: Attribute source tells Gutenberg where to read the attribute value from when parsing saved HTML. Without a source, the attribute is stored only in the block comment and is not pulled from the rendered HTML — useful for settings that don't appear in the front-end markup.