I'm trying to make my plugin multisite compatible. I'm using the register_activation_hook() function to register my my_activate() function to run when the plugin is activated. This works well on a single-site install.

function my_activate() {
    // Do some things.
register_activation_hook( __FILE__, 'my_activate' );

The problem is, my_activate() doesn't run for each site when my plugin is 'network activated'. Also, it doesn't run when new sites are created on the network.

How can I get my activation routine to a) run when my plugin is network activated for all sites in the network and b) run when a new site is created on the multisite network?


Your callback function should run when your plugin is network activated or activated for a single site. Either way, it should be working.

However, if you intend for the code contained within your callback to be ran for each blog in your network, then be aware that this will not happen out of the box, instead, the code within your callback will in the primary blog context.

If your code needs to run on each blog upon Network Activation:

function my_plugin_activate($network_wide) {

    if ( is_multisite() && $network_wide ) { 

        foreach (get_sites(['fields'=>'ids']) as $blog_id) {
            //do your specific thing here...

    } else {
        //run in single site context


register_activation_hook( __FILE__, 'my_plugin_activate' );

If your code needs to run when a new blog is created:

function my_plugin_new_blog($blog_id) {

    //replace with your base plugin path E.g. dirname/filename.php
    if ( is_plugin_active_for_network( 'my-plugin-name-dir/my-plugin-name.php' ) ) {
        //do your specific thing here...


add_action('wpmu_new_blog', 'my_plugin_new_blog');


For those reading who want similar functionality but for all plugins that get network activated (not just the one you control, if at all applicable), then you may wish to look at: https://wordpress.org/plugins/proper-network-activation/ which will ensure that each plugin in your multisite network in which is network activated, has both its register_activation_hook and register_deactivation_hook run in each blog context.

| improve this answer | |
  • thanks for the solution, much appreciated! Regarding your first sentence, I've updated my question's wording slightly. – henrywright Mar 14 '15 at 12:19
  • 3
    @henrywright register_activation_hook is just a wrapper around add_action('activate_' . $file, $function) which in itself fires upon, do_action( 'activate_' . $plugin, $network_wide ) of which you can see the variable $network_wide and its value state, one of either true or false is always passed as an argument to the callback. Hence, you have access to this argument in your register_activation_hook and register_deactivation_hook wrappers. For more information see activate_plugin function within wp-admin/includes/plugin.php. Hope that helps. – Adam Mar 15 '15 at 1:50
  • 1
    Appreciate the explanation, and thanks again for your answer :) – henrywright Mar 15 '15 at 1:55
  • 1
    @ErenorPaz restore_current_blog needs to be in the foreach loop, because if you put it outside, then iterate (switch over) to 10 blogs for example, the last call to restore_current_blog will restore the last blog you switched to and NOT the original blog you started at (presumably your main site). codex.wordpress.org/WPMU_Functions/restore_current_blog – Adam Mar 7 '18 at 3:54
  • 2
    @ErenorPaz no need to delete the comment, doing so makes the chat history confusing to read for people. There's nothing wrong giving an opinion even if it may not be correct. No one is going on hate on you for that, we are community here to help, discuss, learn and gain perspective. Anyway all good... – Adam Mar 7 '18 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.