Gutenberg Block Editor

Getting Started with JavaScript

The goal of this lesson is to walk you through the process of getting start with JavaScript with WordPress, with a focus on the new block editor. The APIs available for dealing with this new configuration is detail in the Block Editor Handbook. The purpose of this lesson is to familiarize you with the API reference and code samples contained therein.

What is JavaScript?

In contrast to PHP, which is perform by a web server and the results transmits to the browser as HTML, JavaScript is a programming language that is loads and executed in your web browser.

The block editor in WordPress 5.0 is built in JavaScript, and the code is run in the browser rather than on the server, allowing for a more rich and dynamic user experience. It also necessitates learning JavaScript in order to expand and enhance the block editor.

Plugins Background for Block Editor

The fastest method to get start is to establish a new plugin code directory in wp-content/plugins/. Call it softhunt in this case.

Make a file called softhunt.php in this new directory. When your plugin is activate, this is the server-side code that executes.

Add the following code to the file for now:

Plugin Name: Softhunt

To summarize, the single file softhunt.php should be located in the wp-content/plugins/softhunt/ directory.

Once you’ve done that, go to your plugins list in wp-admin and look for your plugin.

When you click Activate, WordPress will load your plugin.

Loading JavaScript 

You may now include the code that loads the JavaScript after the plugin is install. This technique follows the normal WordPress enqueuing scripts procedure (see the enqueuing section of the Plugin Handbook for further information).

Add the following code to your softhunt.php file:

function mysofthunt_enqueue() {
        plugins_url( 'softhunt.js', __FILE__ )
add_action( 'enqueue_block_editor_assets', 'mysofthunt_enqueue' );

When the block editor loads, the enqueue_block_editor_assets hook is call, which enqueues the JavaScript file softhunt.js.

Create a file called softhunt.js and add:

console.log( "I'm loaded!" );

Next, create a new post in the block editor.

We’ll look in your browser’s Developer Tools for the JavaScript console to see if the message is shown. If you’re not sure what developer tools are, check out Mozilla’s “What are browser developer tools?” documentation, which includes further information on the JavaScript console.

If your code is successfully register and enqueued, you should get the following message in your console:

block editor img1

Note to Theme Developers: Plugins are enqueue using the technique describe above. There is a small distinction if you are expanding the block editor for your theme: instead of plugins_url( ), you will use the get_template_directory_uri( ) method (). So here’s an enqueue example for a theme:

function mysofthunt_enqueue() {
        get_template_directory_uri() . '/softhunt.js'
add_action( 'enqueue_block_editor_assets', 'mysofthunt_enqueue' );


At this point, you have a plugin in the wp-content/plugins/softhunt directory with two files: softhunt.php, which is the PHP server-side code, and softhunt.js, which is the JavaScript that runs in the browser.

This completes the initial setup enabling you to begin expanding the block editor.

Extending the Block Editor

In your softhunt.js file, replace the old console.log() code with:

wp.blocks.registerBlockStyle( 'core/quote', {
    name: 'fancy-quote',
    label: 'Fancy Quote',
} );

Important: You’ve used a function from the wp.blocks package. This implies that when you enqueue the script, you must declare it as a dependent. Make the following changes to the softhunt.php file:

Plugin Name: Softhunt
function mysofthunt_enqueue() {
    wp_enqueue_script( 'softhunt-script',
        plugins_url( 'softhunt.js', __FILE__ ),
        array( 'wp-blocks' )
add_action( 'enqueue_block_editor_assets', 'mysofthunt_enqueue' );

The wp_enqueue_script( ) method accepts an array of dependencies as the final parameter. Under the wp namespace, WordPress makes packages available. You use wp.blocks to access the objects that the blocks package exports (in this case, the registerBlockStyle( ) method) in the example.

Go to the block editor and create a new post after you’ve modified both JavaScript and PHP files.
Add a quotation block, and your new Fancy Quote style will appear in the right sidebar under Styles.
To apply the Fancy Quote style to your quote block, click it and choose it:

block editor img2

There will be no apparent change whether you Preview or Publish the content. If you look at the source code, you’ll notice that the is-style-fancy-quote class name has been add to your quote block.

Let’s add some style. In your plugin folder, create a style.css file with:

.is-style-fancy-quote {
    color: tomato;

You enqueue the CSS file by adding the following to your softhunt.php:

function mysofthunt_stylesheet() {
    wp_enqueue_style( 'softhunt-style', plugins_url( 'style.css', __FILE__ ) );
add_action( 'enqueue_block_assets', 'mysofthunt_stylesheet' );

When you view and publish in the editor, you’ll notice your Fancy Quote style with a beautiful tomato color text:

block editor img3

Troubleshooting Block Editor

If you’re having problems getting your JavaScript code to function, here are some troubleshooting suggestions on how to discover errors.

Console Log

A JavaScript developer’s best buddy is the console log. Working with it open is a good idea because it displays all problems and notifications in one location. For additional information, see Mozilla’s JavaScript console documentation.

Find the right key combination for your browser and OS to launch the JavaScript console:


First Step

Check the JavaScript console for any problems as your first step in troubleshooting. An example of a syntax mistake on line 6 is as follows:


Display your message in console log

For debugging and verifying variable values, you may also write straight to the console from your JavaScript code. Use the console.log method to log the following:

console.log( 'My message' );

Alternatively, if you wish to include both a message and a variable, show the values of the settings variable:

console.log( 'Settings value:', settings );

Using console log

If you wish to test a brief command, you may also type JavaScript straight in the console. The commands you type will be apply to the currently open browser window. To count how many blocks are in the editor, use the package in this example. Play around with it and see if you can utilize the console to peruse the various options. 'core/block-editor' ).getBlockCount();

Using the debugger statement 

If you want to halt code execution at a specific line of code, type debugger; anywhere in your code. When the browser encounters the debugger; statement, it will halt the execution of your code. This enables you to check all variables in the vicinity of the debugger statement, which is quite handy. See this MDN page for more information.

Confirm JavaScript is loading 

Check sure your JavaScript file is being enqueue if you don’t notice your modifications and there are no problems. Look for the <script> tag that loads your file in the page source in your browser’s web inspector (some browsers enable you to see the page source by right-clicking on the page and selecting “View Page Source”). In the JavaScript lesson, you would look for softhunt.js and make sure it was load.

If the file does not appear to be load, double-check the enqueue function. You may also look through your server logs to see if there are any errors.

At ensure that your JavaScript is load, add a console.log(“Here”); to the top of your code and verify that the message is display. If not, the file is most likely not loading correctly; see the loading JavaScript from above statement for more information on how to properly enqueue JavaScript.

Confirm all dependencies are loading

If a dependency used by your JavaScript code has not been declared and loaded in the browser, an error will appear in the console log. If the softhunt.js script is enqueued without specifying the wp-blocks requirement in the JavaScript tutorial, the console log will show:


You may correct this by ensuring that your wp_enqueue_script function contains all of the packages listed:

    plugins_url( 'softhunt.js', __FILE__ ),
    array( 'wp-blocks' )

It is suggested that you use wp-scripts to develop step your JavaScript for automatic dependency management.

Scope Your Code for Block Editor

JavaScript files loaded on a web page have always had the same scope. This implies that code in other files will see a global variable specified in one file.

Create a web page that loads three JavaScript files to show how this works. The one.js file is as follows:

var pluginName = 'FirstPlugin';
console.log( 'Plugin name is ', pluginName );

Let’s create two.js as:

var pluginName = 'SecondPlugin';
console.log( 'Plugin name is ', pluginName );

And, finally, three.js:

console.log( 'Plugin name is ', pluginName );

When both one.js and two.js are loaded on the same page, the plugin name defined inside each will be shown. If a global pluginName variable has already been specified, they will overwrite its value. What is shown in the console when three.js is run is unknown; it is dependent on the value of the global pluginName variable, which is dependent on the sequence in which the files are loaded.

This behavior can be troublesome, which is why the code must be scoped. We may avoid values changing unexpectedly by scoping the code and ensuring that each file is separated from the others.

Scoping Code Within a Function for Block Editor

You may scope your code in JavaScript by writing it within a function. Functions have a “local scope,” which is a scope that is exclusive to that function. Additionally, anonymous functions, or functions without a name, may be written in JavaScript, which prevents your function name from being overwritten in the global scope.

Using these two JavaScript capabilities, one.js may be scoped as follows:

function() {
    var pluginName = 'FirstPlugin';
    console.log( 'Plugin name is ', pluginName );

two.js as:

function() {
    var pluginName = 'SecondPlugin';
    console.log( 'Plugin name is ', pluginName );

And three.js:

function() {
    console.log( 'Plugin name is ', pluginName );

The separate files won’t overwrite each other’s variables with this approach. Unfortunately, they will not operate as intended because no one is calling these functions. We’ve merely specified the functions so far; we haven’t really used them.

Automatically Execute Anonymous Functions

There are a few ways to run anonymous functions in JavaScript, but this is the most common:

( function () {
    // your code goes here
} )();

Your function is wrapped in parenthesis and called like any other named function. Immediately-Invoked Function Expression, or IIFE for short, is the name for this pattern.

This is one.js written as an IIFE:

( function () {
    var pluginName = 'FirstPlugin';
    console.log( 'Plugin name is ', pluginName );
} )();

And this is two.js:

( function () {
    var pluginName = 'SecondPlugin';
    console.log( 'Plugin name is ', pluginName );
} )();

And this is three.js:

( function () {
    console.log( 'Plugin name is ', pluginName );
} )();

The code in one.js and two.js is safe and predictable since it is unaffected by other variables in the global scope.

three.js, on the other hand, does not define a pluginName variable and must be given one. You may still use an IIFE to send a variable from the global scope into your function.

Provided that there was a global window.pluginName variable, we could rewrite three.js as:

( function ( name ) {
    console.log( 'Plugin name is ', name );
} )( window.pluginName );

Future Changes for Block Editor

At the beginning we mentioned that:

Historically, JavaScript files loaded in a web page share the same scope.

Notice the historically.

Since its inception, JavaScript has seen significant changes. The language now allows modules, commonly known as ES6 modules, which introduce different scope per file: a global variable in the one.js place. two.js would not be exposed to JavaScript. Modern browsers offer this functionality by default, although not all of them do. Use IIFEs as a last option if your code needs to execute in browsers that don’t support modules.

JavaScript Build Setup for Block Editor

ESNext is JavaScript written in a version newer than browser support, with syntax and functionality exclusively accessible in that version. Browser support is referred to as ECMAScript 5. (ES5). JSX is a React project-created custom syntax extension to JavaScript that allows you to write JavaScript using a familiar HTML tag-like syntax.

Because browsers cannot comprehend or run the ESNext and JSX syntaxes, we must employ a transformation step to turn them to code that browsers can understand.

There are a few compelling reasons to utilize ESNext and this additional transformation step:

  • It simplifies the code, making it easier to read and write.
  • The use of a transformation step enables tools to optimize the code for the widest possible range of browsers.
  • You may arrange your code into smaller modules and files that can be packed together into a single download by utilizing a build phase.

This transformation or construction phase can be performed using a variety of technologies; WordPress utilizes webpack and Babel.

webpack is a pluggable utility that converts JavaScript into a built bundle that can be executed in a browser. Babel converts JavaScript to a different format. You use Babel as a webpack plugin to convert ESNext and JSX to JavaScript.

The @wordpress/scripts package encapsulates these libraries to standardize and simplify development, so you don’t have to worry about webpack or babel configuration.

Quick Start to Block Editor

If you want to get started quickly, use one of the examples from the Gutenberg Examples repository and skip to the next section. The essential files for working with ESNext and JSX may be found in each of the -esnext folders in the examples repository.

Setup for Block Editor

Both webpack and Babel are Node.js-based utilities written in JavaScript. Node.js is a JavaScript runtime environment that runs outside of a browser. Simply simply, node is a command-line tool that allows you to run JavaScript code.

To begin, configure Node.js in your development environment. The procedures necessary vary depending on your operating system; however, if you have a package manager installed, installation is as simple as:

  • Ubuntu: apt install nodejs npm
  • macOS: brew install node
  • Windows: choco install node

If you don’t have a package management, you can get installers and binaries from the official Node.js download page.

Note: Because the build tools and process take place on the command line, a basic understanding of how to use a terminal application is required. Visual Studio Code and PhpStorm are two popular text editors with built-in terminals that are suitable for use.

Node Package Manager (npm)

The Node Package Manager (npm) is a tool that comes with the node package manager. npm is a command-line tool for installing and managing JavaScript packages. Package.json is a special file that npm can generate and process that contains information about your project and the packages it uses.

To begin a new node project, first create a working directory:

mkdir softhunt
cd softhunt

You create a new package.json running npm init in your terminal. This will walk you through creating your package.json file:

npm init
package name: (softhunt) softhunt
version: (1.0.0)
description: Test block
entry point: (index.js) build/index.js
test command:
git repository:
author: ranjeetandani
license: (ISC) GPL-2.0-only
About to write to /home/ranjeetandani/src/wp/scratch/package.json:
  "name": "softhunt",
  "version": "1.0.0",
  "description": "Test block",
  "main": "block.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  "author": "ranjeetandani",
  "license": "GPL-2.0-only"
Is this OK? (yes) yes

Using npm to install packages

The following step is to install the needed packages. The npm command npm install may be used to install packages. If you use the –save-dev option, npm will add the package to the package.json file as a dev dependency. The –save-exact option tells npm to store an exact version of a dependency rather than a range of possible versions. For additional information, see the npm install documentation.


npm install --save-dev --save-exact @wordpress/scripts

The modules and their dependencies are stored in a node_modules directory after installation.

In addition, if you look at the package.json file, you’ll see a new section:

"devDependencies": {
  "@wordpress/scripts": "6.0.0"

Setting Up wp-scripts build

The webpack and Babel dependencies and default settings are handled by the @wordpress/scripts package. The scripts package needs the compile source file to be in src/index.js, and the generated output to be in build/index.js.

Let’s make a simple block with that in mind. Create a file with the following content in src/index.js:

import { registerBlockType } from '@wordpress/blocks';
registerBlockType( 'softhunt/test-block', {
    title: 'Basic Example',
    icon: 'smiley',
    category: 'design',
    edit: () => <div>Hello World!</div>,
    save: () => <div>Hello World!</div>,
} );

To configure npm to run a script, you use the scripts section in package.json webpack:

"scripts": {
  "build": "wp-scripts build"

You can then run the build using: npm run build.

After the build is complete, go to build/index.js to see the built file. The block will load in the editor after you enqueue this file in the admin panel like any other JavaScript in WordPress.

Development Mode

In @wordpress/scripts, the build command is performed in “production” mode. This reduces the size of the code, making it easier to download, but it also makes it more difficult to understand. You may use the start command to run in development mode, which does not reduce the code and also launches a background process to monitor the source file for new changes and rebuilds as you develop.

The start command can be added to the same scripts section of package.json:

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

When you type npm start in the terminal, a watcher will appear. You may then edit away in your text editor; it will automatically build with each save. The edit/save/reload development procedure can then be used.

Note: Keep an eye out for any problems on your terminal. The build will fail if you make a typo or a syntax error, and the error will be shown in the terminal.

Source Control

You should exclude node_modules/ from source control since a typical node_modules folder will include hundreds of files that will change with each software upgrade. Simply execute npm install in the same folder as your package if you’re starting from scratch. To get your needed packages.json.

You also don’t need to include node_modules or any of the aforementioned configuration files in your plugin because they’ll be included in the webpack-generated file. Make sure your plugin PHP includes the build/index.js file. This is the primary JavaScript file that your block will require to run.

Dependency Management

When you use the wp-scripts ver 5.0.0+ build step, you’ll get an index.asset.php file with a list of dependencies and a version number for your block. It looks somewhat like this in our basic example above:

array('dependencies' => array('wp-element', 'wp-polyfill'), 'version' => 'fc93c4a9675c108725227db345898bcc');

This asset file may be used to establish the dependency list for enqueuing the script automatically. This eliminates the need to explicitly update dependencies; instead, it will be generated based on the package imports used in your block.

$asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');
    plugins_url( 'build/index.js', __FILE__ ),

See ESNext blocks in gutenberg-examples repo for full examples.


Yes, the initial setup is a little more time-consuming, but the extra features and advantages generally outweigh the extra setup time.

The usual procedure after a setup is in place is:

  1. Install dependencies: npm install
  2. Start development builds: npm start
  3. Develop. Test. Repeat.
  4. Create production build: npm run build

That’s all for this article if you have any queries please contact us through our website or email us at [email protected]om

Leave a Comment