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 definedefaultCurrencyandavailableCurrencies.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
buildfolder 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_callbackfunction that accepts the block’s$attributes. - It retrieves the
defaultCurrencyandavailableCurrencies. - 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_typefunction is updated to include therender_callbackargument, 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.potfile. - 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.