easythemestore

How to Create a Custom WordPress Block from Scratch

How to Create a Custom WordPress Block from Scratch

Creating custom WordPress blocks allows you to extend the Gutenberg editor with your own unique content elements. This guide will walk you through the entire process of developing a custom block from scratch using modern WordPress development practices.

Prerequisites

Before we begin, ensure you have:

  • WordPress 5.8+ (with Gutenberg enabled)
  • Node.js (v14+) and npm installed
  • A local development environment (Local by Flywheel, XAMPP, etc.)
  • Basic knowledge of JavaScript (ES6+) and React

1. Setting Up the Development Environment

Install the Required Tools

First, install the official WordPress block development toolchain:

npm install -g @wordpress/create-block

Create a New Block Plugin

Run the following command to scaffold a new block:

npx @wordpress/create-block custom-block
cd custom-block

This creates a new plugin with:

  • A ready-to-use block structure
  • Webpack configuration
  • Modern JavaScript/React setup. Our YouTube channel; https://www.youtube.com/@easythemestore

2. Understanding the Block Structure

The generated plugin contains these key files:

custom-block/
├── build/          # Compiled assets
├── src/           # Source files
│   ├── block.json # Block metadata
│   ├── edit.js    # Editor component
│   ├── index.js   # Main block file
│   └── save.js    # Frontend render
├── package.json   # NPM dependencies
└── plugin.php     # Main plugin file

3. Customizing Your Block

Let’s modify the default block to create a “Call to Action” block.

Update block.json

Modify the metadata in src/block.json:

{
  "apiVersion": 2,
  "name": "custom-block/cta",
  "title": "Call to Action",
  "category": "design",
  "icon": "megaphone",
  "description": "A customizable call-to-action block",
  "attributes": {
    "heading": {
      "type": "string",
      "source": "html",
      "selector": "h2"
    },
    "content": {
      "type": "string",
      "source": "html",
      "selector": "p"
    }
  }
}

Edit the Block Component (edit.js)

Update src/edit.js to include editable fields:

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

export default function Edit({ attributes, setAttributes }) {
  return (
    <div {...useBlockProps()}>
      <RichText
        tagName="h2"
        value={attributes.heading}
        onChange={(heading) => setAttributes({ heading })}
        placeholder="Enter heading..."
      />
      <RichText
        tagName="p"
        value={attributes.content}
        onChange={(content) => setAttributes({ content })}
        placeholder="Enter content..."
      />
    </div>
  );
}

Define Frontend Output (save.js)

Update src/save.js to render the block:

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

export default function save({ attributes }) {
  return (
    <div {...useBlockProps.save()}>
      <RichText.Content tagName="h2" value={attributes.heading} />
      <RichText.Content tagName="p" value={attributes.content} />
    </div>
  );
}

4. Adding Block Styles

Add custom CSS for your block:

Editor Styles

Create src/editor.scss:

.wp-block-custom-block-cta {
  background: #f0f0f0;
  padding: 20px;
  border-radius: 5px;
  
  h2 {
    color: #2271b1;
  }
}

Frontend Styles

Create src/style.scss:

.wp-block-custom-block-cta {
  background: #ffffff;
  border: 1px solid #ddd;
  padding: 30px;
  margin: 20px 0;
  
  h2 {
    color: #333;
    margin-top: 0;
  }
}

5. Building and Testing the Block

Compile your block:

npm run build

Then:

  1. Upload the entire custom-block folder to /wp-content/plugins/
  2. Activate the plugin in WordPress admin
  3. Add your new block in the Gutenberg editor

6. Advanced Customizations

Add Block Controls

Add a color picker to the block toolbar:

import { PanelColorSettings } from '@wordpress/block-editor';

// Add to your Edit component
<InspectorControls>
  <PanelColorSettings
    title="Color Settings"
    colorSettings={[
      {
        value: attributes.bgColor,
        onChange: (bgColor) => setAttributes({ bgColor }),
        label: "Background Color",
      }
    ]}
  />
</InspectorControls>

Add Block Variations

Create multiple style variations in block.json:

"styles": [
  {
    "name": "default",
    "label": "Default",
    "isDefault": true
  },
  {
    "name": "outline",
    "label": "Outline"
  }
]

7. Best Practices for Block Development

  1. Use WordPress Components (RichText, InspectorControls, etc.)
  2. Make Blocks Accessible (proper ARIA labels, keyboard navigation)
  3. Optimize Performance (avoid unnecessary re-renders)
  4. Follow WordPress Coding Standards
  5. Test Across Devices (mobile, tablet, desktop)

Conclusion

You’ve now created a fully functional custom WordPress block from scratch! This foundation can be extended with:

  • Dynamic content rendering
  • InnerBlocks for nested content
  • Server-side rendering for complex blocks
  • Block patterns for pre-designed layouts

🚀 Next Steps:

  • Explore the Block Editor Handbook
  • Learn about block templates and patterns
  • Experiment with dynamic blocks using PHP

This guide gives you everything needed to start building professional-grade WordPress blocks. Happy coding! 💻