A WordPress Multisite network starts with subdomains (shop.example.com) or subdirectories (example.com/shop). Often you want individual sites on their own domains, like myshop.com or brand-two.net, while still managing them from one network. Since WordPress 4.5, domain mapping is built in. You no longer need a plugin, only the right DNS, web server and SSL setup.
If you haven’t set up Multisite yet, see WordPress Multisite setup.
How it works
Each site in the network has a Site Address (URL). Set it to the custom domain, and WordPress serves that site whenever a request arrives for that domain. That’s all, as long as:
- the domain’s DNS points to your server;
- the web server accepts requests for that domain and passes them to WordPress;
- there’s an SSL certificate for the domain.
1. Point the domain’s DNS at the server
At the domain’s DNS provider:
myshop.com. A 203.0.113.10
www.myshop.com. CNAME myshop.com.
See A record vs CNAME and DNS propagation.
2. Map the domain in WordPress
Network Admin → Sites → Edit the site → set Site Address (URL) to https://myshop.com → Save.
With WP-CLI:
wp site list
wp option update home 'https://myshop.com' --url=shop.example.com
wp option update siteurl 'https://myshop.com' --url=shop.example.com
Update the domain and path in the wp_blogs table too, if they weren’t changed by the admin UI. The UI handles it. Then update hard-coded URLs in content:
wp search-replace 'https://shop.example.com' 'https://myshop.com' --url=myshop.com --all-tables-with-prefix
See WP-CLI.
3. Web server: accept the domains
Nginx
The simplest approach is a default or catch-all server block for the network, so new mapped domains work without editing Nginx:
server {
listen 80;
listen 443 ssl;
server_name example.com *.example.com myshop.com www.myshop.com brand-two.net;
root /var/www/network/public;
# … standard WordPress multisite PHP and try_files configuration
}
Listing domains explicitly gives more control, and also lets you add www → apex redirects per domain. For many domains, use include /etc/nginx/multisite-domains.conf; inside server_name. See Nginx server blocks.
Apache
Add ServerAlias myshop.com www.myshop.com to the network’s virtual host. See Apache virtual hosts.
4. SSL for every mapped domain
Each domain needs a certificate. With Certbot, either:
Separate certificates per domain (independent renewals, simple):
sudo certbot --nginx -d myshop.com -d www.myshop.com
Or one certificate with many names (up to 100 SANs):
sudo certbot --nginx --expand -d example.com -d '*.example.com' -d myshop.com -d www.myshop.com
The wildcard for the network’s own subdomains needs DNS validation. See wildcard certificates.
For networks with many customer domains, Caddy’s on-demand TLS (with an allow-list check against WordPress) or a CDN in front (Cloudflare for SaaS) automates certificates per new domain. See Caddy reverse proxy.
5. Cookies and logins
Logging in on mapped domains can fail because cookies are set for the network’s main domain. Common fixes in wp-config.php:
define('COOKIE_DOMAIN', $_SERVER['HTTP_HOST']);
// or, if set, remove/adjust: define('COOKIE_DOMAIN', 'example.com');
Users log in on each domain separately, since browsers don’t share cookies across unrelated domains. Single sign-on across mapped domains needs a plugin.
Troubleshooting
| Problem | Check |
|---|---|
| Domain shows the main site or “Site not found” | Site Address not updated, or wp_blogs.domain mismatch |
| Nginx serves the wrong site or a default page | Domain missing from server_name, or another server block catches it |
| SSL warning | Certificate doesn’t include that domain |
| Redirect loop | HTTPS or www mismatch between the Site Address, Nginx redirects and a CDN. See too many redirects |
| Can’t log in on the mapped domain | COOKIE_DOMAIN setting |
| Images still load from the old subdomain | Run search-replace on that site’s tables |
Quick reference
| Step | Action |
|---|---|
| DNS | A record to the server IP |
| WordPress | Network Admin → Sites → Edit → Site Address |
| Nginx | Add the domain to server_name |
| SSL | certbot --nginx -d domain -d www.domain |
| Content URLs | wp search-replace old new --url=domain |
Related: WordPress on a VPS and WordPress redirects.