Asset Management

⌘K
  1. Home
  2. Docs
  3. Developers “How To&...
  4. Asset Management

Asset Management

This document explains how to properly include and manage assets (CSS, JavaScript, images, fonts) in WPBakery Page Builder elements, and how to use the plugin’s built-in assets.

Asset Types

WPBakery elements can include several types of assets:

  1. CSS files – Styling for your elements
  2. JavaScript files – Interactive functionality
  3. Images – Icons, placeholders, backgrounds
  4. Fonts – Custom icon fonts or web fonts
  5. External libraries – jQuery plugins, icon libraries, etc.

 

Asset Loading Methods

1. Using wp_enqueue_* Functions (Recommended)

The standard WordPress way to include assets:

<?php

/**
 * Enqueue element assets
 */

function enqueue_custom_element_assets() {
    // CSS
    wp_enqueue_style(
        'custom-element-style',                              // Handle
        plugins_url( 'assets/css/custom-element.css', __FILE__ ), // URL
        [],                                                   // Dependencies
        '1.0.0',                                             // Version
        'all'                                                // Media
    );

    // JavaScript
    wp_enqueue_script(
        'custom-element-script',                             // Handle
        plugins_url( 'assets/js/custom-element.js', __FILE__ ), // URL
        ['jquery'],                                          // Dependencies
        '1.0.0',                                             // Version
        true                                                 // In footer
    );

    // Pass data to JavaScript
    wp_localize_script(
        'custom-element-script',                             // Script handle
        'customElementData',                                 // Object name
        [
            'ajaxUrl' => admin_url( 'admin-ajax.php' ),
            'nonce' => wp_create_nonce( 'custom-element-nonce' ),
        ]
    );
}

When to Enqueue

A. Always Load (Global)

// For frontend

add_action( 'wp_enqueue_scripts', 'enqueue_custom_element_assets' );

// For backend editor

add_action( 'admin_enqueue_scripts', 'enqueue_custom_element_assets_admin' );

function enqueue_custom_element_assets_admin( $hook ) {
    // Only on page editor pages
    if ( 'post.php' === $hook || 'post-new.php' === $hook ) {
        wp_enqueue_style( 'custom-element-admin' );
    }
}

B. Conditional Loading (When Element is Used)

// In your shortcode class

class WPBakeryShortCode_Custom_Element extends WPBakeryShortCode {
    /**
     * Enqueue assets only when element is used
     */

    public function __construct( $settings ) {
        parent::__construct( $settings );
        // Frontend
        add_action( 'wp_enqueue_scripts', [ $this, 'enqueueAssets' ] );
        // Backend editor
        add_action( 'admin_enqueue_scripts', [ $this, 'enqueueAdminAssets' ] );
    }

    /**
     * Frontend assets
     */

    public function enqueueAssets() {
        wp_enqueue_style(
            'vc-custom-element',
            plugins_url( 'assets/css/element.css', __FILE__ ),
            [],
            '1.0.0'
        );

        wp_enqueue_script(
            'vc-custom-element',
            plugins_url( 'assets/js/element.js', __FILE__ ),
            ['jquery'],
            '1.0.0',
            true
        );
    }

    /**
     * Backend editor assets
     */
    public function enqueueAdminAssets() {
        wp_enqueue_style( 'vc-custom-element-admin' );
        wp_enqueue_script( 'vc-custom-element-admin' );

    }

}

C. Lazy Loading (Only on Pages Using Element)

// Track if element is used
$custom_element_used = false;

// In shortcode output function
function custom_element_shortcode( $atts, $content = null ) {
    global $custom_element_used;
    $custom_element_used = true;
}

// Enqueue only if used
add_action( 'wp_footer', 'maybe_enqueue_custom_element_assets' );
function maybe_enqueue_custom_element_assets() {
    global $custom_element_used;
    if ( $custom_element_used ) {
        wp_enqueue_style( 'custom-element' );
        wp_enqueue_script( 'custom-element' );
    }
}

2. Inline Styles and Scripts

For small, element-specific code:

// In template file
$custom_css = "
.custom-element-{$unique_id} {
    background-color: {$bg_color};
    padding: {$padding}px;
}
";

$output = '<style>' . esc_html( $custom_css ) . '</style>';
$output .= '<div class="custom-element-' . esc_attr( $unique_id ) . '">';
// ... element content
$output .= '</div>';
// For JavaScript
$custom_js = "
jQuery(document).ready(function($) {
    $('.custom-element-{$unique_id}').customPlugin();
});
";

$output .= '<script>' . $custom_js . '</script>';

Warning: Use sparingly as it can cause performance issues and duplicate code.

3. Using vc_* Helper Functions

WPBakery provides helper functions for common assets:

// Enqueue icon fonts

vc_icon_element_fonts_enqueue( 'fontawesome' );  // Font Awesome
vc_icon_element_fonts_enqueue( 'openiconic' );   // Open Iconic
vc_icon_element_fonts_enqueue( 'typicons' );     // Typicons
vc_icon_element_fonts_enqueue( 'entypo' );       // Entypo
vc_icon_element_fonts_enqueue( 'linecons' );     // Linecons
vc_icon_element_fonts_enqueue( 'material' );     // Material Icons
// In your template

if ( 'fontawesome' === $icon_type ) {
    vc_icon_element_fonts_enqueue( 'fontawesome' );
}

 

Working with Images

1. Element Icons (Editor)

// In config file

return [
    'name' => 'Custom Element',
    'base' => 'custom_element',
    'icon' => 'icon-wpb-custom',  // CSS class
    // or
    'icon' => plugins_url( 'assets/images/element-icon.png', __FILE__ ),
];

2. Content Images

// In template - using WordPress attachment

$image_id = $atts['image'];
$image_src = wp_get_attachment_image_src( $image_id, 'full' );
if ( $image_src ) {
    $output .= '<img src="' . esc_url( $image_src[0] ) . '" ';
    $output .= 'width="' . esc_attr( $image_src[1] ) . '" ';
    $output .= 'height="' . esc_attr( $image_src[2] ) . '" ';
    $output .= 'alt="' . esc_attr( get_post_meta( $image_id, '_wp_attachment_image_alt', true ) ) . '" />';
}

// Or use WordPress function

$output .= wp_get_attachment_image( $image_id, 'large', false, [ 'class' => 'custom-image' ] );

3. Background Images

// Using CSS
$image_url = wp_get_attachment_image_src( $atts['bg_image'], 'full' );
if ( $image_url ) {
    $inline_style = 'background-image: url(' . esc_url( $image_url[0] ) . ');';
    $output .= '<div class="element" style="' . esc_attr( $inline_style ) . '">';
}

4. Responsive Images

// Generate srcset for responsive images

$image_id = $atts['image'];
$image_src = wp_get_attachment_image_src( $image_id, 'full' );
$image_srcset = wp_get_attachment_image_srcset( $image_id, 'full' );
$image_sizes = wp_get_attachment_image_sizes( $image_id, 'full' );
$output .= '<img src="' . esc_url( $image_src[0] ) . '" ';
if ( $image_srcset ) {
    $output .= 'srcset="' . esc_attr( $image_srcset ) . '" ';
}

if ( $image_sizes ) {
    $output .= 'sizes="' . esc_attr( $image_sizes ) . '" ';
}

$output .= 'alt="" />';

Working with Fonts

1. Web Fonts (Google Fonts, etc.)

// Enqueue Google Fonts
function enqueue_custom_fonts() {
    wp_enqueue_style(
        'custom-google-fonts',
        'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap',
        [],
        null
    );
}

add_action( 'wp_enqueue_scripts', 'enqueue_custom_fonts' );

// Use in CSS
.custom-element {
    font-family: 'Roboto', sans-serif;
}

2. Custom Icon Fonts

// Enqueue custom icon font

function enqueue_custom_icon_font() {
    wp_enqueue_style(
        'custom-icons',
        plugins_url( 'assets/fonts/custom-icons/custom-icons.css', __FILE__ ),
        [],
        '1.0.0'
    );
}

add_action( 'wp_enqueue_scripts', 'enqueue_custom_icon_font' );

CSS (custom-icons.css):

@font-face {
    font-family: 'CustomIcons';
    src: url('custom-icons.woff2') format('woff2'),
         url('custom-icons.woff') format('woff'),
         url('custom-icons.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: block;
}

.custom-icon {
    font-family: 'CustomIcons';
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.custom-icon-home:before {
    content: "\e001";
}

.custom-icon-star:before {
    content: "\e002";
}

External Libraries

jQuery Plugins

function enqueue_jquery_plugin() {

    // Enqueue the plugin

    wp_enqueue_script(
        'slick-slider',
        plugins_url( 'assets/lib/slick/slick.min.js', __FILE__ ),
        ['jquery'],
        '1.8.1',
        true
    );

    // Enqueue plugin CSS
    wp_enqueue_style(
        'slick-slider',
        plugins_url( 'assets/lib/slick/slick.css', __FILE__ ),
        [],
        '1.8.1'
    );
}

add_action( 'wp_enqueue_scripts', 'enqueue_jquery_plugin' );

 

Best Practices

  1. Always use wp_enqueue_* – Never hard-code script/style tags
  2. Register first, enqueue later – Improves performance
  3. Use version numbers – For cache busting
  4. Declare dependencies – Ensure load order
  5. Load in footer when possible – Better page performance
  6. Minify production assets – Reduce file sizes
  7. Use CDNs with fallbacks – Improve loading speed
  8. Conditional loading – Only load what’s needed
  9. Proper escaping – Always escape URLs and attributes
  10. RTL support – Provide RTL styles when needed

 

Troubleshooting

Assets Not Loading

  1. Check file paths and URLs are correct
  2. Verify hooks are firing (use did_action())
  3. Check for JavaScript errors in console
  4. Ensure dependencies are loaded first
  5. Check file permissions

Style Conflicts

  1. Use specific CSS selectors
  2. Increase specificity without !important
  3. Use unique class prefixes
  4. Check for theme/plugin conflicts
  5. Test with default theme

Script Errors

  1. Check browser console for errors
  2. Verify jQuery is loaded (check dependencies)
  3. Ensure script runs after DOM ready
  4. Check for namespace conflicts
  5. Use try-catch for error handling
Was this article helpful to you? No Yes

How can we help?