• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Step-by-Step Guide to building a custom multi-currency switcher block for Gutenberg using React components

Step-by-Step Guide to building a custom multi-currency switcher block for Gutenberg using React components

Setting Up Your WordPress Development Environment

Before diving into React and Gutenberg, ensure your local WordPress development environment is robust. A common setup involves using Docker with a pre-configured WordPress image or a local server stack like LocalWP. For this guide, we’ll assume you have a WordPress installation accessible locally, and you’re familiar with navigating its file structure, particularly the wp-content/plugins/ directory.

We’ll be creating a custom plugin. Navigate to your WordPress plugins directory and create a new folder for your plugin, e.g., custom-currency-switcher.

Plugin Initialization and Basic Structure

Inside your plugin folder, create the main plugin file. This file will contain the necessary plugin headers and hook into WordPress to register our Gutenberg block.

Plugin Header File

Create a file named custom-currency-switcher.php with the following content:

<?php
/**
 * Plugin Name: Custom Currency Switcher Block
 * Plugin URI: https://example.com/plugins/custom-currency-switcher/
 * Description: A custom Gutenberg block for switching currencies.
 * Version: 1.0.0
 * Author: Your Name
 * Author URI: https://yourwebsite.com/
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: custom-currency-switcher
 * Domain Path: /languages
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Registers the block using the metadata loaded from the `block.json` file.
 * Behind the scenes, it registers also all assets so they can be enqueued
 * through the block editor in the corresponding context.
 *
 * @see https://developer.wordpress.org/reference/functions/register_block_type/
 */
function custom_currency_switcher_block_init() {
    register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'custom_currency_switcher_block_init' );
?>

Setting Up the Build Process with @wordpress/scripts

Gutenberg blocks are typically built using modern JavaScript (ESNext) and React. WordPress provides a convenient package, @wordpress/scripts, to handle the build process (compilation, bundling, etc.).

Install Node.js and npm/yarn

If you don’t have Node.js and npm (or yarn) installed, download them from nodejs.org. After installation, open your terminal or command prompt, navigate to your plugin directory (custom-currency-switcher), and run:

npm init -y

This command creates a package.json file, which will manage your project’s dependencies.

Install WordPress Script Dependencies

Now, install the necessary WordPress development tools:

npm install @wordpress/scripts --save-dev

Next, update your package.json file to include build scripts. Open package.json and add the following to the scripts section:

{
  "name": "custom-currency-switcher",
  "version": "1.0.0",
  "description": "A custom Gutenberg block for switching currencies.",
  "main": "build/index.js",
  "scripts": {
    "build": "wp-scripts build",
    "start": "wp-scripts start"
  },
  "keywords": [
    "wordpress",
    "gutenberg",
    "block"
  ],
  "author": "Your Name",
  "license": "GPL-2.0-or-later",
  "devDependencies": {
    "@wordpress/scripts": "^26.0.0"
  }
}

The build script will compile your JavaScript and CSS for production, while start will watch for changes and recompile automatically during development.

Creating the Block Configuration (`block.json`)

WordPress uses a block.json file to define block metadata and dependencies. Create a file named block.json in the root of your plugin directory (alongside custom-currency-switcher.php).

{
    "apiVersion": 2,
    "name": "custom-currency-switcher/block",
    "version": "0.1.0",
    "title": "Currency Switcher",
    "category": "widgets",
    "icon": "money-alt",
    "description": "Allows users to switch between different currencies.",
    "keywords": [
        "currency",
        "switcher",
        "ecommerce"
    ],
    "attributes": {
        "defaultCurrency": {
            "type": "string",
            "default": "USD"
        },
        "availableCurrencies": {
            "type": "array",
            "default": ["USD", "EUR", "GBP"]
        }
    },
    "textdomain": "custom-currency-switcher",
    "editorScript": "file:./build/index.js",
    "editorStyle": "file:./build/index.css",
    "style": "file:./build/style-index.css"
}

Explanation of key fields:

  • apiVersion: Specifies the block API version.
  • name: A unique identifier for your block (namespace/block-name).
  • title: The human-readable name displayed in the block inserter.
  • category: The category under which the block will appear.
  • icon: An icon for the block. WordPress Dashicons can be used by their name.
  • description: A short description of the block.
  • keywords: Terms that help users find the block.
  • attributes: Defines the data that your block will store. Here, we define defaultCurrency and availableCurrencies.
  • textdomain: For internationalization.
  • editorScript: Points to the JavaScript file that will be loaded in the editor.
  • editorStyle: Points to the CSS file for the editor.
  • style: Points to the CSS file for the front-end.

Developing the React Components

Gutenberg blocks are built using React. We’ll create two main components: one for the editor interface and one for the front-end rendering.

Editor Component (`src/editor.js`)

Create a src folder in your plugin directory. Inside src, create editor.js. This file will contain the React component for the block’s editor view.

import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, SelectControl, TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

import './editor.scss'; // For editor-specific styles

registerBlockType( 'custom-currency-switcher/block', {
    apiVersion: 2,
    title: __( 'Currency Switcher', 'custom-currency-switcher' ),
    icon: 'money-alt',
    category: 'widgets',
    description: __( 'Allows users to switch between different currencies.', 'custom-currency-switcher' ),
    keywords: [ __( 'currency', 'custom-currency-switcher' ), __( 'switcher', 'custom-currency-switcher' ), __( 'ecommerce', 'custom-currency-switcher' ) ],
    attributes: {
        defaultCurrency: {
            type: 'string',
            default: 'USD',
        },
        availableCurrencies: {
            type: 'array',
            default: ['USD', 'EUR', 'GBP'],
        },
    },

    edit: ( { attributes, setAttributes } ) => {
        const blockProps = useBlockProps();
        const { defaultCurrency, availableCurrencies } = attributes;

        const currencyOptions = [
            { label: 'US Dollar (USD)', value: 'USD' },
            { label: 'Euro (EUR)', value: 'EUR' },
            { label: 'British Pound (GBP)', value: 'GBP' },
            // Add more currencies as needed
        ];

        const handleDefaultCurrencyChange = ( value ) => {
            setAttributes( { defaultCurrency: value } );
        };

        const handleAvailableCurrenciesChange = ( value ) => {
            // This is a simplified example. A more robust solution would involve
            // adding/removing currencies from a list, not just replacing.
            // For now, let's assume a comma-separated string input.
            const currencies = value.split(',').map(c => c.trim().toUpperCase()).filter(c => c);
            setAttributes( { availableCurrencies: currencies } );
        };

        return (
            <>
                <InspectorControls>
                    <PanelBody title={ __( 'Currency Settings', 'custom-currency-switcher' ) }>
                        <SelectControl
                            label={ __( 'Default Currency', 'custom-currency-switcher' ) }
                            value={ defaultCurrency }
                            options={ currencyOptions }
                            onChange={ handleDefaultCurrencyChange }
                        />
                        <TextControl
                            label={ __( 'Available Currencies (comma-separated)', 'custom-currency-switcher' ) }
                            value={ availableCurrencies.join(', ') }
                            onChange={ handleAvailableCurrenciesChange }
                            help={ __( 'e.g., USD, EUR, GBP', 'custom-currency-switcher' ) }
                        />
                    </PanelBody>
                </InspectorControls>
                <div { ...blockProps }>
                    <p>{ __( 'Currency Switcher (Editor View)', 'custom-currency-switcher' ) }</p>
                    <p>{ __( 'Default:', 'custom-currency-switcher' ) } { defaultCurrency }</p>
                    <p>{ __( 'Available:', 'custom-currency-switcher' ) } { availableCurrencies.join(', ') }</p>
                    { /* In a real scenario, you'd render a dropdown or buttons here */ }
                </div>
            </>
        );
    },

    save: () => {
        // The save function should return null for dynamic blocks,
        // or the JSX for static blocks. For this example, we'll make it dynamic.
        return null;
    },
} );

Key components used:

  • registerBlockType: Registers the block with WordPress.
  • useBlockProps: A hook to get the necessary props for the block’s wrapper element.
  • InspectorControls: Renders controls in the block’s sidebar (Inspector).
  • PanelBody: A container for controls within the Inspector.
  • SelectControl: A dropdown for selecting an option.
  • TextControl: A text input field.
  • __ (from @wordpress/i18n): For internationalization.

Front-end Component (`src/frontend.js`)

Since we’ve set save: () => null in editor.js, this block will be dynamic. Dynamic blocks render their output on the server-side using a PHP callback. We’ll define this callback in our main PHP file.

Registering Scripts and Styles

We need to tell WordPress how to load our compiled JavaScript and CSS files. This is done via the block.json file, which we’ve already configured. When you run the build command, @wordpress/scripts will automatically generate the necessary registration code based on block.json.

Building the Block Assets

Now, run the build command in your terminal from the plugin’s root directory:

npm run build

This command will:

  • Compile your React/JSX code into standard JavaScript.
  • Bundle your JavaScript files.
  • Compile your SCSS/CSS files.
  • Place the compiled assets into a build folder within your plugin directory.

You should now see a build folder containing index.js, index.css, and style-index.css.

Implementing the Dynamic Rendering (PHP)

For dynamic blocks, we need a PHP function to render the block’s output on the front-end. We’ll hook this into the register_block_type function.

Modify `custom-currency-switcher.php`

Update your main plugin file to include the render callback:

<?php
/**
 * Plugin Name: Custom Currency Switcher Block
 * Plugin URI: https://example.com/plugins/custom-currency-switcher/
 * Description: A custom Gutenberg block for switching currencies.
 * Version: 1.0.0
 * Author: Your Name
 * Author URI: https://yourwebsite.com/
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 * Text Domain: custom-currency-switcher
 * Domain Path: /languages
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Renders the currency switcher block on the front-end.
 *
 * @param array $attributes The block attributes.
 * @return string The HTML output for the block.
 */
function custom_currency_switcher_render_callback( $attributes ) {
    $default_currency = isset( $attributes['defaultCurrency'] ) ? $attributes['defaultCurrency'] : 'USD';
    $available_currencies = isset( $attributes['availableCurrencies'] ) ? $attributes['availableCurrencies'] : array( 'USD', 'EUR', 'GBP' );

    // Enqueue a script for front-end interactivity if needed
    // wp_enqueue_script( 'custom-currency-switcher-frontend', plugin_dir_url( __FILE__ ) . 'build/frontend.js', array( 'react', 'react-dom' ), '1.0.0', true );

    ob_start();
    ?>
    <div class="wp-block-custom-currency-switcher-block">
        <p><?php echo esc_html__( 'Current Currency:', 'custom-currency-switcher' ); ?> <strong><?php echo esc_html( $default_currency ); ?></strong></p>
        <!-- Here you would typically render a dropdown or buttons for currency selection -->
        <div class="currency-options">
            <label for="currency-select"><?php echo esc_html__( 'Select Currency:', 'custom-currency-switcher' ); ?></label>
            <select id="currency-select" name="currency-select">
                <?php foreach ( $available_currencies as $currency ) : ?>
                    <option value="<?php echo esc_attr( $currency ); ?>" <?php selected( $default_currency, $currency ); ?>>
                        <?php echo esc_html( $currency ); ?>
                    </option>
                <?php endforeach; ?>
            </select>
        </div>
        <!-- Add JavaScript here to handle the actual currency switching logic -->
    </div>
    <?php
    return ob_get_clean();
}

/**
 * Registers the block using the metadata loaded from the `block.json` file.
 * Behind the scenes, it registers also all assets so they can be enqueued
 * through the block editor in the corresponding context.
 *
 * @see https://developer.wordpress.org/reference/functions/register_block_type/
 */
function custom_currency_switcher_block_init() {
    register_block_type( __DIR__ . '/build', array(
        'render_callback' => 'custom_currency_switcher_render_callback',
    ) );
}
add_action( 'init', 'custom_currency_switcher_block_init' );
?>

In this PHP code:

  • We define a custom_currency_switcher_render_callback function that accepts the block’s $attributes.
  • It retrieves the defaultCurrency and availableCurrencies.
  • It uses output buffering (ob_start(), ob_get_clean()) to capture the HTML output.
  • A basic HTML structure is generated, including a select dropdown for currency selection.
  • The register_block_type function is updated to include the render_callback argument, pointing to our PHP function.

Adding Front-end Styles (`src/style.scss`)

Create a src/style.scss file for your block’s front-end styles:

.wp-block-custom-currency-switcher-block {
    border: 1px solid #ccc;
    padding: 15px;
    margin-bottom: 15px;
    background-color: #f9f9f9;
    border-radius: 4px;

    p {
        margin-bottom: 10px;
    }

    .currency-options {
        margin-top: 10px;

        label {
            margin-right: 10px;
            font-weight: bold;
        }

        select {
            padding: 5px;
            border-radius: 3px;
            border: 1px solid #ddd;
        }
    }
}

Adding Editor Styles (`src/editor.scss`)

Create a src/editor.scss file for styles that should only apply within the Gutenberg editor:

.wp-block-custom-currency-switcher-block {
    border: 2px dashed #0073aa; /* Different border for editor */
    padding: 10px;
    background-color: #eaf4fa;

    p {
        font-style: italic;
    }
}

After creating these SCSS files, remember to run npm run build again to compile them into CSS files in the build directory.

Testing the Block

1. **Activate the Plugin:** Go to your WordPress admin area, navigate to “Plugins,” and activate “Custom Currency Switcher Block.”

2. **Add the Block:** Create or edit a post/page. Click the “+” icon to add a new block and search for “Currency Switcher.” Add it to your content.

3. **Configure in Sidebar:** Select the block. In the right-hand sidebar (Inspector), you should see the “Currency Settings” panel. Change the default currency and add/remove available currencies (e.g., enter “USD, CAD, AUD”).

4. **View on Front-end:** Save the post/page and view it on the front-end. You should see the rendered currency switcher with the styles applied.

Next Steps and Enhancements

This provides a foundational custom currency switcher block. For a production-ready solution, consider:

  • Front-end JavaScript Logic: Implement JavaScript to handle the actual currency switching. This might involve AJAX calls to a WordPress REST API endpoint or using client-side logic to update prices displayed on the page (if you’re integrating with an e-commerce plugin like WooCommerce).
  • Integration with E-commerce Plugins: If using WooCommerce, you’ll need to hook into its currency switching mechanisms. This often involves using WooCommerce’s own currency switcher functionality or building custom integrations.
  • Advanced Attribute Handling: For managing available currencies, a more sophisticated UI in the editor might be needed, perhaps using a repeatable field component.
  • Internationalization (i18n): Ensure all user-facing strings are translatable using the __ function and that your plugin includes a .pot file.
  • Error Handling and Validation: Add more robust validation for user inputs in the editor.
  • Accessibility: Ensure the block is accessible, especially the front-end controls.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Optimizing p99 database query response latency in multi-site Domain-driven architecture (DDD) blocks custom tables
  • How to design a modular Action-hook Event Mediator architecture for enterprise-level custom plugins
  • Step-by-Step Guide to building a custom database optimizer portal block for Gutenberg using Next.js headless configurations
  • Optimizing WooCommerce cart response times by lazy loading custom user transaction ledgers assets
  • Step-by-Step Guide: Offloading high-frequency custom subscription logs metadata writes to a Redis KV store

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (658)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (872)
  • PHP (5)
  • PHP Development (41)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (639)
  • SEO & Growth (492)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (66)
  • WordPress Plugin Development (72)
  • WordPress Plugin Development (330)
  • WordPress Theme Development (357)

Recent Posts

  • Optimizing p99 database query response latency in multi-site Domain-driven architecture (DDD) blocks custom tables
  • How to design a modular Action-hook Event Mediator architecture for enterprise-level custom plugins
  • Step-by-Step Guide to building a custom database optimizer portal block for Gutenberg using Next.js headless configurations

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (872)
  • Debugging & Troubleshooting (658)
  • Security & Compliance (639)
  • SEO & Growth (492)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala