How to register scripts and styles in your WordPress Gutenberg Plugin

Hey ya. In this article we’re going to set you up with a basic plugin environment to get you going in WordPress Plugin development, including Gutenberg. The goal of this article is to cover the following:

  • Setup a basic plugin using Gutenberg
  • Use jQuery on the front end for a block
  • Use javascript files on both front and back end?
  • Register stylesheets for block use
  • Register SCSS files

Learn to code with our beginner friendly tutorials on programming, Linux, Docker, and more

Okay. First step, let’s setup our plugin. I’ll be using a local WAMP server with WordPress already setup. Once you’ve got WordPress running locally, navigate to your “plugins” directory and create the project. I’ll call mine new-plugin and have a new-plugin.php file like this:

<?php

/**
 * Plugin Name: new plugin
 * Plugin URI: https://truthseekers.io
 * Description: registering scripts styles and stuff
 * Author: John
 * Author URI: https://truthseekers.io
 */

Okay cool, we can now activate our plugin. Once the plugin is activated we’ll want to setup “wp-scripts”. From the root directory of your project in your command line we’ll need to setup our package.json file and install the npm module (I’m assuming you have node and npm installed)

$ npm init -y
$ npm install @wordpress/scripts --save-dev

wp-scripts says in their docs that everything compiles to build/index.js. We also need to add our start and build scripts. So modify your package.json by adjusting the “main” line to use the “build/index.js” file, and add the “scripts” block like so:

{
  "name": "new-plugin",
  "version": "1.0.0",
  "description": "",
  "main": "build/index.js",
  "scripts": {
    "start": "wp-scripts start",
    "build": "wp-scripts build",
    "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@wordpress/scripts": "^10.0.0"
  }
}

wp-scripts “entrypoint” for our source code is the “src/index.js” file, meaning that wp-scripts expects to find all of the JS source code we write in src/index.js. Let’s just do a simple log for now:

console.log("hello from new-plugin js");

Now if we were to run “npm start” our “start” script runs, which sets up our build/ folder with all our compiled source code. Let’s do that with the npm start command:

$ npm start

Our build file should appear with the folders inside. So far so good!

Ok, now let’s “enqueue” or register that JS code so WordPress can detect it. We do that with our main php file. Based on the WordPress docs, it appears that we want to “register” the script, and then use that script inside our “register_block_type” function. wp_register_script and wp_register_style is how we prepare our scripts and styles to be used by WordPress. The first step is to create a handle for the script, and then apply that handle where we want the script/style added. It looks like this for our sample plugin:

function new_plugin_setup()
{
    $asset_file = include(plugin_dir_path(__FILE__) . 'build/index.asset.php');

    wp_register_script(
        'truth-new-plugin-script',
        plugins_url('build/index.js', __FILE__),
        $asset_file['dependencies'],
        $asset_file['version']
    );

    register_block_type('truth/new-plugin-block', array(
        'editor_script' => 'truth-new-plugin-script',
    ));
}

add_action('init', 'new_plugin_setup');

Webpack sets up a list of dependencies & version number in build/index.asset.php, so we can easily access dependencies for the project.

Then you want to “register” the script. In this case we created a handle named “truth-new-plugin-script”, so any time we call on that handle it will import that javascript. Then we have the path, dependencies and version…

You can see we’re using that handle to apply the script to our “new-plugin-block’ in the register_block_type function. The ‘editor_script’ will make the js file only apply to inside the editor.

If you save the file and create a new post, and open the developer tools you should see your console.log statement from inside the src/index.js file. Now let’s register the block type in the front end. Inside your src/index.js file we need to import the registerBlockType from @wordpress/blocks (provided by wp-scripts) and create our block:

console.log("hello from new-plugin js lala");
import { registerBlockType } from '@wordpress/blocks';

registerBlockType('truth/new-plugin-block', {
    title: 'new plugin block',
    icon: 'smiley',
    category: 'layout',
    edit: () => <div>I am the edit test</div>,
    save: () => <div>I am the frontend test!</div>,
});

Just to make sure we’re still good, let’s try to create the block. It’s named after the “title” so I’d type in “new plugin block” to add it to post area. And we’re good so far!

Ok, let’s add our CSS file now. This css file will be for our editor… so we’ll first want to register the script (note you can also enqueue, but registering and then grabbing by the handle when you need it is recommended) Underneath the wp_register_script in our new_plugin_setup() function we’ll call wp_register_style to register our backend editor stylesheet:

wp_register_style(
        'truth-new-block-style',
        plugins_url('/src/style.css', __FILE__),
        array('wp-edit-blocks')
    );

truth-new-block-style is our stylesheet handle. then we have the location of the file, and last parameter is dependencies. I didn’t know stylesheets had dependencies so that’s a bit weird but whatever. Now we need to connect this style to our block. We’ll add an element to the array in our existing register_block_type call like this:

register_block_type('truth/new-plugin-block', array(
        'editor_script' => 'truth-new-plugin-script',
        'editor_style'  => 'truth-new-block-style'
    ));

Cool now we should be able to create a CSS file where we said it was in wp_register_style (which is in /src/style.css) So let’s test that out, but first we should setup our edit function to add in the default classname for our block:

registerBlockType('truth/new-plugin-block', {
    title: 'new plugin block',
    icon: 'smiley',
    category: 'layout',
    edit: ({ className }) => <div className={className}>I am the edit test</div>,
    save: () => <div>I am the frontend test!!</div>,
});

This is just ES6 syntax to pass in the className provided by WordPress and adding that class to the div. Now onto our /src/style.css file:

.wp-block-truth-new-plugin-block {
    background: blue;
}

Save and refresh, and you’ll hopefully see you’re beautifully colored blue block.

Want More Tutorials?

Get our best crash courses and tutorials

(Source Code Provided)

Cool. I’ll leave the front end styles up to you as an exercise. But let’s cover the front end script. Say you need some jQuery on the front end of your site to work with the block. Well, according to WordPress jQuery is already included, so all we need to do is tell wp_register_script that jQuery is a dependency for our script. In our main php file add this code:

wp_register_script(
        'jsc-courses-frontend-script', //handle
        plugins_url('/src/frontend.js', __FILE__),
        array('jquery')
    );

// DON'T ADD THIS FUNCTION TWICE! The above code is new, below just add the 'script' line.
    register_block_type('truth/new-plugin-block', array(
        'editor_script' => 'truth-new-plugin-script',
        'editor_style'  => 'truth-new-block-style',
        'script' => 'jsc-courses-frontend-script'
    ));

Then add your src/frontend.js code as follows:

jQuery(document).ready(function ($) {

    console.log("doing some jquery stuff!");
    $('.wp-block-truth-new-plugin-block').click(function () {
        alert("Ouch! Don't click me!");
    })

});

Now navigate to your front end and click on your block and you’ll see it all hopefully works.

UPDATE: CSS Pre-processors are easy with this setup

Let’s try to add some SCSS files. First, you’ll have to think about the ideal setup for your project. Do you want to create many smaller CSS files and only load the minimal css necessary on each section? For production that may be best, but we’ll keep it simpler here since this isn’t a webpack tutorial.

Our setup will have two additional “entry points” in our webpack. In WordPress we have a CSS file for our front-end, and another CSS file for our editor. So we’ll import all our “front end css” into a “frontEndStyles” Javascript file. Webpack will see this Javascript file (entry point) and create a CSS file based off it. Then we’ll add an “editorStyles” JS file that imports all the editor’s CSS. Webpack will create a CSS file for it too.

Finally, because Webpack is creating these two extra css files, we’ll want to register those files in our PHP instead.

First, we’ll setup our two entry points in Webpack. These entry points are kind of like “doorways” to our project. If you had a huge project with one entry point, it’s like having a mansion with only a front door to get in or out. Adding multiple entry points is like having a garage on the side. Code that’s part of the project, but separate for whatever reason. By default WordPress and Webpack have the “src/index.js” file as the entry point.

Create a webpack.config.js file and add this code:

const defaultConfig = require("@wordpress/scripts/config/webpack.config");
const path = require('path');

console.log("laaaaalala");

module.exports = {
    ...defaultConfig,
    entry: {
        ...defaultConfig.entry,
        editorStyle: './src/editorStyle.js',
        style: './src/style.js'
    }
}

The first line imports the existing webpack config provided by wp-scripts.

in module.exports we’re just spreading out the existing settings into the object, creating the “entry”, and adding the two entry points that we want, along with their names and file locations. You may even want to name ‘style’ as “frontEndStyle” for extra clarity if you want.

Now create the ‘src/editorStyle.js’ and ‘src/style.js’ files.

Now we can import all our front end styles to style.js and our editor styles to editorStyle.js. Let’s create a CSS file for both.

editorStyle.css:

.wp-block-truth-new-plugin-block {
    background: lawngreen;
}

style.css: (already have this one. Let’s change the color)

.wp-block-truth-new-plugin-block {
    background: pink;
}

Now in order to allow webpack to create our CSS files for us, we’ll need to make sure webpack can get to our CSS files through the entry points. So in our editorStyle.js and style.js we’ll want to import these CSS files.

editorStyle.js:

import './editorStyle.css';

style.js:

import './style.css';

Now webpack sees our CSS code and can create our production css files for us. First we’ll have to kill our server and start it back up with Ctrl + C and then npm start in our terminal. Go ahead and do that.

Once you restart NPM it should rebuild based off our new webpack config and create two css files in our “build folder”. Here’s what I have:

Notice editorStyle.css and “style-style.css” (Honestly I was expecting style.css since it’s supposed to match the KEY “style” you provided in the webpack config… but whatever, I’m not going to mess with it.)

So… Let’s now try to see if we can get SCSS files to work.

  1. Change each of your CSS files in the src/ folder to have a .scss extension.
  2. update the import statements to import the newly named files.

Update style.js:

import './style.scss';

Update editorStyle.js:

import './editorStyle.scss';

Now to let’s change the scss files to actually do scss things. style.scss:

$primary-color: yellow;

.wp-block-truth-new-plugin-block {
    background: $primary-color;
}

editorStyle.scss:

$secondary-color: brown;

.wp-block-truth-new-plugin-block {
    background: brown;
}

Now if you look through your CSS files in your build/ folder you’ll see that webpack is reading and processing your SCSS files and turning them into plain ole’ CSS. So… You could import 100 css/scss files into your two “entry points” and it’ll all compile into those two css files.

The last thing we have to do is integrate the CSS files from our build/ folder into the plugin. Currently we’re importing the files inside our src/ which wont work because they’re scss files.

I did a pretty crappy job of naming my handles, so I apologize for that, and we’ll now give them more appropriate names as we fix our new-plugin.php file.

function new_plugin_setup()
{
    $asset_file = include(plugin_dir_path(__FILE__) . 'build/index.asset.php');

    wp_register_script(
        'truth-new-plugin-editor-script',
        plugins_url('build/index.js', __FILE__),
        $asset_file['dependencies'],
        $asset_file['version']
    );

    wp_register_style(
        'truth-new-plugin-editor-style',
        plugins_url('/build/editorStyle.css', __FILE__),
        array('wp-edit-blocks')
    );

    wp_register_style(
        'truth-new-plugin-frontend-style',
        plugins_url('/build/style-style.css', __FILE__),
        array('wp-edit-blocks')

    );

    wp_register_script(
        'truth-new-plugin-frontend-script', //handle
        plugins_url('/src/frontend.js', __FILE__),
        array('jquery')
    );

    register_block_type('truth/new-plugin-block', array(
        'editor_script' => 'truth-new-plugin-editor-script',
        'editor_style'  => 'truth-new-plugin-editor-style',
        'script'        => 'truth-new-plugin-frontend-script',
        'style'         => 'truth-new-plugin-frontend-style'
    ));
}

add_action('init', 'new_plugin_setup');

All we did was update the locations of the CSS files that wp_register_style will look for our css files… I also updated the handles to be not so horribly named. (I apologize for that again I was being lazy.)

Lastly, to make sure your frontend styles show up we need to add the class to the frontend as well. Do that in 'src/index.js' by editing the “save” function like this:

save: ({ className }) => <div className={className}>I am the frontend test!</div>,

It’s really hard to write these tutorials without errors or missing something, so here’s the source code of the final working version you can play with. It SHOULD work by just sticking it in your plugins/ folder and running “npm install” and “npm start”. I hope this was helpful to you.

Leave a Comment

Your email address will not be published. Required fields are marked *

want more details?

Fill in your details and we'll be in touch

%d bloggers like this: