How I Migrated a WordPress Multisite Network to Local WP

Someone described WordPress Multisite as the “bastard child” of WordPress, and I think that is an accurate description. I’ve burned many hours dealing with the quirks of Multisite, and this is one of them.

If you look at Local WP’s official docs on how to migrate a Multisite to local, you’ll see the painful instructions which include manual migration of the database and running search and replace scripts, whereas migrating a regular WordPress site can be done with a few button clicks!

After a lot of fiddling and experimentation, I was able to migrate a Multisite (subdirectory, not subdomain) to Local WP, almost perfectly (I’ll describe what is not perfect below). Before I go into the details, here are the quick takeaways:

  • LocalWP does not include the .htaccess file when you create a Multisite install for Apache; you have to add it yourself.
  • I was able to successfully migrate a subdirectory Multisite using All-in-One Migration plus the paid Multisite extension, which is very expensive.
  • Everything works great except /wp-admin redirects to the root on the main and child sites. Use /wp-login.php to log in instead.

OK, here are the details.

1. Create a multisite install in Local WP

I used Apache and specified subdirectory (not subdomain). Subdomain opens a whole other can of worms.

2. Add .htaccess if necessary

Test out your local site by trying to navigate to a page or post other than the home page. If it keeps redirecting to the home page, that means you’re missing an .htaccess file.

Why Local doesn’t include the .htaccess in Multisite installs is beyond me. It’s like making a car but not including spark plugs. It would be so easy to include fix problems for a lot of people! Here’s the .htaccess code for multisite if you need it:

# BEGIN WordPress Multisite
# Using subfolder network type: https://wordpress.org/documentation/article/htaccess/#multisite

RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

# END WordPress Multisite

I copied this straight from WordPress.org.

After creating this .htaccess file in the site root, links to posts and pages should work. However, for me, /wp-admin still redirected to the home page. I don’t have a fix for that, just a workaround (use /wp-login.php to go to the admin).

Note that if you’re using NGINX, there is no need to create the .htaccess (but /wp-admin still didn’t work for me with NGINX either).

3. Install the All-in-One Migration free plugin and the paid Multisite Extension on local

The bummer here is that the All-in-One Multisite Extension is currently a whopping $310/year.

4. Use All-in-One Migration with the Extension to create an export file

I find that excluding the mu-plugins directory in the advanced options prevents problems during the import process. After creating it, download it to your local computer.

5. Import the file into your Local WP install

After importing, log in using /wp-login.php or click the WP Admin button in the Local WP app for this site. Go ahead and save Permalinks. I sometimes find that I need to disable certain plugins like WordFence after migrating to local. You may have to do this by renaming filenames if the site isn’t working.

Conclusion

So, that’s how I migrated a subdirectory Multisite to Local WP without having to manually move database tables or run scripts. All-in-One for Multisite ain’t cheap, but it worked for me.

Please leave your questions or comments below! – Brian

Shares

Please Leave a Question or Comment

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments