If you’re developing advanced plugins for WordPress, supporting multisite networks is a powerful way to extend your plugin’s usability across large installations. However, multi-site compatibility isn’t just about activating a plugin network-wide — it involves handling multiple databases, sites, and user contexts gracefully.
This guide walks you through how to create multi-site compatible plugins that are scalable, safe, and performant.
What is WordPress Multisite?
WordPress Multisite allows you to run multiple websites (called “sites” or “blogs”) from a single WordPress installation. Each site shares the same codebase but has:
- Its own set of posts, pages, options, and users.
- A shared
wp_users
table but differentwp_{blog_id}_posts
,wp_{blog_id}_options
, etc.
Plugin Activation Options
When installing a plugin in Multisite, you can:
- Network Activate: Enabled on all sites.
- Site Activate: Enabled on selected sites only.
In your plugin, you must handle both scenarios correctly.
1. Register Network-Wide Hooks
register_activation_hook(__FILE__, 'myplugin_activate');
function myplugin_activate($network_wide) {
if (is_multisite() && $network_wide) {
// Loop through all sites
$sites = get_sites();
foreach ($sites as $site) {
switch_to_blog($site->blog_id);
myplugin_install();
restore_current_blog();
}
} else {
myplugin_install();
}
}
function myplugin_install() {
// Create custom tables, options, etc.
add_option('myplugin_version', '1.0.0');
}
Use switch_to_blog()
and restore_current_blog()
for safe context switching between sites.
2. Use Site-Specific Data Functions
Avoid using get_option()
for network-wide settings. Instead:
- Use
get_site_option()
andupdate_site_option()
for network-wide settings. - Use
get_option()
andupdate_option()
for site-specific settings.
// For network-level settings
$setting = get_site_option('myplugin_network_option');
// For single-site settings
$setting = get_option('myplugin_site_option');
3. Manage Network vs Site Admin Screens
Differentiate admin menus depending on context:
if (is_multisite() && is_network_admin()) {
add_menu_page('Plugin Network Settings', 'Plugin Network', 'manage_network_options', 'plugin-network', 'render_network_settings');
} else {
add_menu_page('Plugin Settings', 'Plugin', 'manage_options', 'plugin', 'render_site_settings');
}
4. Use uninstall.php
Carefully
If you’re cleaning up data, remember:
if (!defined('WP_UNINSTALL_PLUGIN')) {
exit;
}
if (is_multisite()) {
$sites = get_sites();
foreach ($sites as $site) {
switch_to_blog($site->blog_id);
delete_option('myplugin_site_option');
restore_current_blog();
}
} else {
delete_option('myplugin_site_option');
}
Avoid deleting shared user data or files unless absolutely necessary.
5. Handle Custom Tables Per Site
If your plugin creates custom database tables:
global $wpdb;
$table_name = $wpdb->prefix . 'myplugin_table';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
value text NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
Ensure the prefix
is site-specific (wp_2_
, wp_3_
, etc.).
Security Considerations
- Always check user capabilities with
is_super_admin()
for network-wide actions. - Avoid assuming
blog_id = 1
is the main site — always useget_main_site_id()
.
Bonus: WP-CLI Support for Multisite
Support automation with WP-CLI:
wp site list --field=blog_id | xargs -n1 -I % wp --url=% myplugin sync-data
In your plugin:
if (defined('WP_CLI') && WP_CLI) {
WP_CLI::add_command('myplugin', 'MyPlugin_CLI');
}
Final Thoughts
Creating a multi-site compatible plugin involves more than toggling a checkbox. It requires:
- Smart use of
switch_to_blog()
- Separation of site-wide vs network-wide settings
- Clean activation/deactivation routines
- Context-aware admin interfaces
Done right, your plugin can scale across dozens or hundreds of sites — powering SaaS platforms, school networks, enterprise CMS systems, and more.