I am trying to create an image control using:

  new wp.customize.Control(
      type: "image",
      button_labels: {select: 'Select image', change: 'Change image', remove: 'Remove', default: 'Default', placeholder: 'No image selected'...}
      description: "Upload or select an image for this featured link"
      id: "issue_section_term_apple_settings_link_image"
      label: "Custom image"
      priority: 1
      section: "issue_section_term_apple_section"

I am using the "type" property and set it to "image" which is what the WP_Customize_Image_Control php class has set for the class "type" property.

This is only spitting out the label and description, and an empty "attachment media view" div and doesnt produce an active media UI:

<div class="attachment-media-view">
    <div class="actions">

Do I need to instantiate the control another way, or trigger a JS function to activate the controls?

Also - somewhat related. Because I am creating the control via javascript that means that wont work right? I am trying to toggle this control based on the value of another control. Will I need to manually bind the controls together?

1 Answer 1


You would just need to add a canUpload: true to your control's options (the 2nd parameter for wp.customize.Control) and then the .actions div would have an upload button.

However, clicking the button would not do anything (the media modal/popup would not appear), hence you need to instead use the specific class for image upload control, which is wp.customize.ImageControl.

Working Example (tested with WordPress v5.9.3):

wp.customize.control.add( new wp.customize.ImageControl( myControlSettingID, {
    section: 'issue_section_term_apple_section',
    label: 'Custom image',
    button_labels: {
        select: 'Select image',
        frame_title: 'Select image',
        frame_button: 'Choose image'
    canUpload: true,
    setting: wp.customize( myControlSettingID )
} ) );

Remember though, that the image upload control will return only the image URL, so if you need its ID, then use new wp.customize.MediaControl instead.

References, or resources that might help you further:

As for this:

I am trying to toggle this control based on the value of another control. Will I need to manually bind the controls together?

Excerpt from the 3rd link/resource above:

There are also activate() and deactivate() methods now for manipulating this active state, for panels, sections, and controls. The primary purpose of these states is to show or hide the object without removing it entirely from the Customizer.

So if that's your purpose, then you can use the above methods, like Twenty Twenty-One did, like so: (see assets/js/customize.js)

// Wait until the customizer has finished loading.
wp.customize.bind( 'ready', function() {
    // Hide the "respect_user_color_preference" setting if the background-color is dark.
    if ( 127 > twentytwentyoneGetHexLum( wp.customize( 'background_color' ).get() ) ) {
        wp.customize.control( 'respect_user_color_preference' ).deactivate();
        wp.customize.control( 'respect_user_color_preference_notice' ).deactivate();

} );
  • sweet this is great! I'll give this a shot once i fix my dev environment.
    – rugbert
    Commented May 13, 2022 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.