Learn how to create a custom WPBakery Visual Composer element in WordPress. This tutorial guides you step-by-step to build a custom info box element with title and content fields for WPBakery using vc_map().
If you’ve built WordPress pages for any length of time, you’ve probably dragged blocks around in Visual Composer. Here’s the part that trips people up: the plugin most of us know by that name was renamed to WPBakery Page Builder back in 2015. Same drag-and-drop builder, same shortcodes, different label.
Why call that out? Because in 2017 the same company shipped a completely separate product named Visual Composer Website Builder. Two tools, one overlapping name. This tutorial is about the original shortcode-based builder, now called WPBakery Page Builder, the one that registers elements with vc_map(). If that function is in your toolkit, you’re in the right place.
What we’re building is a reusable “Info Box” element with a title and a content field. Once it’s registered, you can drop it into any layout straight from WPBakery’s visual interface and fill it in like any built-in element.
Step 1: Create a New Folder for Custom Elements
Open your active theme folder and create a folder named vc-elements. Every custom element we build lives here, so the theme stays tidy and your elements travel with it.
Step 2: Modify functions.php to Register Custom Elements
Open your theme’s functions.php and add the code below. It checks that WPBakery is actually active before loading anything, then pulls in the element files from vc-elements. The guard matters: without it, your site fatals on any install where the builder isn’t running.
Code to Add in functions.php:
<?php
/**
* Visual Composer custom elements.
*/
function vc_before_init_actions() {
// Stop if Visual Composer is not enabled.
if ( ! defined( 'WPB_VC_VERSION' ) ) {
return;
}
// Visual Composer custom elements list.
require_once( get_template_directory() . '/vc-elements/infobox.php' );
}
add_action( 'init', 'vc_before_init_actions' );Note: We’re building an “Info Box” with a title and a content (textarea) field. Treat it as a starting point and add fields as you need them.
Step 3: Create the infobox.php File
Inside the vc-elements folder, create a file named infobox.php. This is where the element’s logic and its WPBakery mapping go.
Step 4: Extend WPBakeryShortCode and Register the Element
In infobox.php, extend the WPBakeryShortCode class to handle the front-end output, then register the element with vc_map() so it shows up in the editor. Here’s the full code:
Code for infobox.php:
<?php
/**
* Class to load for this map.
*/
class VC_Custom_InfoBox extends WPBakeryShortCode {
/**
* Shortcode display.
*/
protected function content( $atts, $content = null ) {
// Variables.
$display = '';
$attr = array();
extract(
shortcode_atts(
array(
'title' => '',
'content' => ''
), $atts )
);
// Display html.
$display .= '<div class="infobox__wrapper">';
$display .= '<h3 class="infobox__title">' . esc_html( $title ) . '</h3>';
$display .= '<p class="infobox__content">' . esc_html( $content ) . '</p>';
$display .= '</div>';
return $display;
}
}<?php
/**
* VC Map elements.
*/
vc_map( array(
'base' => 'vc_custom_infobox',
'name' => esc_html__( 'Info Box', 'text-domain' ),
'description' => esc_html__( 'Display custom infobox', 'text-domain' ),
'class' => '',
'category' => esc_html__( 'Visual Composer Custom Elements', 'text-domain' ),
'params' => array(
array(
'type' => 'textfield',
'heading' => esc_html__( 'Title', 'text-domain' ),
'param_name' => 'title',
'value' => ''
),
array(
'type' => 'textarea',
'heading' => esc_html__( 'Content', 'text-domain' ),
'param_name' => 'content',
'value' => ''
)
)
) );Two things are happening here. The base value, vc_custom_infobox, is the shortcode tag WPBakery generates. The params array defines the fields the editor draws: a text field for the title and a textarea for the content. When someone edits the element, whatever they type flows into the content() method above and comes out as escaped HTML. The esc_html() calls aren’t decoration; they keep user input from becoming a markup problem.
Step 5: Use Your New Custom Element
Save your files and open a page in the WPBakery editor. The Info Box shows up under the “Visual Composer Custom Elements” category you named in the map. Drag it in, set a title and content, and you’re done. Want a second element? Repeat the pattern: a new file in vc-elements, a class for the output, a vc_map() call to register it.
Conclusion
That’s a working custom element, front-end output and editor controls included. From here you can add more parameter types (color pickers, dropdowns, attach images) or spin up entirely new elements the same way.
One honest caveat: vc_map() is still the documented way to register elements in WPBakery Page Builder, but it’s tied to that specific plugin. If a client is running the newer Visual Composer Website Builder instead, this code won’t apply, and that’s exactly the name confusion worth double-checking before you start.
For the full parameter reference, see the official documentation: VC Map Inner API.


