WordPress Multisite is a feature built into WordPress core that allows a single installation to host a network of independent sites — each with its own content, users, settings, and plugins — while sharing a single codebase, database, and file upload directory. Activating Multisite converts wp-config.php and .htaccess to network-aware configurations and switches the database from single-site tables to a table-per-site scheme: the main site keeps the original tables (wp_posts, wp_options, etc.) while each additional site gets its own prefixed set (wp_2_posts, wp_2_options, etc.), and shared tables (wp_users, wp_usermeta, wp_blogs, wp_site) span the entire network. Networks can be configured in two URL modes: subdomain mode (site2.example.com) or subdirectory mode (example.com/site2/) — subdomain mode requires wildcard DNS and a wildcard SSL certificate, while subdirectory mode works with a standard single-domain certificate. The Super Admin role is the highest privilege level in a network — Super Admins manage plugins and themes at the network level, whereas individual site administrators manage content and site-level settings. Plugins activated at the network level via Network Admin → Plugins are forced-active on all sites and cannot be deactivated by individual site admins — this is the correct approach for security plugins, caching plugins, and shared functionality. Per-site plugin activation is available when a plugin is not network-activated, giving site admins the choice to enable or disable it. The switch_to_blog() function (and its companion restore_current_blog()) allows PHP code to query or modify another site in the network — used in network-wide reports, search aggregators, and cron jobs that process all sites. User roles are site-scoped: a user can be an Administrator on site 2 and a Subscriber on site 3, with capabilities stored in per-site wp_N_usermeta rows. The CSP headers post covers how to apply security headers network-wide from a single mu-plugin rather than per site.
Problem: A marketing agency manages 12 client microsites that share the same WordPress theme and a set of internal plugins — each site is a separate WordPress installation, so plugin updates must be applied 12 times and user accounts must be created separately on each site, multiplying maintenance overhead.
Solution: Convert the primary installation to a WordPress Multisite network, migrate client sites as child sites, network-activate shared plugins, and use a single network admin panel for updates and user management across all 12 sites.
// ── Step 1: Enable Multisite in wp-config.php ─────────────────────────────
// Add BEFORE "That's all, stop editing!" line:
define( 'WP_ALLOW_MULTISITE', true );
// After running Network Setup in WP Admin → Tools → Network Setup,
// wp-config.php gets these additional constants:
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', false ); // true for subdomain mode
define( 'DOMAIN_CURRENT_SITE','example.com' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );
// ── Step 2: Programmatically create a new site in the network ─────────────
function agency_create_client_site( array $args ): int|WP_Error {
$defaults = [
'domain' => '', // subdirectory slug or subdomain
'title' => '',
'user_email' => '',
'user_role' => 'administrator',
'options' => [],
];
$args = wp_parse_args( $args, $defaults );
// Build the full domain / path depending on network mode
if ( is_subdomain_install() ) {
$domain = sanitize_title( $args['domain'] ) . '.' . DOMAIN_CURRENT_SITE;
$path = '/';
} else {
$domain = DOMAIN_CURRENT_SITE;
$path = '/' . sanitize_title( $args['domain'] ) . '/';
}
$site_id = wpmu_create_blog(
$domain,
$path,
sanitize_text_field( $args['title'] ),
get_current_user_id(),
[ 'public' => 1 ],
get_current_network_id()
);
if ( is_wp_error( $site_id ) ) {
return $site_id;
}
// Add an external admin user to the new site
if ( $args['user_email'] ) {
$user = get_user_by( 'email', sanitize_email( $args['user_email'] ) );
if ( $user ) {
add_user_to_blog( $site_id, $user->ID, $args['user_role'] );
}
}
// Apply site-specific options after creation
switch_to_blog( $site_id );
foreach ( $args['options'] as $key => $value ) {
update_option( sanitize_key( $key ), $value );
}
restore_current_blog();
return $site_id;
}
// Usage
$new_site = agency_create_client_site([
'domain' => 'client-alpha',
'title' => 'Client Alpha Microsite',
'user_email' => 'admin@client-alpha.com',
'options' => [
'blogdescription' => 'Official site of Client Alpha',
'timezone_string' => 'America/New_York',
],
]);
// ── Step 3: Network-wide query across all sites ───────────────────────────
function agency_get_all_sites_post_count(): array {
$counts = [];
foreach ( get_sites( [ 'number' => 500 ] ) as $site ) {
switch_to_blog( $site->blog_id );
$counts[ $site->blog_id ] = [
'name' => get_bloginfo( 'name' ),
'posts' => wp_count_posts()->publish,
];
restore_current_blog();
}
return $counts;
}
NOTE: Converting an existing single-site WordPress installation to Multisite is a one-way operation — there is no built-in revert path. Take a full database and file backup before enabling Multisite. Also note that not all plugins are Multisite-compatible: plugins that assume a single site’s table prefix or hardcode the site URL will break on secondary sites. Test every plugin on a staging network before network-activating it in production.