WordPress Multisite environments offer a powerful way to manage multiple sites through a single WordPress installation. However, their complexity means plugins and themes must be carefully adapted to work across networked sites. While exploring custom logic for sending conditional emails via a plugin, we encountered a subtle yet significant failure on a multisite setup, which stemmed from misunderstanding how hooks behave across sites in a network.
TL;DR
The use of site-level hooks for conditional email logic in a WordPress plugin led to emails not being sent at all on a multisite network. This breakdown was due to the irregular triggering of key hooks within subsites. We resolved the problem by using a network-level action hook that ensured consistent behavior across all sites. The fix highlighted the need to audit plugin architecture for compatibility with multisite hook execution contexts.
Understanding the Problem: Plugin Email Logic Failing on Multisite
The plugin we had developed functioned flawlessly on standard single-site WordPress installations. It was designed to send customized emails based on user actions—such as registration, form submissions, or account updates. The logic was organized around conditions like:
- User roles
- User metadata fields
- Specific triggers like
user_registerorprofile_update
However, once deployed to a multisite network, users began reporting that the expected emails were no longer being sent. There were no errors in the logs, and no obvious indicator that anything had gone wrong. The email template system loaded, the conditional logic ran, and yet—no emails left the server.
Why the Multisite Environment Broke Our Logic
Initial debugging efforts focused on checking basic causes—SMTP issues, spam filters, plugin conflicts. But soon we narrowed it down: the conditionals inside our email logic weren’t being evaluated properly because the plugin was not even executing the callback functions that should trigger them.
This misbehavior was traced to WordPress’s action hooks. Specifically, we were listening for hooks like:
add_action('user_register', 'my_plugin_email_trigger');
On a single site, this worked. But on a multisite? Different story entirely. Each site operates in a quasi-independent scope. When users registered via a subsite—not the main network site—our hooks did not fire.
Investigation showed that the user_register action would often not be globally broadcast across the network. The plugin was network-activated, but it was still expecting hook behavior consistent across all sites in the network—something WordPress simply does not guarantee.
The Role of Network-Level Hooks
After deep exploration of the WordPress Codex and multisite behavior, we discovered that WordPress offers network-level hooks and filters that can be used when designing plugins intended for use in multisite contexts. These hooks behave differently—they are triggered in the context of the network admin, or are fired regardless of which subsite is currently processing the request.
Here’s what we learned:
- Hooks like
user_registerare only reliable within the current site scope. - Plugins must consider network-activated behavior and cannot assume all actions propagate across subsites.
- Hooks such as
wpmu_new_useror globally scoped actions fired through themu-pluginsfolder often fill this gap.
To address the issue, we migrated some of our conditional logic out of site-scoped hooks and into a custom function tied to a multisite-compatible action.
The Solution: Leveraging a Custom Network-Level Hook
The ultimate solution involved defining our own hook—but this time, one destined to run at the network level rather than per-site. Here’s how we structured the fix:
- Network-activate the plugin so it loads across all sites.
- Place core functionality within
mu-pluginsor a centralized dispatcher file. - Register a custom handler like:
add_action('wpmu_new_user', 'my_network_email_logic', 10, 2);
function my_network_email_logic($user_id, $password) {
$user = get_userdata($user_id);
if (!$user) return;
// Evaluate logic
$role = $user->roles[0] ?? '';
$meta_flag = get_user_meta($user_id, 'email_opt_in', true);
if ($role === 'subscriber' && $meta_flag === 'yes') {
wp_mail($user->user_email, 'Welcome to the Network', 'Thanks for joining us!');
}
}
This hook, wpmu_new_user, is triggered when a new user is added via the network. It guarantees the callback will fire—no matter which site within the network initiated the request.
Important Lessons Learned
Through this experience, we uncovered key insights essential for developing robust plugins in multisite environments:
- 1. Hook Scope Matters: Always identify whether a hook behaves differently between single sites and multisite sub-sites.
- 2. Centralize What You Can: Place universal logic into
mu-pluginsor a network-level plugin rather than assuming it will trigger from each site individually. - 3. Use Network-Aware Actions: Actions like
wpmu_new_useror notifications hooked into network admin functionality provide broader reliability. - 4. Test Across Subsites: Always simulate transactions from different subsites, not just the main site, during plugin QA processes.
When Should You Use MU-Plugins?
Using must-use plugins (placed in wp-content/mu-plugins) proved to be an ideal way to ensure critical logic loaded for every site in the network, regardless of whether it was manually activated. Notably:
- They are always loaded, and cannot be disabled via the dashboard.
- No need to activate across sites manually.
- Ideal for plugin setups with foundational logic like email handling, user provisioning, or role assignments.
The downside? They require manual file placement on the server, which isn’t conducive to all deployment scenarios.
Looking Ahead
This case clearly demonstrated the delicacies involved in developing for WordPress Multisite. It’s not simply a matter of compatibility; it’s about architectural awareness. Plugin developers must account for a range of behavioral differences—especially in hook registration, execution timing, and user context.
By redesigning our email-sending logic to use well-established hooks like wpmu_new_user, paired with a centralized dispatch system supported in mu-plugins, we regained full functionality and improved resilience for the long term. Additionally, it made the email system more observable and testable across the network.
Conclusion
Conditional email logic is a feature many WordPress plugins rely on, but integrating it across multisite networks introduces architectural challenges that can lead to silent failures. As this experience illustrates, blindly applying single-site strategies to a network environment almost guarantees issues. Our fix—pivoting to a network-level hook—was not only necessary, but a best practice we now recommend in general plugin development for WordPress Multisite environments.
So the next time your network-wide email triggers silently fail, remember: it’s not always the mail server. Sometimes, it’s the missing hook you never knew you needed.
