• 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 two-factor authentication block for Gutenberg using SolidJS high-performance reactive components

Step-by-Step Guide to building a custom two-factor authentication block for Gutenberg using SolidJS high-performance reactive components

Gutenberg Block Development Environment Setup

To begin building a custom Gutenberg block for two-factor authentication (2FA), we need a robust development environment. This involves setting up Node.js, npm (or yarn), and the WordPress Command Line Interface (WP-CLI) for efficient block scaffolding and management. We’ll leverage SolidJS for its high-performance reactive components, which will translate into a snappier user experience within the WordPress admin area.

First, ensure you have Node.js (version 14 or higher recommended) and npm installed. You can download them from nodejs.org. Verify your installation with:

node -v
npm -v

Next, install WP-CLI globally. This tool is indispensable for managing WordPress installations, plugins, and themes from the command line.

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

Now, let’s scaffold a new Gutenberg block plugin. Navigate to your WordPress plugins directory and execute the following command. Replace my-2fa-block with your desired plugin slug.

cd /path/to/your/wordpress/wp-content/plugins/
wp scaffold block my-2fa-block

This command generates a basic block structure, including necessary configuration files and example JavaScript. We will modify these to integrate SolidJS.

Integrating SolidJS into the Gutenberg Block

The default Gutenberg block setup uses React. To integrate SolidJS, we need to adjust the build process. The primary configuration file for the block’s JavaScript build is webpack.config.js (or similar, depending on the scaffolding tool). We’ll modify this to include SolidJS’s JSX transform.

First, install SolidJS and its JSX transform as development dependencies:

cd my-2fa-block
npm install solid-js @babel/plugin-transform-react-jsx --save-dev

Next, update your webpack.config.js. The key change is to configure Babel to use the SolidJS JSX transform. If your project uses @wordpress/scripts, the Babel configuration is often managed internally. In such cases, you might need to eject or customize the Babel configuration. A common approach is to add a .babelrc file or modify the babel.config.js if one exists.

Create or modify a .babelrc file in the root of your block plugin directory:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-transform-react-jsx",
    {
      "runtime": "automatic",
      "importSource": "solid-js"
    }
  ]
}

With the JSX transform configured, we can now start writing our block’s frontend and editor components using SolidJS syntax. The main entry point for your block’s JavaScript is typically src/index.js. Replace its content with the following structure:

// src/index.js
import { registerBlockType } from '@wordpress/blocks';
import { render } from 'solid-js/web';
import { TwoFactorAuthBlock } from './components/TwoFactorAuthBlock'; // We'll create this component

registerBlockType('my-2fa-block/two-factor-auth', {
  title: 'Two-Factor Authentication',
  icon: 'shield-alt', // WordPress dashicon
  category: 'security',
  edit: () => {
    const element = document.createElement('div');
    // In a real scenario, you'd likely use a wrapper and manage state.
    // For simplicity here, we're directly rendering.
    render(() => , element);
    return element;
  },
  save: () => {
    const element = document.createElement('div');
    render(() => , element);
    return element;
  },
});

Building the SolidJS 2FA Component

Now, let’s create the core SolidJS component that will handle the 2FA logic. This component will manage the input for the 2FA code and interact with the WordPress backend for verification. We’ll create a new file, src/components/TwoFactorAuthBlock.jsx.

// src/components/TwoFactorAuthBlock.jsx
import { createSignal, Show } from 'solid-js';
import apiFetch from '@wordpress/api-fetch'; // WordPress API fetch utility

export function TwoFactorAuthBlock(props) {
  const [code, setCode] = createSignal('');
  const [message, setMessage] = createSignal('');
  const [isLoading, setIsLoading] = createSignal(false);
  const [isVerified, setIsVerified] = createSignal(false);

  const handleCodeChange = (event) => {
    setCode(event.target.value);
  };

  const handleSubmit = async (event) => {
    event.preventDefault();
    setIsLoading(true);
    setMessage('');

    try {
      // Assuming a WordPress REST API endpoint for 2FA verification
      const response = await apiFetch({
        path: '/my-2fa-block/v1/verify-code',
        method: 'POST',
        data: { code: code() },
      });

      if (response.success) {
        setIsVerified(true);
        setMessage('Authentication successful!');
      } else {
        setMessage(response.message || 'Invalid code. Please try again.');
      }
    } catch (error) {
      console.error('2FA Verification Error:', error);
      setMessage('An error occurred during verification.');
    } finally {
      setIsLoading(false);
    }
  };

  return (
    <div class="two-factor-auth-block">
      {props.isEditMode ? (
        <p>Two-Factor Authentication (Edit Mode - Frontend view will be rendered here)</p>
      ) : (
        <>
          <h3>Enter your Two-Factor Code</h3>
          <form onSubmit={handleSubmit}>
            <input
              type="text"
              value={code()}
              onInput={handleCodeChange}
              placeholder="e.g., 123456"
              required
              disabled={isLoading() || isVerified()}
            />
            <button type="submit" disabled={isLoading() || isVerified()}>
              {isLoading() ? 'Verifying...' : 'Verify'}
            </button>
          </form>
          <Show when={message()}>
            <p class={isVerified() ? 'success-message' : 'error-message'}>{message()}</p>
          </Show>
          <Show when={isVerified()}>
            <p>You are now authenticated.</p>
          </Show>
        </>
      )}
    </div>
  );
}

In this component:

  • We use createSignal from SolidJS to manage the state of the input code, feedback messages, loading status, and verification status.
  • apiFetch, a WordPress utility, is used to communicate with our custom backend endpoint.
  • The Show component conditionally renders messages and the success state.
  • The isEditMode prop differentiates between the editor view and the frontend view.

Backend API Endpoint for Verification

For the 2FA verification to work, we need a corresponding backend endpoint in WordPress. This typically involves creating a custom plugin or adding functionality to your theme’s functions.php file to register a REST API route.

Here’s an example of how you might register this endpoint using PHP:

<?php
/**
 * Plugin Name: My 2FA Block
 * Description: Adds a custom 2FA block.
 * Version: 1.0
 * Author: Your Name
 */

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

// Register the REST API endpoint
add_action( 'rest_api_init', function () {
    register_rest_route( 'my-2fa-block/v1', '/verify-code', array(
        'methods'  => 'POST',
        'callback' => 'my_2fa_block_verify_code_callback',
        'permission_callback' => '__return_true', // Adjust permissions as needed
    ) );
} );

// Callback function for the REST API endpoint
function my_2fa_block_verify_code_callback( WP_REST_Request $request ) {
    $received_code = sanitize_text_field( $request->get_param( 'code' ) );

    // --- IMPORTANT SECURITY NOTE ---
    // In a real-world scenario, you would:
    // 1. Retrieve the user's expected 2FA code (e.g., from session, user meta, or a dedicated service).
    // 2. Implement secure comparison (e.g., using hash_equals for time-attack resistance if codes are hashed).
    // 3. Handle code expiration and rate limiting.
    // 4. Associate the verified status with the current user session.
    // For this example, we'll use a placeholder check.
    // --- END SECURITY NOTE ---

    // Placeholder verification logic: Replace with your actual 2FA implementation.
    // Example: Check against a temporary code stored in user meta or session.
    $user_id = get_current_user_id(); // Get the logged-in user ID
    if ( ! $user_id ) {
        return new WP_Error( 'not_logged_in', 'User not logged in.', array( 'status' => 401 ) );
    }

    $expected_code = get_user_meta( $user_id, '_my_2fa_temp_code', true ); // Example: retrieve temporary code

    if ( ! empty( $expected_code ) && hash_equals( $expected_code, $received_code ) ) {
        // Code is correct, clear the temporary code and mark as verified (e.g., in session)
        delete_user_meta( $user_id, '_my_2fa_temp_code' );
        // Set a session flag or cookie to indicate successful 2FA for this session
        // Example: update_user_meta( $user_id, '_my_2fa_verified_session', time() );

        return rest_ensure_response( array( 'success' => true, 'message' => '2FA code verified successfully.' ) );
    } else {
        // Code is incorrect
        return rest_ensure_response( array( 'success' => false, 'message' => 'Invalid 2FA code.' ), 400 );
    }
}

// --- Example: How to generate and store a temporary 2FA code (for demonstration) ---
// This would typically be triggered when 2FA is required, e.g., during login or sensitive action.
function my_2fa_block_generate_and_store_code( $user_id ) {
    // Generate a 6-digit code (example)
    $code = str_pad( wp_rand( 0, 999999 ), 6, '0', STR_PAD_LEFT );
    update_user_meta( $user_id, '_my_2fa_temp_code', $code );

    // In a real app, you'd send this code via SMS, email, or authenticator app.
    // For this example, we'll just store it.
    error_log( "Generated 2FA code for user {$user_id}: {$code}" ); // Log for debugging
    return $code;
}

// Example hook to trigger code generation (e.g., after user logs in if 2FA is enabled)
// add_action( 'wp_login', 'my_2fa_block_trigger_code_generation', 10, 2 );
// function my_2fa_block_trigger_code_generation( $user_login, $user ) {
//     if ( get_user_meta( $user->ID, '_my_2fa_enabled', true ) ) {
//         my_2fa_block_generate_and_store_code( $user->ID );
//     }
// }
?>

Security Considerations for the Backend:

  • Never hardcode secrets or verification logic directly. Use secure methods for generating, storing, and comparing 2FA codes.
  • Implement rate limiting on the verification endpoint to prevent brute-force attacks.
  • Ensure the permission_callback is correctly configured. For sensitive operations, it should verify user capabilities or authentication status.
  • Consider using WordPress’s built-in hashing functions (like wp_hash() and wp_check_password() or hash_equals() for comparing secrets) for security.
  • The example uses get_current_user_id(), implying the user is already logged in. A full 2FA flow would integrate with the login process itself.

Styling the Block

To make the block presentable, you’ll need to add CSS. Create a src/style.scss file (or similar) and import it into your src/index.js. Ensure your build process (Webpack) is configured to handle SCSS compilation.

// src/style.scss
.two-factor-auth-block {
  padding: 15px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background-color: #f9f9f9;

  h3 {
    margin-top: 0;
    color: #333;
  }

  form {
    display: flex;
    gap: 10px;
    margin-bottom: 15px;

    input[type="text"] {
      flex-grow: 1;
      padding: 8px;
      border: 1px solid #ddd;
      border-radius: 3px;
    }

    button {
      padding: 8px 15px;
      background-color: #0073aa;
      color: white;
      border: none;
      border-radius: 3px;
      cursor: pointer;
      transition: background-color 0.2s ease;

      &:disabled {
        background-color: #ccc;
        cursor: not-allowed;
      }

      &:hover:not(:disabled) {
        background-color: #005177;
      }
    }
  }

  .success-message {
    color: green;
    font-weight: bold;
  }

  .error-message {
    color: red;
    font-weight: bold;
  }
}

Then, import this SCSS file in your src/index.js:

// src/index.js (add this line)
import './style.scss';

Building and Activating the Block

After setting up the components and backend, you need to build the JavaScript assets and activate the plugin.

Run the build command in your block’s directory:

npm run build

This command compiles your SolidJS and SCSS code into optimized JavaScript and CSS files, typically placed in a build directory. These files are then enqueued by WordPress.

Finally, navigate to your WordPress admin area, go to “Plugins,” and activate “My 2FA Block.” You should now be able to add the “Two-Factor Authentication” block to your posts or pages.

Advanced Considerations and Next Steps

This guide provides a foundational implementation. For a production-ready solution, consider the following:

  • User Experience: Implement more sophisticated error handling, loading states, and potentially a countdown timer for code expiration.
  • Security: Integrate with a robust 2FA library or service. Ensure secure storage and transmission of sensitive data. Implement session management for verified states.
  • Code Generation and Delivery: Develop a secure mechanism for generating 2FA codes (e.g., TOTP using libraries like Google Authenticator) and delivering them to users (SMS, email, push notifications).
  • Block Editor Integration: For sensitive actions within the block editor itself (not just on the frontend), you might need to leverage WordPress’s authentication and authorization APIs more deeply, potentially requiring a full page reload or a more complex modal flow.
  • Accessibility: Ensure the block is fully accessible, adhering to WCAG guidelines.
  • Internationalization: Make strings translatable using WordPress’s i18n functions.

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

  • How to securely integrate HubSpot Contacts endpoints into WordPress custom plugins using Rewrite API custom endpoints
  • Troubleshooting namespace class loading collisions in production when using modern Sage Roots modern environments wrappers
  • Troubleshooting WooCommerce hook execution loops in production when using modern Classic Core PHP wrappers
  • Implementing automated compliance reporting for custom internal server status logs ledgers using dompdf library
  • Step-by-Step Guide to building a custom CSV bulk exporter block for Gutenberg using SolidJS high-performance reactive components

Categories

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

Recent Posts

  • How to securely integrate HubSpot Contacts endpoints into WordPress custom plugins using Rewrite API custom endpoints
  • Troubleshooting namespace class loading collisions in production when using modern Sage Roots modern environments wrappers
  • Troubleshooting WooCommerce hook execution loops in production when using modern Classic Core PHP wrappers

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (824)
  • Debugging & Troubleshooting (609)
  • Security & Compliance (587)
  • 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