WordPress provides a structured and secure way to add custom settings pages to the admin area through the built-in Settings API. Instead of writing your code to handle form submissions, data storage, and sanitization, you can rely on the Settings API to streamline these tasks. This approach integrates your settings seamlessly into the WordPress admin and ensures consistency and user-friendliness.
In this article, we’ll detail how to implement a custom settings page for your plugin or theme using the Settings API. We’ll cover registering settings, creating sections and fields, hooking into the admin menu system to display your page, and ensuring that user-submitted data is validated and saved securely. By following these steps, you’ll deliver a professional admin interface that site owners will find familiar and easy to use.
The WordPress Settings API provides a high-level interface for defining settings, sections, and fields that appear on a dedicated settings page in the WordPress admin. Instead of manually handling form submissions, updating options, and writing complex HTML, the API manages these processes for you.
Key Components of the Settings API:
The Settings API also handles creating nonces, validating and sanitizing user inputs, and integrating with options.php for saving. This process avoids writing boilerplate code and keeps your code consistent with WordPress standards.

Creating a custom settings page using the Settings API involves several key steps:
By following these steps, you integrate seamlessly with WordPress UI and data management, making it easy for users to adjust plugin or theme behavior through a familiar interface.
Let’s walk through an example. Suppose we have a plugin that needs one setting: a “Welcome Message” displayed on the site’s homepage. We want to allow the site admin to set or change this message from a custom settings page in the admin.
We will do all registration logic in an admin_init action. This logic ensures that when the admin panel initializes, our settings become known.
Example Code:
add_action( 'admin_init', 'myplugin_settings_init' );
function myplugin_settings_init() {
// Register the setting. The first parameter is the option name; the second is the callback for sanitization.
register_setting( 'myplugin_settings_group', 'myplugin_welcome_message', 'myplugin_sanitize_welcome_message' );
// Add a section. The section doesn't store data itself, just groups fields.
add_settings_section(
'myplugin_settings_section',
'My Plugin Settings Section',
'myplugin_settings_section_callback',
'myplugin-settings-page'
);
// Add a field. The callback renders the HTML input for the field.
add_settings_field(
'myplugin_welcome_message',
'Welcome Message',
'myplugin_welcome_message_field_callback',
'myplugin-settings-page',
'myplugin_settings_section'
);
}
What’s Happening Here?
We need callback functions to handle the section description and render the input field:
function myplugin_settings_section_callback() {
echo '<p>Adjust the settings for My Plugin below.</p>';
}
function myplugin_welcome_message_field_callback() {
// Get the current value of the option
$value = get_option( 'myplugin_welcome_message', '' );
echo '<input type="text" name="myplugin_welcome_message" value="' . esc_attr( $value ) . '" class="regular-text" />';
}
Explanation:
We must ensure that the data entered by users is clean before saving. A sanitization callback can remove dangerous HTML or enforce rules like a character limit.
function myplugin_sanitize_welcome_message( $input ) {
// Sanitize input by stripping tags and trimming whitespace
$input = strip_tags( $input );
$input = trim( $input );
return $input;
}
When the form is submitted, WordPress calls this function, passing the submitted value. The returned value is what gets stored in the database.
Now that we have our setting registered, we need a page in the admin to host it. We’ll add a top-level menu item or a submenu item. Let’s go with a top-level menu for this example.
Example Code:
add_action( 'admin_menu', 'myplugin_add_admin_menu' );
function myplugin_add_admin_menu() {
add_menu_page(
'My Plugin Settings',
'My Plugin',
'manage_options', // capability required to view this page
'myplugin-settings-page',
'myplugin_settings_page_html',
'dashicons-admin-generic', // icon
80 // position in the menu
);
}
What’s Happening?
We will output a form on the callback function that generates the page. The Settings API simplifies this step:
Example Code:
function myplugin_settings_page_html() {
// Check user capability
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// Settings saved confirmation message
if ( isset( $_GET['settings-updated'] ) ) {
add_settings_error( 'myplugin_messages', 'myplugin_message', 'Settings Saved', 'updated' );
}
// Display messages
settings_errors( 'myplugin_messages' );
echo '<div class="wrap">';
echo '<h1>My Plugin Settings</h1>';
echo '<form action="options.php" method="post">';
// Output security fields for the registered settings
settings_fields( 'myplugin_settings_group' );
// Output the settings section and fields
do_settings_sections( 'myplugin-settings-page' );
// Submit button
submit_button( 'Save Settings' );
echo '</form>';
echo '</div>';
}
Explanation:
That’s it. WordPress handles saving data when the form posts to options.php. After sanitization, it updates the myplugin_welcome_message option in the database.
Once your code is in place, visit the WordPress admin. You should see a “My Plugin” menu item. Clicking it opens your settings page with a Text field and a “Save Settings” button. Enter a value and save. If everything is correct, you’ll see a confirmation message, and your sanitized value will appear in the input after reloading.
Check the database (wp_options table by default) for myplugin_welcome_message. It should store the user’s input if you write code to display this welcome message on the front end (e.g., via echo get_option(‘myplugin_welcome_message’);), you’ll see the updated message on the site.
This example covered a single Text field, but the process is the same for multiple fields, radio buttons, checkboxes, or dropdowns. For each field:
If you have multiple settings, you might create multiple sections, each calling add_settings_section() and add_settings_field() inside the admin_init hook. By organizing your fields into logical sections, you keep the page clean and user-friendly.
The Settings API integrates security measures automatically. The settings_fields() function outputs a nonce and hidden fields that ensure only authorized users save settings. Make sure you always call settings_fields() with the correct settings group name, matching the one you used in register_setting().
This process ensures that when the form is submitted, WordPress verifies the nonce and the user’s capability before updating any options. You don’t need to write extra code to handle these checks.
While the Settings API helps with saving data, you must still handle sanitization and validation in your callback. This approach ensures that no dangerous data enters your database.
For complex validations:
This careful validation prevents security issues and maintains data integrity. By guiding users with clear error messages, you improve usability.
The example stored a single value (myplugin_welcome_message) in one option. Sometimes, you might have multiple settings and consider whether to store them as separate options or as one array of options.
Approaches:
To store multiple settings in a single array, register a single option (e.g., myplugin_settings), then in your field callbacks, output fields named myplugin_settings[field_name]. Your sanitization callback returns the cleaned associative array. The Settings API handles merging the array with the database record.
If you prefer to attach your settings to an existing menu (like under the “Settings” menu), use add_options_page() in place of add_menu_page():
add_action( 'admin_menu', 'myplugin_add_admin_submenu' );
function myplugin_add_admin_submenu() {
add_options_page(
'My Plugin Settings',
'My Plugin',
'manage_options',
'myplugin-settings-page',
'myplugin_settings_page_html'
);
}
This function adds a subpage under the main “Settings” menu. The process for rendering and registering settings remains the same. The only difference is using add_options_page() (or add_submenu_page() if attaching to another plugin’s menu) instead of add_menu_page().
If you currently handle form submissions manually (e.g., using a custom POST handler and update_option() calls), migrating to the Settings API can simplify your code. By registering settings and fields, you reduce boilerplate and gain automatic nonce checks, form generation, and standard styling.
To migrate:
This migration improves maintainability and reduces the risk of coding errors or security lapses.
For more complex plugins, you might have multiple settings pages. Each page can have its unique settings, groups, and sections. The process is the same for each page:
With multiple pages, ensure your naming is consistent and your code well-organized so you don’t mix up groups, sections, or fields.
While the Settings API targets the traditional admin interface, the concept of storing options is consistent across WordPress. If you need a more modern UI (like the Customizer or block editor), you can still store your final data in options created by the Settings API.
You can:
These settings keeps your data consistent while allowing different user interfaces for changing settings.
As with any code, testing is crucial. To test:
If fields aren’t appearing, double-check that:
Implementing a custom settings page in the WordPress admin using the Settings API is both straightforward and beneficial. By registering your settings, sections, and fields through a standardized interface, you ensure that your admin pages are user-friendly, consistent, and secure.
Instead of manually handling form submissions and data validation, you leverage WordPress built-in functions. You integrate seamlessly with the WordPress admin experience, providing site owners and administrators with familiar UI elements and workflows. The result is a polished and maintainable settings page that reflects best practices.
As you continue to refine your plugin or theme, you can easily add more fields, rearrange sections, or enhance validation, all without reinventing the wheel. By embracing the Settings API, you set a strong foundation for future growth and an improved user experience, making it simpler for everyone involved to manage and configure your software.

Hassan Tahir wrote this article, drawing on his experience to clarify WordPress concepts and enhance developers’ understanding. Through his work, he aims to help both beginners and professionals refine their skills and tackle WordPress projects with greater confidence.