Skip to content
Development
Skill

/wp-multisite

Use when building or adapting a WordPress plugin for Multisite/Network — network activation (register_activation_hook with $network_wide), network admin pages (network_admin_menu), per-site vs network-wide options (get_option / get_network_option / update_network_option),

From plugin
wp-dev-skills
2719 skills1 command
Install
$ npx -y skills add mralaminahamed/wp-dev-skills --skill wp-multisite --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/wp-multisite

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when building or adapting a WordPress plugin for Multisite/Network — network activation (register_activation_hook with $network_wide), network admin pages (network_admin_menu), per-site vs network-wide options (get_option / get_network_option / update_network_option),

SKILL.md

wp-multisite.SKILL.md
name: wp-multisite
description: "Use when building or adapting a WordPress plugin for Multisite/Network — network activation (register_activation_hook with $network_wide), network admin pages (network_admin_menu), per-site vs network-wide options (get_option / get_network_option / update_network_option), looping sites with get_sites() + switch_to_blog() / restore_current_blog(), super admin capabilities (is_super_admin(), manage_network, is_network_admin()), table prefix handling ($wpdb->prefix vs $wpdb->base_prefix), blog ID awareness (get_current_blog_id), or detecting multisite context (is_multisite(), is_plugin_active_for_network()). Triggers: \"make my plugin multisite compatible\", \"network activate\", \"network admin page\", \"per-site settings\", \"switch_to_blog()\", \"restore_current_blog()\", \"super admin only feature\", \"why does my plugin break on multisite\", \"run this for every site in the network\", \"network-wide option\", \"plugin only on certain sites\", \"blog ID handling\", \"is_multisite()\", \"is_network_admin()\", \"is_plugin_active_for_network()\", \"get_network_option()\", \"wpdb base_prefix\", \"manage_network capability\", \"network options page\", \"multisite table prefix\", \"site-aware hook registration\", \"get_sites() loop\". Not for: WP-CLI multisite ops; MU-plugins auto-load behaviour (no activation hooks fire)."

WordPress Multisite Plugin Development

> **Model note:** Adapting an existing plugin for multisite involves scattered conditional changes — requires reading across many files to find all `get_option`/`update_option` and activation hooks. Use `sonnet`; `haiku` may miss indirect callers. New builds with multisite in mind from the start are straightforward and can use `haiku`.

Adapt and build plugins that work correctly on WordPress multisite networks. Covers activation scope, option storage, network admin UI, capability model, and safe site-switching patterns.

When to use

  • "Make my plugin multisite compatible", "support network activation".
  • "Add a network admin settings page", "store a network-wide option".
  • "Loop over all sites and do X", "run a task on every blog".
  • "Why does my plugin break on multisite?", "fix table prefix issues".
  • "Check if a user is super admin", "restrict to network admin only".

**Not for:** WP-CLI multisite operations — use `wp-wpcli-and-ops` (official skill). General plugin architecture — use `wp-plugin-development`.

Method

1. Detection and guarding

// Is this a multisite network?
if ( is_multisite() ) { ... }

// Is the current screen the network admin?
if ( is_network_admin() ) { ... }

// Is the plugin network-activated?
if ( is_plugin_active_for_network( plugin_basename( __FILE__ ) ) ) { ... }

// Is the user a super admin?
if ( current_user_can( 'manage_network' ) ) { ... }  // preferred
if ( is_super_admin() ) { ... }                       // also fine

Never assume `is_multisite()` is false — always write code that handles both cases unless the plugin explicitly requires multisite.

2. Activation scope

A plugin can be:

  • **Site-activated** — active on one site, hooks run only on that site.
  • **Network-activated** — active on all sites, activation hook runs once on the network.
register_activation_hook( __FILE__, 'my_plugin_activate' );

function my_plugin_activate( $network_wide ) {
    if ( $network_wide && is_multisite() ) {
        // Run setup for every existing site
        $sites = get_sites( [ 'number' => 0, 'fields' => 'ids' ] );
        foreach ( $sites as $site_id ) {
            switch_to_blog( $site_id );
            my_plugin_setup_site();
            restore_current_blog();
        }
    } else {
        my_plugin_setup_site();
    }
}

// Also run setup when a new site is created (for network-activated plugins)
add_action( 'wp_initialize_site', function( WP_Site $new_site ) {
    if ( is_plugin_active_for_network( plugin_basename( __FILE__ ) ) ) {
        switch_to_blog( $new_site->blog_id );
        my_plugin_setup_site();
        restore_current_blog();
    }
} );

3. Option storage: site vs network

| Function | Scope | Storage | |---|---|---| | `get_option()` / `update_option()` | Current site | `{prefix}options` (per site) | | `get_network_option()` / `update_network_option()` | Entire network | `{main_prefix}sitemeta` | | `get_site_meta()` / `update_site_meta()` | Per-site record | `{main_prefix}blogmeta` |

// Network-wide setting (same value for all sites)
$api_key = get_network_option( null, 'my_plugin_api_key' );
update_network_option( null, 'my_plugin_api_key', sanitize_text_field( $key ) );

// Per-site setting (different value per site)
$setting = get_option( 'my_plugin_site_setting', 'default' );
update_option( 'my_plugin_site_setting', $value );

// Per-site metadata on the site object
$site_note = get_site_meta( get_current_blog_id(), 'my_plugin_note', true );
update_site_meta( get_current_blog_id(), 'my_plugin_note', sanitize_textarea_field( $note ) );

4. Network admin settings page

// Register under network admin menu
add_action( 'network_admin_menu', function() {
    add_menu_page(
        __( 'My Plugin Network', 'my-plugin' ),
        __( 'My Plugin', 'my-plugin' ),
        'manage_network',             // super admin only
        'my-plugin-network',
        'my_plugin_render_network_page'
    );
} );

// Network admin settings must use wp_redirect — Settings API not available in network admin
add_action( 'network_admin_edit_my_plugin_network_settings', function() {
    check_admin_referer( 'my_plugin_network_settings' );
    if ( ! current_user_can( 'manage_network' ) ) wp_die( -1 );

    update_network_option( null, 'my_plugin_api_key',
        sanitize_text_field( wp_unslash( $_POST['api_key'] ?? '' ) )
    );

    wp_redirect( add_query_arg( [ 'updated' => 'true' ], network_admin_url( 'settings.php?page=my-plugin-network' ) ) );
    exit;
} );

function my_plugin_render_network_p
Read more
Ships withwp-dev-skills

Covers the complete WordPress plugin development lifecycle — build, test, audit, release, and ship to WP.org — for Claude Code, Gemini CLI, Cursor, Windsurf, Cline, Codex, GitHub Copilot, opencode, and more.

Get the whole plugin
Stats
27
Stars
3
Forks
Maintained
Maintenance
PHP
Language
MIT
License
1mo ago
Last commit
3mo ago
Created

Repo: mralaminahamed/wp-dev-skills

Other skills on wp-dev-skills.