Building your own Divi Builder Modules

Building your own Divi Builder Modules

I’ve recently been spending some time extending modules in the Divi Page Builder.

I had a few requests from clients to either make changes to an existing module or create a new module with custom functionality. As always my first port of call was a Google Search. The results, while not abundant, did eventually lead me down the right path.

The limited set of articles I did find didn’t really explain the complete process of setting up a new module or they used slightly incorrect ways of adding a new module to the page builder. So I decided to write a post that detailed the entire process from start to finish. For the sake of this article, we are going to take the Image module and make a new one based on it.

This article won’t go into the details of actually customising the module, as that will be dependant on your specific needs. Also it would probably take up a whole heap of additional articles explaining all the sections in a Page Builder Module Class.

1) Preparation

First off you a basic understanding of PHP and WordPress hooks. For the sake of this article I’m going to assume you are working with a child theme. All the PHP code will be added to one of two files in your child theme. The first is the child theme’s functions.php file (create it if there isn’t one) . The second file will contain all the module related code. You can call the file anything you want, for this article I will call mine custom-pb-image-module.php.

So in the root of my child theme I will have


Inside the functions.php file, include the module file, typically at the top of the functions.php

/* include custom image module file*/ 
include(get_stylesheet_directory() . '/custom-pb-image-module.php');

The get_stylesheet_directory() function will return the path to the child theme folder.

Everything else we do will be inside the custom module file.

2) Prepare your custom module file

Inside the module file add this code:

function ex_divi_child_theme_setup() {

  if ( class_exists('ET_Builder_Module')) {

    // this is where your new module class will go


add_action('et_builder_ready', 'ex_divi_child_theme_setup');

What does this code do?:

  1. Adds a hook to the et_builder_ready action, to call the ex_divi_child_theme_setup function.
  2. The ex_divi_child_theme_setup function then checks if the Builder Module class exists and if true, runs the new module class.

2) Copy an existing module.

The ET Builder Module Classes are quite big, so you don’t really want to write the entire thing yourself. (You’d probably need to be a developer at Elegant Themes to be able to do so anyway). So choose an existing module that is closest to what you need, and then go and find it’s Class in the following Divi file:


I’m going to use the Image module, it looks like this:

class ET_Builder_Module_Image extends ET_Builder_Module {
  function init() {
    $this->name = __( 'Image', 'et_builder' );
    $this->slug = 'et_pb_image';
    // a whole bunch of PHP code that defines how the class functions 

new ET_Builder_Module_Image;

Copy the entire class of the module you want to use including that last ‘new ET_Builder’ line and paste it inside your module file, replacing the comment of ‘this is where your new module class will go’.

3) Time to do some hacking.

Firstly you need to rename the Class Name of the new module and the slug. The default Image Module class looks like this

class ET_Builder_Module_Image extends ET_Builder_Module {
  function init() {
    $this->name = esc_html__( 'Image', 'et_builder' );
    $this->slug = 'et_pb_image';

For our new module we would do something like this

class ET_Builder_Module_Image2 extends ET_Builder_Module {
  function init() {
    $this->name = esc_html__( 'Image 2', 'et_builder' );
    $this->slug = 'et_pb_image2';

Note that it is very important to keep the et_pb_ prefix for the module slug, otherwise the Divi Builder won’t load the module.

Then we need to change how the instance of the new class is called, as well as add the shortcode for it (so that WordPress can render your module on the website). At the moment it says this:

new ET_Builder_Module_Image;

We need to change it to this

$et_builder_module_image2 = new ET_Builder_Module_Image2();
add_shortcode( 'et_pb_image2', array($et_builder_module_image2, '_shortcode_callback') );

using the new class name and the new slug.

NOTE: if you want to override an existing module with a customised version (not add a new one), you only need to change the class name of the module, not the slug. Also you need to replace the shortcode for that module.

class ET_Builder_Module_Image2 extends ET_Builder_Module {
  function init() {
    $this->name = esc_html__( 'Image', 'et_builder' );
    $this->slug = 'et_pb_image';


$et_builder_module_image2 = new ET_Builder_Module_Image2();
remove_shortcode( 'et_pb_image' );
add_shortcode( 'et_pb_image', array($et_builder_module_image2, '_shortcode_callback') );


Anyway, we’re building a new module, so your final custom module file looks something like this:

function ex_divi_child_theme_setup() {

   if ( class_exists('ET_Builder_Module')) {

      class ET_Builder_Module_Image2 extends ET_Builder_Module {
         function init() {
            $this->name = __( 'Image', 'et_builder' );
            $this->slug = 'et_pb_image2';
            // a whole bunch of php code that defines how the class functions
      $et_builder_module_image2 = new ET_Builder_Module_Image2();
      add_shortcode( 'et_pb_image2', array($et_builder_module_image2, '_shortcode_callback') );


add_action('et_builder_ready', 'ex_divi_child_theme_setup');


Now you are ready to start making changes to the module’s code and build your custom module functionality.

Happy hacking…

UPDATE: During preparation of this article I discovered that my custom modules weren’t always loading into the Page Builder. I couldnt figure out why until I found out how the Divi Page Builder caching works. So make sure you check that as well.

62 responses to “Building your own Divi Builder Modules”

  1. Love this Jonathan, thank you 🙂

    Could you briefly explain how we link the custom CSS for the module, do we just use the custom class we created in the PHP file?

    • Hi Michelle, thanks.

      Whatever module you create in this method is going to use the ‘slug’ as one of the class names for the div that contains the module. So if you need to write any custom CSS for your new module, you can use the slug name as the parent and then style child elements accordingly. If you take a look at the html for the Image Overlay demo you will see what I am talking about.

      I think that perhaps a follow up article on this topic would be a good idea.

  2. Jonathan, I can’t thank you enough for taking the time to carefully write this up and share it.

    A couple of weeks ago, I did a search and came across only two pages on the topic of creating custom modules, neither of which went very much into depth. At first, I did not realize that the slug had to start with ‘et_pb_’ – took a LOT of trial and error to figure that on out lol!

    I then finally had the idea down, and it was working for the most part, but I struggled at first with changing options in the module and not having them show up right.

    With this article, you’ve shown that you don’t have to have all the code to test for admin, page rights, etc. etc. that I found on Stack Overflow, and your reference to the cache clearing plugin finally wrapped everything up for me.

    Thanks a million times for this careful write-up! It opens up a whole new world of possibilities, and it is truly exciting (and relieving!) when things work right. This is a great tutorial. 🙂


    • Thanks Terry. For my part this article was because I found various other articles online that had half the picture, but I still had to piece some of it together myself. I’m all about sharing so this post came out of that. If it helps another developer save a few hours and focus on what they actually want to build, all the better.

      • Great philosophy, and thanks again. I’d offer a big man hug and maybe even a bit of foot kissing, but the distance is too great…

  3. I followed this example to the letter with one exception (I made it a plugin instead of a child theme). I have everything working… but when I go to use my new module and then save the page or post the module does not show up in the Divi Builder layout section. Have you ever seen this before? Do you know what I’m missing? I tried it twice.

  4. Hey, thanks for your post.
    I’m french developer and I would like to know how catch javascript event when module’s setting box is displayed to update custom fields values.

    • Hi Sébastien

      I’m not 100% sure what you mean, perhaps you could explain it a little bit further?

  5. Great intro to building Divi modules. I don’t understand why it’s not in the official Divi documentation?

    • I think Elegant Theme’s focus has probably been on the user rather than the developer. I don’t think anyone could have foreseen the third party developer community that has grown around Divi. I believe that Nick Roach has indicated that they do plan on releasing a ‘developer edition’ that will include better documentation for developers.

      Having said all that, I do like the challenge of figuring out how Divi is put together, so having developer documentation will be taking away a bit of the mystery…

  6. I tried this method for Divi 3 . But I am afraid, It does not work there. Can you please give me a clue on it?

    • Hi there

      If you mean being able to build a module for Divi 3.0, this should still work, however I can’t guarantee it will work in the new Divi Visual Builder. I am still working through the code to understand how that all works.

      However once I figure it out I’ll post an update.

      • At this stage and until ET issues the dev documentation, any third party modules will not be included in the Insert List within VB. However, if a third party module can be inserted in legacy mode (page builder), then it’s content will appear in PB but you won’t be able to modify it.

          • Awesome, Philipp! When I found the bundle when I first was concerned with 3.0.0, I just threw up my hands. I’m told 3.1 will have a dev pack which will obviously have to deal with the bundle, but hopefully it will have an interface of some kind that masks what you’ve discovered ;^)

            If I were concerned with just my own personal site, I’d jump on your discovery, but how do you give the novice confidence with this given there’s been 18 or so releases since 3.0.0?

  7. I can’t get the code to work in Divi 3.0. I get an error (all the code displayed on a blank website) when trying to “update” the custom php file.

    • I didn’t look at the second link, but the first one appears to be guidance on how to REPLACE the core module. In the end, if that works for you on a site by site basis, nothing wrong with the approach.

      Still, there’s no guarantee that your modifications will work in Divi 3+ VB, but if you keep it simple, it probably will, IMO.

  8. Aaaaaarg! Pleeeease help here before I throw my laptop into the wall with all the force my nerdy but capable arms can muster!

    Once i’ve set a slug (or use an existing), how do I change which fields/options are displayed in the module settings??

    If I e.g. want to remove the “open image in lightbox” switch when trying to add a custom module that OVERRIDES the existing “et_pb_image”?

    I can get it to work if I create a new slug for each change I want to make ..but that caaan’t be the way to do this :-/

    Any solution / help to (what’s probably a simple thing) will make my day ..and thanks a zillion in advance! 🙂

      • Hi there Jonathan,

        thanks a lot for the comment. I already found something similar I juuust managed to get it working before I wrecked anything 🙂

        What I added was this:

        function remove_from_local_storage() {
        global $slug;
        echo “localStorage.removeItem(‘et_pb_templates_”.esc_attr($slug).”‘);”;

        Maybe it’s useful for someone else…

        I have ANOTHER question for you though!

        Can you perhaps help me out in displaying / hiding certain fields in the module options in admin depending on a value chosen in a dropdown?

        Something like when “yes” to custom borders and then having the border options appear …only here having e.g. 3 of my own custom fields appear…

        Again: thanks for your nice post and any help you can give 🙂

        Kind regards

  9. Hi Jonathan,

    Wistia videos are not currently supported by Divi. I can add them through the use of a oEmbed url through a text module. Therefore I need to customise the Video slider module to add the oEmbed url so that Wistia videos will work. Thus I want to add a text box region to the Video slider module.

    Following your documentation I can add my own custom Video slider, however I can’t get the vider_slider_item class to work. I tried renaming it, however this is the actual class I need to edit and it’s not being registered. I have followed your instructions except did it with 2 classes in the 1 file instead of 1 class.

  10. Hello! How incredible is this tutorial. I have been following it and managed to overwrite the current module of images. However, I have a question: when I am trying to define the default values ​​for the plugin, I make them in this section:

    $this->fields_defaults = array(
    ‘show_in_lightbox’ => array( ‘off’ ),
    ‘url_new_window’ => array( ‘off’ ),
    ‘animation’ => array( ‘off’ ),
    ‘sticky’ => array( ‘off’ ),
    ‘align’ => array( ‘right’ ),
    ‘force_fullwidth’ => array( ‘off’ ),
    ‘always_center_on_mobile’ => array( ‘off’ ),
    ‘use_overlay’ => array( ‘off’ ),

    The problem is that when loading the module from Divi Builder, I still appear by default the original options and not the ones I just modified.

    I followed the steps to delete the local storage but I did not get results. Does anyone know if that is the section that I should modify?

    P.S. I’m working with the Divi Builder plugin on a theme I’m doing from scratch.

    • Hi Wolfgang

      I’d have to see (and test) your full code to see what’s going on. What I do know is that you pretty much need to clear the Divi Page Builder cache every time you make a change to your custom module. So I usually have my browser console open, make changes to the module code, run the clear Page Builder cache snippet and then hard refresh the page I am using to test.

  11. Hi, great art, it’s a pity that i didn’t found it earlier (now i know how-to build new module). But i’ve got other problem – how to add new section type or how to create module with two children (like tabs module with tab child).

    • Hi Motylo, You will need to go through the code for how those modules are built to understand how that works.

      If you do a search for the class for the Tabs module (ET_Builder_Module_Tabs) I think it has a child_slug field which relates to the child module it uses.

      The same goes for sections, you’ll need to search for how sections are built to understand how to create new ones.

      I recommend reading through the Divi code to understand how it all fits together, it’s the only way I can figure these things out myself 🙂

      • Hi,
        After some code reading found out that currently isn’t possible to (in simple like new modules way):
        – add more child slugs – like in Highlander – there can be only one.
        – add new type of row/section – it’s coded in js file, so only injection work.

        Looking forward to new version of Divi and “simpler way” of creating modules that work with Visual Builder.

  12. Hi Jonathan,

    Thank you for taking the time to put this article together.

    Apropos to this conversation, do you happen to know of any plugins that would allow me to wrap Divi rows and modules in shortcode?

    Or maybe there’s a 3rd party solution for this?

    I know Divi Booster allows you to view the HTML generated by an element, so conceivably I could simply generate the HTML, replace the element with a Code element and wrap THAT in shortcode, but it would make it difficult to make tweaks.

    I would be very grateful for any recommendations you have around this.

    Our use case is a membership site where we use shortcodes to perform various actions based on permissions, etc.

    Thanks Jonathan, have a nice day!


    • It’s not too complicated to do. I started this weekend.

      I first made a small extension that works with Divi Extender and injects a Divi library layout.

      I also have an extension that retrieves the IDs. With a shortcode function to set in functions.php

      The first works as a module code but with the list of layouts of the divi library. The problem is that I used the shortcode to inject the provisions into the modules tabs.

      I will try to combine the two to have a shortcode in the text editor.

      If you are interested you can have it (free) here:


      • Hi Leif

        At this time no, most module developers are waiting on the Divi Developers release, which will hopefully provide some guidance on how to do that.

        • Hi Jonathan,
          So it looks like my implementation is partially working. I have it appearing in the admin and it’s saving, but I don’t see appearing in the front-end. What am I missing?
          I’m using Divi 3 so I wonder if this is still not possible with that version.
          Thank you!!

  13. Hi, I’ve created a custom post type named Video Gallery. My problem is how to create a custom module that is same as blog module but calling my Video Gallery post?

  14. Hi guys,

    How can I edit the button module to add the gradient pickers under the current background color picker? This drives me crazy for a month or so.


  15. Hi there,

    First of all I’d like to thank you for this great tutorial. I’ve tested for Divi Builder Galleries and works like charm. 🙂 I used it for displaying the excerpt down the gallery title when choosing modal slideshow.

    However I’ve found that it works great when using Divi Builder (obviously) but it doesn’t when Divi is my theme but no Builder is used (traditional way of creating galleries in WP). This happens even (apparently) the same module is called to display the gallery.

    I’d like to know if is there any way this both Divi Builder Gallery and traditional shortcode display the excerpt under the title.


    • This article is specific to building Divi plugins, so it would not apply to any non Divi modules or shortcodes.

  16. Hello!

    First, this was incredibly helpful, so thank you!

    I’m trying to build a custom button module that’s offers the bare minimum style controls for a client. (I figured if I had to customize the module to allow certain styling capabilities, I might as well pare down the options, too.)

    I would love to get rid of the “Use Custom Styles for Button,” “Spacing,” “Box Shadow,” “Filter,” and “Animation” sections under the design tab, but they seem to be universal options for all modules. Is it possible to remove these fields?

  17. Hi dear Jonathan, this tutorial is awesome for its potential. Also, even with the last Divi 3 version It worked for me, using the Blog module file within the theme modules folder…

    But my plan was to change the Post slider module to show Woocommerce products instead (referring to this topic : Hoping that the suggested codes could lead to a sustainable solution.
    Finally I would have changed each module regarding their specific needs, adding more than one CPT or selecting categories.

    Sadly I’m not (yet) in the scope of PHP development, so I can only copy-paste smart written solutions when they appear.

    Also while trying to build a new module from the Post slider I encountered an error each time I activated the functions.php related code.

    functions.php :
    /* include custom image module file*/
    include(get_stylesheet_directory() . ‘/Module-PostSlider-Woo.php’);

    I tried with this starting code on top of the custom ” Module-PostSlider-Woo.php” file :

    function ex_divi_child_theme_setup() {
    if ( class_exists(‘ET_Builder_Module’)) {

    class ET_Woo_Post_Slider extends ET_Builder_Module_Type_PostBased {
    function init() {
    $this->name = esc_html__( ‘Post Slider Woo’, ‘et_builder’ );
    $this->slug = ‘et_pb_post_slider_woo’;
    $this->fb_support = true;

    and alternatively :

    function ex_divi_child_theme_setup() {
    if ( class_exists(‘ET_Builder_Module’)) {

    class ET_Woo_Post_Slider extends ET_Builder_Module {
    function init() {
    $this->name = esc_html__( ‘Post Slider Woo’, ‘et_builder’ );
    $this->slug = ‘et_pb_post_slider_woo’;
    $this->fb_support = true;

    ending with :

    $et_woo_post_slider = new ET_Woo_Post_Slider();
    add_shortcode( ‘et_pb_post_slider_woo’,
    ‘_shortcode_callback’) );

    add_action(‘et_builder_ready’, ‘ex_divi_child_theme_setup’);

    Without any internal change for testing purpose.
    It’s displaying the error at the closing brackets, just before the last line of code.

    I don’t see why it’s not working after several trials while the blog custom module worked..

    You would be so clever to show a convenient way to ensure this custom modules building and ensuring the right way to change included post types & optionally categories…

    All best while I truly appreciate your absolutely qualitative work.

    • Hi Thibault, it’s hard to determine the cause of the problem based on the code snippets you’ve posted and to be honest the comments area of a blog post is not the optimum place for solving a problem. If you’d like me to investigate your child theme in order to suggest a solution, please consider hiring me for a consultation from the ‘Hire me’ link in the menu.

      • Thanks for your quick overlook. For now I should have found an alternative solution but remind you for a next need.

        By the way I would suggest a clever update for this post if you mind it to make any Divi module compatible with CPT content. That would be so awesome.


  18. PS : strangely enough my comment was added as a reply above but was intended as a new topic.

  19. Hi,

    Wow! Great tutorial, Thanks alot.

    It’s only working when i am editing page with backend builder, but when i am editing page through frontend builder, it generate following error

    “function (t){return s.a.createElement(p.a,g({rawContentProcesser:_.a.replaceCodeContentEntities},e.props))}”

    I’ve checked browser’s console, there is no JS error.

    I’m using Divi Version: 3.3.1
    Am i missing something in code ?

    Thank you!!

  20. In Divi 3.1x this file no longer contains the module classes mentioned above. How should we proceed now?


  21. I have my own block of html code styled with some css and animated with some JavaScript. Do I have to do what is described here to add it to the page or is there a simpler way to add it?

    • No, unfortunately this is very much out of date, and I’ve not worked with Divi modules in a long time, so I don’t know how things have changed since then.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: