Introduction
For more up-to-date, detailed information about the Customizer API, please see the new official documentation in the theme handbook: https://developer.wordpress.org/themes/advanced-topics/customizer-api/.

The Theme Customization API, added in WordPress 3.4, allows developers to customize and add controls to the “Appearance” → “Customize” admin screen. The Theme Customization screen (i.e. “Theme Customizer”) allows site admins to tweak a theme’s settings, color scheme or widgets, and see a preview of those changes in real time.

This page documents the Theme Customization API (Application Programming Interface), and how to implement it in your own themes.

This article assumes you have already read Theme Development and Writing a Plugin, which give an overview (and many details) of how to develop custom themes and plugins for WordPress. This article also requires a functional understanding of object-oriented programming. A familiarity with the WordPress Settings API should be very helpful as well.

Note: This information applies to WordPress Version 3.4 and higher.

Developing for the Customizer
Whether you are a theme or plugin developer, you can use this API to add more powerful, interactive customization options to your theme or plugin.

To add your own options to the Customizer, you need to use a minimum of 2 hooks:

customize_register
This hook allows you to define new Customizer panels, sections, settings, and controls.
wp_head
This hook allows you to output custom-generated CSS so that your changes show up correctly on the live website.
Note: Optionally, the customize_preview_init hook can also be used for enqueuing custom JavaScript on the Customizer screen. JavaScript can be used for making the Customizer more responsive and powerful, but this step is not required.

Important: Do not conditionally load your Customizer code with an is_admin() check. If you only add your customize_register if is_admin(), then any panels, sections, or controls will be unavailable when the Customizer preview loads. As of WordPress 4.1, there are contextual panels, sections, and controls so that they can be displayed only on certain URLs being previewed. If you only register your panels, sections, and controls if is_admin() then you’ll be effectively saying that these are not contextual to any URL on your site. For more information, see #30387 and #29758.

Part 1: Defining Settings, Controls, Etc.
Any new Theme Customizer settings, sections, or controls must be defined from within a customize_register action. This action automatically loads the $wp_customize object, which is an instance of the WP_Customize_Manager class.

First, define the action like this:

function mytheme_customize_register( $wp_customize ) {
//All our sections, settings, and controls will be added here
}
add_action( ‘customize_register’, ‘mytheme_customize_register’ );

Note that the $wp_customize object is passed automatically to the function, and all customizations you make to the Theme Customization page are performed through methods of the $wp_customize object.
Next, you need to define your settings, then your sections, then your controls (controls need a section and a setting to function).

Adding a New Setting
Settings automatically use WordPress’s theme_mod features to get/set settings for your theme.

To add a new setting to your Theme Customizer, you need to call the $wp_customize->add_setting() method. By defining your setting this way, you don’t need to do any extra work to create, save, or fetch settings for your theme.

Adding a theme setting (within the ‘customize_register’ action) might look like this:

$wp_customize->add_setting( ‘header_textcolor’ , array(
‘default’   => ‘#000000′,
‘transport’ => ‘refresh’,
) );

Note: The ‘transport’ argument is optional, and defaults to ‘refresh’. If left to default, then the theme customizer’s preview window will update by completely reloading itself when this setting is changed. If you would prefer to avoid refreshes and improve responsiveness, you can set this to ‘postMessage’ instead, then handle any styling updates manually with a bit of JavaScript (see the Configure Live Preview section below).
Adding a New Section
Sections are groups of options. When you define new controls, they must be added to a section. Although you can add controls to existing default sections, we will briefly cover adding a new section.

To add a new section to your Theme Customizer, you need to call the $wp_customize->add_section() method.

Adding a theme section (within the ‘customize_register’ action) might look like this:

$wp_customize->add_section( ‘mytheme_new_section_name’ , array(
‘title’      => __( ‘Visible Section Name’, ‘mytheme’ ),
‘priority’   => 30,
) );

WordPress does include a few built-in sections. If you want to use any of the existing, built-in ones, you don’t need to declare them with add_section(). Instead, refer to them by name. The following sections are built-in:
title_tagline – Site Title & Tagline (and Site Icon in WP 4.3+)
colors – Colors
header_image – Header Image
background_image – Background Image
nav – Navigation
static_front_page – Static Front Page
Adding a New Control
A control is an HTML form element that renders on the Theme Customizer page and allows admins to change a setting, and preview those changes in real time. Controls are linked to a single setting, and a single section.

To add a new control to your Theme Customizer, you need to call the $wp_customize->add_control() method.

Adding a control to a theme section (within the ‘customize_register’ action) might look like this:

$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, ‘link_color’, array(
‘label’      => __( ‘Header Color’, ‘mytheme’ ),
‘section’    => ‘your_section_id’,
‘settings’   => ‘your_setting_id’,
) ) );

Controllers have quite a few options, some of which require passing it another class (such as the WP_Customize_Color_Control() class shown in the above example). For more examples, see the documentation for add_control()
Part 2: Generating Live CSS
Finally, you just need to make sure that you’re fetching the settings and outputting any necessary CSS into your header. If you defined your settings within a ‘customize_register’ action, as described above, then getting your setting values is as simple as outputting css with ‘wp_head’ action and fetching the values with get_theme_mod()

For example, let’s say you have a setting called ‘header_color’ and it looks like this:

$wp_customize->add_setting( ‘header_color’ , array(
‘default’     => ‘#000000′,
‘transport’   => ‘refresh’,
) );

Your code to output the css into the header might look something like this:

function mytheme_customize_css()
{
?>
<style type=”text/css”>
h1 { color: <?php echo get_theme_mod(‘header_color’, ‘#000000′); ?>; }
</style>
<?php
}
add_action( ‘wp_head’, ‘mytheme_customize_css’);

When you look at the page source you would see the following in the header:
<style type=”text/css”>
h1 {color:#000000;}
</style>
You will notice that the default value of #000000 is given for the color. Once this value is changed via the customizer, the new value will be shown. For example, let’s say you wanted to change the color to white. In the customizer, you insert the hex value for white, #ffffff, click Save and Publish.

Now in the page source you will see:

<style type=”text/css”>
.h1 {color:#ffffff;}
</style>
At this point, your live theme customization options should be fully functional (unless the settings you defined in Part 1 explicitly use ‘transport’=>’postMessage’).

Tip: At the end of this tutorial is a Sample Theme Customization class. This class contains a useful function (which is NOT part of WordPress) called generate_css() that can help you quickly easily generate valid CSS for this step.

Part 3: Configure Live Preview (Optional)
This step is optional, but can dramatically improve user experience. This technique uses a little custom JavaScript in combination with your settings for a faster, more interactive Theme Customizer. If this is not used, then updates are rendered by reloading the entire preview window.

In order to create this custom JavaScript handler, you need to do the following:

1 – Make sure your settings are all configured for live preview ( ‘transport’=>’postMessage’ )
2 – Create a new JavaScript file (e.g. theme-customize.js) to handle the live changes
3 – Create a hook for ‘customize_preview_init’ that enqueues the js file
We’ll go through all 3 steps in detail…

Step 1: Update Your Settings
First, make sure that any custom settings you’ve created have ‘transport’=>’postMessage’ set (see “Adding a New Setting” above). This will disable the automatic refresh behavior when you change that setting, allowing you to define any custom JavaScript handling you like.

Please note that all of WordPress’s Theme Customizer settings use ‘transport’=>’refresh’ by default, so if you want to make the default, built-in Theme Customizer options also take advantage of this, you can easily update their transport method(s) within your ‘customize_register’ hook function like this:

$wp_customize->get_setting( ‘blogname’ )->transport = ‘postMessage';
$wp_customize->get_setting( ‘blogdescription’ )->transport = ‘postMessage';
$wp_customize->get_setting( ‘header_textcolor’ )->transport = ‘postMessage';
$wp_customize->get_setting( ‘background_color’ )->transport = ‘postMessage';

Step 2: Create a JavaScript File
Next, you need to create a new JavaScript file for all your custom handling. Generally, you’d call this theme-customizer.js and place it in your theme’s ‘js/ folder, but you can call it whatever you want or place it where you want.

The contents of your theme-customizer.js file might look like this:

/**
* This file adds some LIVE to the Theme Customizer live preview. To leverage
* this, set your custom settings to ‘postMessage’ and then add your handling
* here. Your javascript should grab settings from customizer controls, and
* then make any necessary changes to the page using jQuery.
*/
( function( $ ) {

// Update the site title in real time…
wp.customize( ‘blogname’, function( value ) {
value.bind( function( newval ) {
$( ‘#site-title a’ ).html( newval );
} );
} );

//Update the site description in real time…
wp.customize( ‘blogdescription’, function( value ) {
value.bind( function( newval ) {
$( ‘.site-description’ ).html( newval );
} );
} );

//Update site title color in real time…
wp.customize( ‘header_textcolor’, function( value ) {
value.bind( function( newval ) {
$(‘#site-title a’).css(‘color’, newval );
} );
} );

//Update site background color…
wp.customize( ‘background_color’, function( value ) {
value.bind( function( newval ) {
$(‘body’).css(‘background-color’, newval );
} );
} );

//Update site link color in real time…
wp.customize( ‘link_textcolor’, function( value ) {
value.bind( function( newval ) {
$(‘a’).css(‘color’, newval );
} );
} );

} )( jQuery );

As you can see from the example above, a single basic handler looks like this:

wp.customize( ‘YOUR_SETTING_ID’, function( value ) {
value.bind( function( newval ) {
//Do stuff (newval variable contains your “new” setting data)
} );
} );

Step 3: Enqueue Your JavaScript
Finally, you simply need to ensure your JavaScript is enqueued.

To ensure that the file is loaded only on the Theme Customizer admin screen (and not your live website), you should use the customize_preview_init hook.

For example…

/**
* Used by hook: ‘customize_preview_init’
*
* @see add_action(‘customize_preview_init’,$func)
*/
function mytheme_customizer_live_preview()
{
wp_enqueue_script(
‘mytheme-themecustomizer’,            //Give the script an ID
get_template_directory_uri().’/assets/js/theme-customizer.js’,//Point to file
array( ‘jquery’,’customize-preview’ ),    //Define dependencies
”,                        //Define a version (optional)
true                        //Put script in footer?
);
}
add_action( ‘customize_preview_init’, ‘mytheme_customizer_live_preview’ );

Sample Theme Customization Class
This sample shows one potential implementation of a basic Theme Customization class that can be easily incorporated into any existing theme. This example class even makes use of the postMessage transport method for live JavaScript-based Theme Customizer previews.

Please note that this class should be used in conjunction with the sample theme-customize.js file exampled earlier in this tutorial.

<?php
/**
* Contains methods for customizing the theme customization screen.
*
* @link http://codex.wordpress.org/Theme_Customization_API
* @since MyTheme 1.0
*/
class MyTheme_Customize {
/**
* This hooks into ‘customize_register’ (available as of WP 3.4) and allows
* you to add new sections and controls to the Theme Customize screen.
*
* Note: To enable instant preview, we have to actually write a bit of custom
* javascript. See live_preview() for more.
*
* @see add_action(‘customize_register’,$func)
* @param \WP_Customize_Manager $wp_customize
* @link http://ottopress.com/2012/how-to-leverage-the-theme-customizer-in-your-own-themes/
* @since MyTheme 1.0
*/
public static function register ( $wp_customize ) {
//1. Define a new section (if desired) to the Theme Customizer
$wp_customize->add_section( ‘mytheme_options’,
array(
‘title’       => __( ‘MyTheme Options’, ‘mytheme’ ), //Visible title of section
‘priority’    => 35, //Determines what order this appears in
‘capability’  => ‘edit_theme_options’, //Capability needed to tweak
‘description’ => __(‘Allows you to customize some example settings for MyTheme.’, ‘mytheme’), //Descriptive tooltip
)
);

//2. Register new settings to the WP database…
$wp_customize->add_setting( ‘link_textcolor’, //No need to use a SERIALIZED name, as `theme_mod` settings already live under one db record
array(
‘default’    => ‘#2BA6CB’, //Default setting/value to save
‘type’       => ‘theme_mod’, //Is this an ‘option’ or a ‘theme_mod’?
‘capability’ => ‘edit_theme_options’, //Optional. Special permissions for accessing this setting.
‘transport’  => ‘postMessage’, //What triggers a refresh of the setting? ‘refresh’ or ‘postMessage’ (instant)?
)
);

//3. Finally, we define the control itself (which links a setting to a section and renders the HTML controls)…
$wp_customize->add_control( new WP_Customize_Color_Control( //Instantiate the color control class
$wp_customize, //Pass the $wp_customize object (required)
‘mytheme_link_textcolor’, //Set a unique ID for the control
array(
‘label’      => __( ‘Link Color’, ‘mytheme’ ), //Admin-visible name of the control
‘settings’   => ‘link_textcolor’, //Which setting to load and manipulate (serialized is okay)
‘priority’   => 10, //Determines the order this control appears in for the specified section
‘section’    => ‘colors’, //ID of the section this control should render in (can be one of yours, or a WordPress default section)
)
) );

//4. We can also change built-in settings by modifying properties. For instance, let’s make some stuff use live preview JS…
$wp_customize->get_setting( ‘blogname’ )->transport = ‘postMessage';
$wp_customize->get_setting( ‘blogdescription’ )->transport = ‘postMessage';
$wp_customize->get_setting( ‘header_textcolor’ )->transport = ‘postMessage';
$wp_customize->get_setting( ‘background_color’ )->transport = ‘postMessage';
}

/**
* This will output the custom WordPress settings to the live theme’s WP head.
*
* Used by hook: ‘wp_head’
*
* @see add_action(‘wp_head’,$func)
* @since MyTheme 1.0
*/
public static function header_output() {
?>
<!–Customizer CSS–>
<style type=”text/css”>
<?php self::generate_css(‘#site-title a’, ‘color’, ‘header_textcolor’, ‘#’); ?>
<?php self::generate_css(‘body’, ‘background-color’, ‘background_color’, ‘#’); ?>
<?php self::generate_css(‘a’, ‘color’, ‘link_textcolor’); ?>
</style>
<!–/Customizer CSS–>
<?php
}

/**
* This outputs the javascript needed to automate the live settings preview.
* Also keep in mind that this function isn’t necessary unless your settings
* are using ‘transport’=>’postMessage’ instead of the default ‘transport’
* => ‘refresh’
*
* Used by hook: ‘customize_preview_init’
*
* @see add_action(‘customize_preview_init’,$func)
* @since MyTheme 1.0
*/
public static function live_preview() {
wp_enqueue_script(
‘mytheme-themecustomizer’, // Give the script a unique ID
get_template_directory_uri() . ‘/assets/js/theme-customizer.js’, // Define the path to the JS file
array(  ‘jquery’, ‘customize-preview’ ), // Define dependencies
”, // Define a version (optional)
true // Specify whether to put in footer (leave this true)
);
}

/**
* This will generate a line of CSS for use in header output. If the setting
* ($mod_name) has no defined value, the CSS will not be output.
*
* @uses get_theme_mod()
* @param string $selector CSS selector
* @param string $style The name of the CSS *property* to modify
* @param string $mod_name The name of the ‘theme_mod’ option to fetch
* @param string $prefix Optional. Anything that needs to be output before the CSS property
* @param string $postfix Optional. Anything that needs to be output after the CSS property
* @param bool $echo Optional. Whether to print directly to the page (default: true).
* @return string Returns a single line of CSS with selectors and a property.
* @since MyTheme 1.0
*/
public static function generate_css( $selector, $style, $mod_name, $prefix=”, $postfix=”, $echo=true ) {
$return = ”;
$mod = get_theme_mod($mod_name);
if ( ! empty( $mod ) ) {
$return = sprintf(‘%s { %s:%s; }’,
$selector,
$style,
$prefix.$mod.$postfix
);
if ( $echo ) {
echo $return;
}
}
return $return;
}
}

// Setup the Theme Customizer settings and controls…
add_action( ‘customize_register’ , array( ‘MyTheme_Customize’ , ‘register’ ) );

// Output custom CSS to live site
add_action( ‘wp_head’ , array( ‘MyTheme_Customize’ , ‘header_output’ ) );

// Enqueue live preview javascript in Theme Customizer admin screen
add_action( ‘customize_preview_init’ , array( ‘MyTheme_Customize’ , ‘live_preview’ ) );

*****************************************************************************************
*****************************************************************************************
Class Reference/WP Customize Manager/add setting
Usage
$wp_customize->add_setting($id, $args);
Parameters
$id
(string) (required) A unique slug-like ID for the theme setting.
Default: None
$args
(array) (required) An associative array containing arguments for the setting.
Default: None
Arguments
default
A default value for the setting if none is defined
type
Optional. Specifies the TYPE of setting this is. Options are ‘option’ or ‘theme_mod’ (defaults to ‘theme_mod’)
capability
Optional. You can define a capability a user must have to modify this setting. Default if not specified: edit_theme_options
theme_supports
Optional. This can be used to hide a setting if the theme lacks support for a specific feature (using add_theme_support).
transport
Optional. This can be either ‘refresh’ (default) or ‘postMessage’. Only set this to ‘postMessage’ if you are writing custom Javascript to control the Theme Customizer’s live preview.
sanitize_callback
Optional. A function name to call for sanitizing the input value for this setting. The function should be of the form of a standard filter function, where it accepts the input data and returns the sanitized data.
sanitize_js_callback
Optional. A function name to call for sanitizing the value for this setting for the purposes of outputting to javascript code. The function should be of the form of a standard filter function, where it accepts the input data and returns the sanitized data. This is only necessary if the data to be sent to the customizer window has a special form.
One way to think of the difference between sanitize_callback and sanitize_js_callback is as input and output. The sanitize_callback will be invoked when data comes from the customizer to the database.
The sanitize_js_callback will be invoked when data comes from the database back to the customizer.
********************************************************************************************
Description
Adds a new section to the Theme Customization admin screen. Sections are convenient ways to group controls logically.

This is a method of the WP_Customize_Manager class and can only be accessed through the $wp_customize object within the customize_register action hook.

Usage
function mytheme_add_section( ) {
$wp_customize->add_section($id, $args);
}
add_action( ‘customize_register’, ‘mytheme_add_section’ );
Parameters
$id
(string) (required) A unique slug-like string to use as an id.
Default: None
$args
(array) (required) An associative array containing arguments for the control.
Default: None
Arguments
title
The visible name of a controller section.
priority
This controls the order in which this section appears in the Theme Customizer sidebar.
description
This optional argument can add additional descriptive text to the section.
active_callback
This optional argument can show or hide section based on currently viewed page. Example: ‘active_callback’ => ‘is_front_page’.
Default Sections
WordPress does include a few built-in sections. If you want to use any of the existing, built-in ones, you don’t need to declare them with add_section(). Instead, refer to them directly. The following sections are built-in…

themes – <name of the theme>
title_tagline – Site Identity
colors – Colors
header_image – Header Image and Site Icon
background_image – Background Image
static_front_page – Static Front Page (shown only if there is at least 1 page)
Example
Adding a theme section (within the ‘customize_register’ action) might look like this:

$wp_customize->add_section( ‘mytheme_new_section_name’ , array(
‘title’      => __(‘Visible Section Name’,’mytheme’),
‘priority’   => 30,
) );

****************************************************************************
Class Reference/WP Customize Manager/add control
Description
Displays a new controller on the Theme Customization admin screen (available in WordPress 3.4 or newer). Controls serve two purposes: they create a “physical” control that allows a user to manipulate a setting, and it also binds a pre-defined setting to a pre-defined section.

This is a method of the WP_Customize_Manager() class and can only be accessed through the $wp_customize object within the customize_register action hook.

Usage
$wp_customize->add_control($id, $args);
Parameters
$id
(mixed) (required) A string or a specific customization controller object.
Default: None
$args
(array) (required) Not used if $id is a control object, otherwise an instance of WP_Customize_Control() (plain text) is created using the specified arguments.
Default: None
Arguments
label
Optional. Displayed label. Example: ‘label’ => __( ‘Base Color Scheme’, ‘twentyfifteen’ ),
description
Optional. Example: ‘description’ => __( ‘Applied to the header on small screens and the sidebar on wide screens.’, ‘twentyfifteen’ ),
section
Any readily available or user defined section. Some available sections: themes, title_tagline, colors, header_image (only when enabled), background_image (only when enabled), static_front_page. Example: ‘section’ => ‘colors’,
priority
Optional. themes (0), title_tagline (20), colors (40), header_image (60), background_image (80), static_front_page (120).
type
Supported types include: text, checkbox, radio, select, textarea, dropdown-pages, email, url, number, hidden, and date. Example: ‘type’ => ‘textarea’,
settings
Optional. If in https://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_setting you specified “theme_mod” type then you should add here ID of the database setting which you want to modify, e.g. “header_color” (which is your arbitrary name specific to your theme only). It will be stored as a serialized value obtainable with https://codex.wordpress.org/Function_Reference/get_theme_mod like get_theme_mod(‘header_color’);. If you selected “option” type in https://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_setting then you can add here a plain word like “theme_name_header_color” which will be obtainable with get_option(‘theme_name_header_color’);. Serialized values like “my_namespace[header_color]” are allowed in both cases, however you probably don’t need to serialize it when using “theme_mod” as it’s already stored in the database as a serialized entry. If not defined, then the $id as the setting ID is used.
choices, height, width etc.
Optional. It’s possible to pass custom parameters for specific control types. These are available only for some control types. Example for “select” and “radio” controls: ‘choices’=> twentyfifteen_get_color_scheme_choices(),
Classes
WP_Customize_Control()
Creates a control that allows users to enter plain text. This is also the parent class for the classes that follow.
WP_Customize_Color_Control()
Creates a control that allows users to select a color from a color wheel.
WP_Customize_Upload_Control()
Creates a control that allows users to upload media.
WP_Customize_Image_Control()
Creates a control that allows users to select or upload an image.
WP_Customize_Background_Image_Control()
Creates a control that allows users to select a new background image.
WP_Customize_Header_Image_Control()
Creates a control that allows users to select a new header image.
Custom controls can also be created. For more information, see this post on Ottopress.com

Example
Remember that this example assumes you are already working within the customize_register action hook.

$wp_customize->add_control( new WP_Customize_Color_Control(
$wp_customize,
‘your_control_id’,
array(
‘label’      => __( ‘Header Color’, ‘mytheme’ ),
‘section’    => ‘your_section_id’,
‘settings’   => ‘your_setting_id’,
‘priority’   => 1
)
));

Alternatively, it is not required to instantiate a WP_Customize_Control object. WordPress will check to see if you are passing in an object and, if absent, will create a new WP_Customize_Control object with the arguments you have passed in.

$wp_customize->add_control(
‘your_control_id’,
array(
‘label’    => __( ‘Control Label’, ‘mytheme’ ),
‘section’  => ‘your_section_id’,
‘settings’ => ‘your_setting_id’,
‘type’     => ‘radio’,
‘choices’  => array(
‘left’  => ‘left’,
‘right’ => ‘right’,
),
)
);

Want to know about new themes or plugins?
Signup today and receive free updates straight in your inbox. We will never share or sell your email address.