W
WordPress SOPKnowledge Base
Search
← All topics

Gutenberg Block Development

runnable

Custom Gutenberg block development using PHP server-side rendering and JavaScript/React with @wordpress/scripts build tooling, block.json API version 3, and RichText editor integration.

gutenbergblocksjavascriptreactblock-editor
Agent trigger phrases: gutenberg block · custom block wordpress · register_block_type · wordpress blocks · block editor development · wp-scripts build · block.json wordpress

Gutenberg supports custom blocks via PHP (server-side render) or JavaScript (React). Use PHP SSR for dynamic content, JS for interactive editing.

PHP — Server-Side Rendering

// Register block
function register_testimonial_block() {
    register_block_type('myplugin/testimonial', [
        'render_callback' => 'render_testimonial_block',
        'attributes'      => [
            'quote'  => ['type' => 'string', 'default' => ''],
            'author' => ['type' => 'string', 'default' => ''],
            'rating' => ['type' => 'integer', 'default' => 5],
        ],
    ]);
}
add_action('init', 'register_testimonial_block');

function render_testimonial_block($attributes) {
    $quote  = esc_html($attributes['quote'] ?? '');
    $author = esc_html($attributes['author'] ?? '');
    return "<blockquote class='wp-block-testimonial'><p>{$quote}</p><cite>{$author}</cite></blockquote>";
}

JavaScript — React Block

import { registerBlockType } from '@wordpress/blocks';
import { RichText, useBlockProps } from '@wordpress/block-editor';

registerBlockType('myplugin/testimonial', {
    title: 'Testimonial',
    category: 'content',
    attributes: {
        quote:  { type: 'string', source: 'html', selector: 'p' },
        author: { type: 'string', source: 'html', selector: 'cite' },
    },
    edit({ attributes, setAttributes }) {
        const blockProps = useBlockProps();
        return (
            <blockquote {...blockProps}>
                <RichText
                    tagName="p"
                    value={attributes.quote}
                    onChange={(quote) => setAttributes({ quote })}
                    placeholder="Enter quote..."
                />
                <RichText
                    tagName="cite"
                    value={attributes.author}
                    onChange={(author) => setAttributes({ author })}
                    placeholder="Author name..."
                />
            </blockquote>
        );
    },
    save({ attributes }) {
        const blockProps = useBlockProps.save();
        return (
            <blockquote {...blockProps}>
                <RichText.Content tagName="p" value={attributes.quote} />
                <RichText.Content tagName="cite" value={attributes.author} />
            </blockquote>
        );
    },
});

Build Setup

npm install @wordpress/scripts --save-dev

package.json:

{
  "scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start"
  }
}

block.json (API Version 3 — WP 5.8+)

{
    "$schema": "https://schemas.wp.org/trunk/block.json",
    "apiVersion": 3,
    "name": "myplugin/testimonial",
    "title": "Testimonial",
    "category": "content",
    "icon": "format-quote",
    "editorScript": "file:./index.js",
    "style": "file:./style-index.css"
}