Independent Editorial DeskWordPress Releases, Builds, and Operations
Back to Archive
Implementation Notes

WordPress Customizer API Example: Add a Theme Setting Safely

Build a safe WordPress Customizer setting with sanitization, preview JavaScript, front-end output, and production checks.

Published

April 23, 2026

Reading Time

3 min read

Updated

April 23, 2026

Customizer controls and preview interface illustrating safe WordPress theme settings.
Build PatternImplementation Notes

Implementation Notes

Extension points, code paths, and implementation choices that should survive contact with production.

Best For

WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.

Primary Topics

Implementation Notes

Editorial Focus

Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on April 23, 2026.

Full Report

Last reviewed: April 23, 2026

The WordPress Customizer is still useful for classic themes, hybrid themes, and client sites that need safe visual controls without giving editors direct access to PHP files. The mistake is treating Customizer values like trusted configuration just because they come from the admin screen.

This guide shows a production-ready Customizer setting for a theme accent color. It covers capability checks, sanitization, selective refresh, front-end output, and the failure modes that usually make theme settings fragile.

When the Customizer is the right tool

Use the Customizer when a site owner needs to adjust theme behavior or presentation while previewing the result. Good examples are brand colors, footer text, header behavior, archive layout density, and promotional banner toggles. Avoid it for secrets, integration credentials, or plugin settings that are not theme-specific.

Register a setting, section, and control

<?php
add_action( 'customize_register', 'vulnwp_register_theme_customizer_settings' );

function vulnwp_register_theme_customizer_settings( WP_Customize_Manager $wp_customize ) {
	$wp_customize->add_section(
		'vulnwp_branding',
		array(
			'title'       => __( 'Branding', 'vulnwp' ),
			'description' => __( 'Theme-level brand controls.', 'vulnwp' ),
			'priority'    => 35,
		)
	);

	$wp_customize->add_setting(
		'vulnwp_accent_color',
		array(
			'default'           => '#0f513d',
			'type'              => 'theme_mod',
			'capability'        => 'edit_theme_options',
			'sanitize_callback' => 'sanitize_hex_color',
			'transport'         => 'postMessage',
		)
	);

	$wp_customize->add_control(
		new WP_Customize_Color_Control(
			$wp_customize,
			'vulnwp_accent_color_control',
			array(
				'label'    => __( 'Accent color', 'vulnwp' ),
				'section'  => 'vulnwp_branding',
				'settings' => 'vulnwp_accent_color',
			)
		)
	);
}

The setting uses theme_mod, which fits theme-specific values. The sanitize_callback is not optional: it prevents unexpected values from being stored and later printed into CSS.

Print the value safely on the front end

add_action( 'wp_head', 'vulnwp_print_accent_color_css' );

function vulnwp_print_accent_color_css() {
	$accent = get_theme_mod( 'vulnwp_accent_color', '#0f513d' );
	$accent = sanitize_hex_color( $accent );

	if ( ! $accent ) {
		$accent = '#0f513d';
	}

	printf(
		'<style id="vulnwp-accent-color">:root{--vulnwp-accent:%s;}</style>' . "\n",
		esc_html( $accent )
	);
}

Even though the value was sanitized on save, the render path sanitizes again. That defensive pattern matters because values can be changed by imports, database edits, or old code paths.

Add live preview JavaScript

add_action( 'customize_preview_init', 'vulnwp_enqueue_customizer_preview' );

function vulnwp_enqueue_customizer_preview() {
	wp_enqueue_script(
		'vulnwp-customizer-preview',
		get_theme_file_uri( 'assets/js/customizer-preview.js' ),
		array( 'customize-preview' ),
		wp_get_theme()->get( 'Version' ),
		true
	);
}
( function( wp ) {
	wp.customize( 'vulnwp_accent_color', function( value ) {
		value.bind( function( nextColor ) {
			document.documentElement.style.setProperty( '--vulnwp-accent', nextColor );
		} );
	} );
} )( window.wp );

transport is set to postMessage, so the preview updates without a full page refresh. Keep the JavaScript small and limited to preview behavior.

Use the CSS variable in the theme

.button,
.wp-block-button__link {
	background: var(--vulnwp-accent);
	border-color: var(--vulnwp-accent);
}

a {
	color: var(--vulnwp-accent);
}

Printing one CSS custom property keeps the dynamic output narrow. Avoid generating large inline stylesheets from Customizer values.

Production checklist

  • Use edit_theme_options unless a narrower capability is intentionally registered.
  • Add a sanitize_callback for every setting.
  • Escape values again when printing them.
  • Use theme_mod for theme-specific values and option only when the setting should survive theme switches.
  • Do not store secrets, API keys, or private tokens in Customizer settings.
  • Test the preview and the saved front-end output separately.

Common mistakes

  • Registering controls without sanitization. Admin UI is not a security boundary.
  • Using Customizer for plugin configuration. Plugin settings usually belong in the Settings API or a dedicated plugin screen.
  • Printing raw values into CSS. Always sanitize and escape on output.
  • Forgetting defaults. A missing setting should not break the theme.
  • Assuming block themes need the same workflow. Modern block themes often use theme.json and global styles instead.

Related reading

If this setting controls theme assets, pair it with the wp_enqueue_script example. For plugin settings, use the Settings API example instead of forcing everything into the Customizer.

References and further reading

Popular Guides

Popular WordPress guides to read next.

These articles connect recurring production concerns: implementation details, updates, troubleshooting, recovery paths, and operational cleanup.

Continue Reading

More from the archive.

Diagnostic dashboard scene representing a WordPress Site Health review before major updates.
01Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Site Health Check Before Major Updates: What to Review First

A pre-update WordPress Site Health checklist covering loopbacks, connectivity, debug settings, and environment readiness.

Structured data and route review scene representing permalink validation after a WordPress migration.
02Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Permalink Checklist After Migration: Catch URL Problems Early

A post-migration WordPress permalink checklist for checking rewrite rules, post URLs, archives, and redirect noise.

Technical media workspace representing image preparation and optimization before upload to WordPress.
03Build Pattern
Implementation Notes

Build Pattern

Extension points, code paths, and implementation choices that should survive contact with production.

May 21, 2026 · 3 min read

WordPress Image Optimization Checklist: What to Fix Before Upload

A practical WordPress image optimization checklist covering dimensions, compression, formats, and Media settings before upload.